mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-18 16:45:10 +00:00
Compare commits
60 Commits
Canary-1.3
...
Canary-1.3
Author | SHA1 | Date | |
---|---|---|---|
|
37e81481c4 | ||
|
4d8b799763 | ||
|
cb786b7147 | ||
|
2a308f50c0 | ||
|
b51c5cead6 | ||
|
461c1f5342 | ||
|
cfea61b3a0 | ||
|
ae2e9a73ab | ||
|
c6f22318a7 | ||
|
dd5e1b99b1 | ||
|
c863ffd353 | ||
|
d6d089b81b | ||
|
c482b7a1c0 | ||
|
01e1cd4d5a | ||
|
bb06eb751b | ||
|
5613d3f35d | ||
|
54d4d184f4 | ||
|
d22756f1bd | ||
|
324f18aa5f | ||
|
31870707cf | ||
|
fd6648e30a | ||
|
bc6be4e088 | ||
|
64a6494d90 | ||
|
ddb8afa6f4 | ||
|
c2f4118b1f | ||
|
47aa2c1513 | ||
|
f3a2f59683 | ||
|
51bcb9e128 | ||
|
dce5f0eb55 | ||
|
f2eb3749f9 | ||
|
45b2e613cf | ||
|
932c480325 | ||
|
0e24435414 | ||
|
a5cf0482b4 | ||
|
14e794af84 | ||
|
29a02f4787 | ||
|
e2f9d84b64 | ||
|
0cc94fdf37 | ||
|
74a9b94227 | ||
|
d3208a4c44 | ||
|
5d136980a3 | ||
|
572ad1eac5 | ||
|
6bb2af0091 | ||
|
534a194ed9 | ||
|
331805791e | ||
|
6773406bb6 | ||
|
6226eadf55 | ||
|
b1cde5fd97 | ||
|
39944b2063 | ||
|
973c6ba5df | ||
|
6803c91da8 | ||
|
557c2a50b2 | ||
|
77a797f154 | ||
|
faf9e3cdd7 | ||
|
7bc80ed4fe | ||
|
a1d44ec496 | ||
|
bab3beb0ac | ||
|
aa9e74339b | ||
|
908273d848 | ||
|
b51ad11574 |
@@ -45,10 +45,10 @@ dotnet_separate_import_directive_groups = false
|
||||
dotnet_sort_system_directives_first = false
|
||||
|
||||
# this. and Me. preferences
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:silent
|
||||
dotnet_style_qualification_for_field = false:silent
|
||||
dotnet_style_qualification_for_method = false:silent
|
||||
dotnet_style_qualification_for_property = false:silent
|
||||
|
||||
# Language keywords vs BCL types preferences
|
||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent
|
||||
@@ -257,14 +257,12 @@ csharp_prefer_system_threading_lock = true:suggestion
|
||||
dotnet_diagnostic.CA1069.severity = none # CA1069: Enums values should not be duplicated
|
||||
# Disable Collection initialization can be simplified
|
||||
dotnet_diagnostic.IDE0028.severity = none
|
||||
dotnet_diagnostic.IDE0079.severity = none # IDE0079: Remove unnecessary suppression
|
||||
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
|
||||
dotnet_diagnostic.IDE0300.severity = none
|
||||
dotnet_diagnostic.IDE0301.severity = none
|
||||
dotnet_diagnostic.IDE0302.severity = none
|
||||
dotnet_diagnostic.IDE0305.severity = none
|
||||
dotnet_diagnostic.CS9113.severity = none # CS9113: Parameter 'value' is unread
|
||||
dotnet_diagnostic.CS0649.severity = none # CS0649: Field is never assigned to, and will always have its default value
|
||||
dotnet_diagnostic.IDE0130.severity = none # IDE0130: Namespace does not match folder structure
|
||||
|
||||
[src/Ryujinx/UI/ViewModels/**.cs]
|
||||
# Disable "mark members as static" rule for ViewModels
|
||||
|
84
.github/workflows/canary.yml
vendored
84
.github/workflows/canary.yml
vendored
@@ -105,46 +105,48 @@ jobs:
|
||||
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz"
|
||||
shell: bash
|
||||
|
||||
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||
|
||||
- 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
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
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
|
||||
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
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 }}"
|
||||
#
|
||||
# sudo apt install -y zsync desktop-file-utils appstream
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# # 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
|
||||
#
|
||||
# export UFLAG="gh-releases-zsync|${{ secrets.RC_OWNER }}${{ secrets.RC_CANARY_NAME }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
# BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=UploadGenericPackage "Ryubing-Canary|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-canary-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
# shell: bash
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
@@ -243,3 +245,7 @@ jobs:
|
||||
- name: Send notification webhook
|
||||
run: |
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/canary --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|FF4500|${{ secrets.CANARY_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||
|
||||
- name: Notify update server of new builds
|
||||
run: |
|
||||
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=canary' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
||||
|
84
.github/workflows/release.yml
vendored
84
.github/workflows/release.yml
vendored
@@ -96,46 +96,48 @@ jobs:
|
||||
shell: bash
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- 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
|
||||
|
||||
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
|
||||
|
||||
# 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
|
||||
|
||||
export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
|
||||
pushd publish_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
|
||||
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
shell: bash
|
||||
# If anyone wants to look into why appimagetool randomly errors with exit code 8, that would be cool
|
||||
|
||||
# - 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
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# # 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
|
||||
#
|
||||
# export UFLAG="gh-releases-zsync|${{ github.repository_owner }}|${{ github.event.repository.name }}|latest|*-$ARCH_NAME.AppImage.zsync"
|
||||
# BUILDDIR=publish OUTDIR=publish_appimage distribution/linux/appimage/build-appimage.sh
|
||||
#
|
||||
# pushd publish_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
|
||||
#
|
||||
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage"
|
||||
# gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=UploadGenericPackage "Ryubing|${{ steps.version_info.outputs.build_version }}|release_output/ryujinx-$BUILD_VERSION-$ARCH_NAME.AppImage.zsync"
|
||||
# shell: bash
|
||||
|
||||
macos_release:
|
||||
name: Release MacOS universal
|
||||
@@ -228,3 +230,7 @@ jobs:
|
||||
- name: Send notification webhook
|
||||
run: |
|
||||
gli --access-token=${{ secrets.GITLAB_TOKEN }} --project=ryubing/ryujinx --command=SendUpdateMessage "${{ steps.version_info.outputs.build_version }}|32cd32|${{ secrets.STABLE_DISCORD_WEBHOOK }}|https://avatars.githubusercontent.com/u/192939710?s=200&v=4|false"
|
||||
|
||||
- name: Notify update server of new builds
|
||||
run: |
|
||||
curl 'https://update.ryujinx.app/api/v1/admin/refresh_cache?rc=stable' -X PATCH -H 'accept: */*' -H 'Authorization: ${{ secrets.UPDATE_SERVER_ADMIN_TOKEN }}'
|
||||
|
@@ -40,8 +40,10 @@
|
||||
<PackageVersion Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies.AllArch" Version="6.1.2-build3" />
|
||||
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
|
||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.20.0" />
|
||||
<PackageVersion Include="Ryujinx.LibHac" Version="0.21.0-alpha.116" />
|
||||
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
|
||||
<PackageVersion Include="Ryujinx.UpdateClient" Version="1.0.29" />
|
||||
<PackageVersion Include="Ryujinx.Systems.Update.Common" Version="1.0.29" />
|
||||
<PackageVersion Include="Gommon" Version="2.7.1.1" />
|
||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||
<PackageVersion Include="Sep" Version="0.6.0" />
|
||||
|
@@ -7,8 +7,8 @@
|
||||
|
||||
# Ryujinx
|
||||
|
||||
[](https://git.ryujinx.app/ryubing/ryujinx/-/releases)
|
||||
[](https://git.ryujinx.app/ryubing/canary/-/releases)
|
||||
[](https://update.ryujinx.app/latest/stable)
|
||||
[](https://update.ryujinx.app/latest/canary)
|
||||
<br>
|
||||
<a href="https://discord.gg/PEuzjrFXUA">
|
||||
<img src="https://img.shields.io/discord/1294443224030511104?color=5865F2&label=Ryubing&logo=discord&logoColor=white" alt="Discord">
|
||||
|
@@ -77,6 +77,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
.editorconfig = .editorconfig
|
||||
@@ -84,10 +86,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
.github\workflows\canary.yml = .github\workflows\canary.yml
|
||||
Directory.Packages.props = Directory.Packages.props
|
||||
.github\workflows\release.yml = .github\workflows\release.yml
|
||||
nuget.config = nuget.config
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
5081
assets/locales.json
5081
assets/locales.json
File diff suppressed because it is too large
Load Diff
@@ -188,6 +188,8 @@
|
||||
01003DD00BFEE000,"Airheart - Tales of broken Wings",,playable,2021-02-26 15:20:27
|
||||
01007F100DE52000,"Akane",nvdec,playable,2022-07-21 00:12:18
|
||||
01009A800F0C8000,"Akash: Path of the Five",gpu;nvdec,ingame,2020-12-14 22:33:12
|
||||
01009E8012976000,"AKIBA'S TRIP: Hellbound & Debriefed",,playable,2025-07-30 23:22:47
|
||||
0100D74019A0E000,"AKIBA'S TRIP: Undead & Undressed Director's Cut",,playable,2025-07-31 13:58:42
|
||||
010053100B0EA000,"Akihabara - Feel the Rhythm Remixed",,playable,2021-02-22 14:39:35
|
||||
0100D4C00EE0C000,"Akuarium",slow,playable,2020-12-12 23:43:36
|
||||
010026E00FEBE000,"Akuto: Showdown",,playable,2020-08-04 19:43:27
|
||||
@@ -1095,6 +1097,7 @@
|
||||
0100F9600E746000,"ESP Ra.De. Psi",audio;slow,ingame,2024-03-07 15:05:08
|
||||
010073000FE18000,"Esports powerful pro yakyuu 2020",gpu;crash;Needs More Attention,ingame,2024-04-29 05:34:14
|
||||
01004F9012FD8000,"Estranged: The Departure",nvdec;UE4,playable,2022-10-24 10:37:58
|
||||
010018f01e0a0000,"Eternights",,playable,2025-07-30 12:10:24
|
||||
0100CB900B498000,"Eternum Ex",,playable,2021-01-13 20:28:32
|
||||
010092501EB2C000,"Europa (Demo)",gpu;crash;UE4,ingame,2024-04-23 10:47:12
|
||||
01007BE0160D6000,"EVE ghost enemies",gpu,ingame,2023-01-14 03:13:30
|
||||
@@ -1240,6 +1243,8 @@
|
||||
010003F00BD48000,"Friday the 13th: Killer Puzzle",,playable,2021-01-28 01:33:38
|
||||
010092A00C4B6000,"Friday the 13th: The Game Ultimate Slasher Edition",nvdec;online-broken;UE4,playable,2022-09-06 17:33:27
|
||||
0100F200178F4000,"FRONT MISSION 1st: Remake",,playable,2023-06-09 07:44:24
|
||||
0100c4e018a24000,"FRONT MISSION 2: Remake",,playable,2025-07-30 12:11:23
|
||||
01007E6019872000,"FRONT MISSION 3: Remake",,playable,2025-07-30 12:12:02
|
||||
0100861012474000,"Frontline Zed",,playable,2020-10-03 12:55:59
|
||||
0100B5300B49A000,"Frost",,playable,2022-07-27 12:00:36
|
||||
010038A007AA4000,"FruitFall Crush",,playable,2020-10-20 11:33:33
|
||||
@@ -1518,6 +1523,7 @@
|
||||
010095C016C14000,"Iridium",,playable,2022-08-05 23:19:53
|
||||
0100AD300B786000,"Iris School of Wizardry -Vinculum Hearts-",,playable,2022-12-05 13:11:15
|
||||
0100945012168000,"Iris.Fall",nvdec,playable,2022-10-18 13:40:22
|
||||
010059801B736000,"IronFall: Invasion",,playable,2025-07-30 11:42:30
|
||||
01005270118D6000,"Iron Wings",slow,ingame,2022-08-07 08:32:57
|
||||
01004DB003E6A000,"IRONCAST",,playable,2021-01-13 13:54:29
|
||||
0100E5700CD56000,"Irony Curtain: From Matryoshka with Love",,playable,2021-06-04 20:12:37
|
||||
@@ -2257,6 +2263,7 @@
|
||||
010086F0064CE000,"Poi: Explorer Edition",nvdec,playable,2021-01-21 19:32:00
|
||||
0100EB6012FD2000,"Poison Control",,playable,2021-05-16 14:01:54
|
||||
010072400E04A000,"Pokémon Café ReMix",,playable,2021-08-17 20:00:04
|
||||
010008c01e742000,"Pokémon Friends",crash;services,menus,2025-07-24 13:32:00
|
||||
01003D200BAA2000,"Pokémon Mystery Dungeon™: Rescue Team DX",mac-bug,playable,2024-01-21 00:16:32
|
||||
01008DB008C2C000,"Pokémon Shield + Pokémon Shield Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-12 07:20:22
|
||||
0100ABF008968000,"Pokémon Sword + Pokémon Sword Expansion Pass",deadlock;crash;online-broken;ldn-works;LAN,ingame,2024-08-26 15:40:37
|
||||
@@ -2305,6 +2312,7 @@
|
||||
010077B00BDD8000,"Professional Farmer: Nintendo Switch™ Edition",slow,playable,2020-12-16 13:38:19
|
||||
010018300C83A000,"Professor Lupo and his Horrible Pets",,playable,2020-06-12 00:08:45
|
||||
0100D1F0132F6000,"Professor Lupo: Ocean",,playable,2021-04-14 16:33:33
|
||||
0100c3a017834000,"Prodeus",,playable,2025-07-30 12:07:52
|
||||
0100BBD00976C000,"Project Highrise: Architect's Edition",,playable,2022-08-10 17:19:12
|
||||
0100ACE00DAB6000,"Project Nimbus: Complete Edition",nvdec;UE4;vulkan-backend-bug,playable,2022-08-10 17:35:43
|
||||
01002980140F6000,"Project TRIANGLE STRATEGY™ Debut Demo",UE4;demo,playable,2022-10-24 21:40:27
|
||||
@@ -2436,6 +2444,7 @@
|
||||
0100E9C010EA8000,"Rise of Insanity",,playable,2020-08-30 15:42:14
|
||||
01006BA00E652000,"Rise: Race The Future",,playable,2021-02-27 13:29:06
|
||||
010020C012F48000,"Rising Hell",,playable,2022-10-31 13:54:02
|
||||
0100D1801A0F4000,"Risk of Rain Returns",,playable,2025-06-28 04:24:04
|
||||
010076D00E4BA000,"Risk of Rain 2",online-broken,playable,2024-03-04 17:01:05
|
||||
0100E8300A67A000,"RISK® Global Domination",nvdec;online-broken,playable,2022-08-01 18:53:28
|
||||
010042500FABA000,"Ritual: Crown of Horns",,playable,2021-01-26 16:01:47
|
||||
@@ -2746,6 +2755,7 @@
|
||||
01005D701264A000,"SpyHack",,playable,2021-04-15 10:53:51
|
||||
010077B00E046000,"Spyro™ Reignited Trilogy",nvdec;UE4,playable,2022-09-11 18:38:33
|
||||
0100085012A0E000,"Squeakers",,playable,2020-12-13 12:13:05
|
||||
0100E1D01EB2E000,"Squeakross: Home Squeak Home",,playable,2025-06-16 02:02:00
|
||||
010009300D31C000,"Squidgies Takeover",,playable,2020-07-20 22:28:08
|
||||
0100FCD0102EC000,"Squidlit",,playable,2020-08-06 12:38:32
|
||||
0100EBF00E702000,"STAR OCEAN First Departure R",nvdec,playable,2021-07-05 19:29:16
|
||||
@@ -2765,7 +2775,7 @@
|
||||
0100E6B0115FC000,"Star99",online,menus,2021-11-26 14:18:51
|
||||
01002100137BA000,"Stardash",,playable,2021-01-21 16:31:19
|
||||
0100E65002BB8000,"Stardew Valley",online-broken;ldn-untested,playable,2024-02-14 03:11:19
|
||||
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",services-horizon;crash;Needs Update,nothing,2024-05-05 17:25:11
|
||||
01002CC003FE6000,"Starlink: Battle for Atlas™ Digital Edition",,playable,2025-07-30 12:09:37
|
||||
010098E010FDA000,"Starlit Adventures Golden Stars",,playable,2020-11-21 12:14:43
|
||||
01001BB00AC26000,"STARSHIP AVENGER Operation: Take Back Earth",,playable,2021-01-12 15:52:55
|
||||
010000700A572000,"State of Anarchy: Master of Mayhem",nvdec,playable,2021-01-12 19:00:05
|
||||
@@ -2973,6 +2983,7 @@
|
||||
0100C2E0129A6000,"The Executioner",nvdec,playable,2021-01-23 00:31:28
|
||||
01006050114D4000,"The Experiment: Escape Room",gpu,ingame,2022-09-30 13:20:35
|
||||
0100B5900DFB2000,"The Eyes of Ara",,playable,2022-09-16 14:44:06
|
||||
0100BA5013E52000,"The Falconeer: Warrior Edition",,playable,2025-07-30 12:04:50
|
||||
01002DD00AF9E000,"The Fall",gpu,ingame,2020-05-31 23:31:16
|
||||
01003E5002320000,"The Fall Part 2: Unbound",,playable,2021-11-06 02:18:08
|
||||
0100CDC00789E000,"The Final Station",nvdec,playable,2022-08-22 15:54:39
|
||||
@@ -3016,6 +3027,7 @@
|
||||
01009B101044C000,"The Legend of Heroes: Trails of Cold Steel III Demo",demo;nvdec,playable,2021-04-23 01:07:32
|
||||
0100D3C010DE8000,"The Legend of Heroes: Trails of Cold Steel IV",nvdec,playable,2021-04-23 14:01:05
|
||||
01005E5013862000,"THE LEGEND OF HEROES: ZERO NO KISEKI KAI [英雄傳說 零之軌跡:改]",crash,nothing,2021-09-30 14:41:07
|
||||
01009C901ACEE000,"The Legend of Nayuta: Boundless Trails",,ingame,2025-06-12 15:47
|
||||
01008CF01BAAC000,"The Legend of Zelda Echoes of Wisdom",nvdec;ASTC;intel-vendor-bug,playable,2024-10-01 14:11:01
|
||||
0100509005AF2000,"The Legend of Zelda: Breath of the Wild Demo",demo,ingame,2022-12-24 05:02:58
|
||||
01007EF00011E000,"The Legend of Zelda™: Breath of the Wild",gpu;amd-vendor-bug;mac-bug,ingame,2024-09-23 19:35:46
|
||||
@@ -3194,6 +3206,7 @@
|
||||
010000400F582000,"TT Isle of Man Ride on the Edge 2",gpu;nvdec;online-broken,ingame,2022-09-30 22:13:05
|
||||
0100752011628000,"TTV2",,playable,2020-11-27 13:21:36
|
||||
0100AFE00452E000,"Tumblestone",,playable,2021-01-07 17:49:20
|
||||
0100D1A01D7BA000,"Turbo Overkill",,playable,2025-07-30 12:08:57
|
||||
010085500D5F6000,"Turok",gpu,ingame,2021-06-04 13:16:24
|
||||
0100CDC00D8D6000,"Turok 2: Seeds of Evil",gpu;vulkan,ingame,2022-09-12 17:50:05
|
||||
010004B0130C8000,"Turrican Flashback",audout,playable,2021-08-30 10:07:56
|
||||
@@ -3217,6 +3230,8 @@
|
||||
0100592005164000,"UNBOX: Newbie's Adventure",UE4,playable,2022-08-29 13:12:56
|
||||
01002D900C5E4000,"Uncanny Valley",nvdec,playable,2021-06-04 13:28:45
|
||||
010076F011F54000,"Undead & Beyond",nvdec,playable,2022-10-04 09:11:18
|
||||
01009B700D0B8000,"Undead Horde",,playable,2025-07-30 12:05:05
|
||||
0100FC301A878000,"Undead Horde 2: Necropolis",,playable,2025-07-30 12:06:07
|
||||
01008F3013E4E000,"Under Leaves",,playable,2021-05-22 18:13:58
|
||||
010080B00AD66000,"Undertale",,playable,2022-08-31 17:31:46
|
||||
01008F80049C6000,"Unepic",,playable,2024-01-15 17:03:00
|
||||
|
|
17
nuget.config
17
nuget.config
@@ -5,6 +5,21 @@
|
||||
<clear />
|
||||
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||
<!-- Only needed when using pre-release versions of Ryujinx.LibHac. -->
|
||||
<!--<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />-->
|
||||
<add key="LibHacAlpha" value="https://git.ryujinx.app/api/v4/projects/17/packages/nuget/index.json" />
|
||||
<add key="Ryujinx.UpdateClient" value="https://git.ryujinx.app/api/v4/projects/71/packages/nuget/index.json" />
|
||||
</packageSources>
|
||||
<packageSourceMapping>
|
||||
<!-- key value for <packageSource> should match key values from <packageSources> element -->
|
||||
<!-- These are defined and .NET still yells about multiple package sources with no mappings. Not sure what to do, this is in the docs lol -->
|
||||
<packageSource key="nuget.org">
|
||||
<package pattern="*" />
|
||||
</packageSource>
|
||||
<packageSource key="Ryujinx.UpdateClient">
|
||||
<package pattern="Ryujinx.UpdateClient" />
|
||||
<package pattern="Ryujinx.Systems.Update.Common" />
|
||||
</packageSource>
|
||||
<packageSource key="LibHacAlpha">
|
||||
<package pattern="Ryujinx.LibHac" />
|
||||
</packageSource>
|
||||
</packageSourceMapping>
|
||||
</configuration>
|
||||
|
@@ -1129,6 +1129,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
};
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private void WriteInt16(short value)
|
||||
{
|
||||
WriteUInt16((ushort)value);
|
||||
@@ -1143,6 +1144,7 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
{
|
||||
_stream.WriteByte(value);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
private void WriteUInt16(ushort value)
|
||||
{
|
||||
|
@@ -1570,11 +1570,13 @@ namespace ARMeilleure.CodeGen.Arm64
|
||||
Debug.Assert(op1.Type == op3.Type);
|
||||
}
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private static void EnsureSameType(Operand op1, Operand op2, Operand op3, Operand op4)
|
||||
{
|
||||
Debug.Assert(op1.Type == op2.Type);
|
||||
Debug.Assert(op1.Type == op3.Type);
|
||||
Debug.Assert(op1.Type == op4.Type);
|
||||
}
|
||||
#pragma warning restore IDE0051
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
|
@@ -20,12 +20,12 @@ namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
if (GetCurrentCallConv() == CallConvName.Windows)
|
||||
{
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
return (1 << (int)X86Register.Rax) |
|
||||
(1 << (int)X86Register.Rcx) |
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
}
|
||||
@@ -36,11 +36,11 @@ namespace ARMeilleure.CodeGen.X86
|
||||
(1 << (int)X86Register.Rdx) |
|
||||
(1 << (int)X86Register.Rsi) |
|
||||
(1 << (int)X86Register.Rdi) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R8) |
|
||||
(1 << (int)X86Register.R9) |
|
||||
(1 << (int)X86Register.R10) |
|
||||
(1 << (int)X86Register.R11);
|
||||
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -2,6 +2,7 @@ using ARMeilleure.CodeGen.RegisterAllocators;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using Microsoft.IO;
|
||||
using Ryujinx.Common.Memory;
|
||||
using System.IO;
|
||||
using System.Numerics;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
|
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.CodeGen.X86
|
||||
{
|
||||
enum X86Register
|
||||
|
@@ -8,8 +8,8 @@ namespace ARMeilleure.Instructions
|
||||
static class CryptoHelper
|
||||
{
|
||||
#region "LookUp Tables"
|
||||
|
||||
private static ReadOnlySpan<byte> SBox =>
|
||||
#pragma warning disable IDE1006 // Naming rule violation
|
||||
private static ReadOnlySpan<byte> _sBox =>
|
||||
[
|
||||
0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
|
||||
0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
|
||||
@@ -29,7 +29,7 @@ namespace ARMeilleure.Instructions
|
||||
0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> InvSBox =>
|
||||
private static ReadOnlySpan<byte> _invSBox =>
|
||||
[
|
||||
0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
|
||||
0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
|
||||
@@ -49,7 +49,7 @@ namespace ARMeilleure.Instructions
|
||||
0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul02 =>
|
||||
private static ReadOnlySpan<byte> _gfMul02 =>
|
||||
[
|
||||
0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
|
||||
0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
|
||||
@@ -69,7 +69,7 @@ namespace ARMeilleure.Instructions
|
||||
0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul03 =>
|
||||
private static ReadOnlySpan<byte> _gfMul03 =>
|
||||
[
|
||||
0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
|
||||
0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
|
||||
@@ -89,7 +89,7 @@ namespace ARMeilleure.Instructions
|
||||
0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul09 =>
|
||||
private static ReadOnlySpan<byte> _gfMul09 =>
|
||||
[
|
||||
0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
|
||||
0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
|
||||
@@ -109,7 +109,7 @@ namespace ARMeilleure.Instructions
|
||||
0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul0B =>
|
||||
private static ReadOnlySpan<byte> _gfMul0B =>
|
||||
[
|
||||
0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
|
||||
0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
|
||||
@@ -129,7 +129,7 @@ namespace ARMeilleure.Instructions
|
||||
0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul0D =>
|
||||
private static ReadOnlySpan<byte> _gfMul0D =>
|
||||
[
|
||||
0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
|
||||
0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
|
||||
@@ -149,7 +149,7 @@ namespace ARMeilleure.Instructions
|
||||
0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> GfMul0E =>
|
||||
private static ReadOnlySpan<byte> _gfMul0E =>
|
||||
[
|
||||
0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
|
||||
0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
|
||||
@@ -169,16 +169,16 @@ namespace ARMeilleure.Instructions
|
||||
0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> SrPerm =>
|
||||
private static ReadOnlySpan<byte> _srPerm =>
|
||||
[
|
||||
0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
|
||||
];
|
||||
|
||||
private static ReadOnlySpan<byte> IsrPerm =>
|
||||
private static ReadOnlySpan<byte> _isrPerm =>
|
||||
[
|
||||
0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
|
||||
];
|
||||
|
||||
#pragma warning restore IDE1006
|
||||
#endregion
|
||||
|
||||
public static V128 AesInvMixColumns(V128 op)
|
||||
@@ -195,10 +195,10 @@ namespace ARMeilleure.Instructions
|
||||
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
|
||||
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
|
||||
|
||||
outState[idx + 0] = (byte)((uint)GfMul0E[row0] ^ GfMul0B[row1] ^ GfMul0D[row2] ^ GfMul09[row3]);
|
||||
outState[idx + 1] = (byte)((uint)GfMul09[row0] ^ GfMul0E[row1] ^ GfMul0B[row2] ^ GfMul0D[row3]);
|
||||
outState[idx + 2] = (byte)((uint)GfMul0D[row0] ^ GfMul09[row1] ^ GfMul0E[row2] ^ GfMul0B[row3]);
|
||||
outState[idx + 3] = (byte)((uint)GfMul0B[row0] ^ GfMul0D[row1] ^ GfMul09[row2] ^ GfMul0E[row3]);
|
||||
outState[idx + 0] = (byte)((uint)_gfMul0E[row0] ^ _gfMul0B[row1] ^ _gfMul0D[row2] ^ _gfMul09[row3]);
|
||||
outState[idx + 1] = (byte)((uint)_gfMul09[row0] ^ _gfMul0E[row1] ^ _gfMul0B[row2] ^ _gfMul0D[row3]);
|
||||
outState[idx + 2] = (byte)((uint)_gfMul0D[row0] ^ _gfMul09[row1] ^ _gfMul0E[row2] ^ _gfMul0B[row3]);
|
||||
outState[idx + 3] = (byte)((uint)_gfMul0B[row0] ^ _gfMul0D[row1] ^ _gfMul09[row2] ^ _gfMul0E[row3]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@@ -211,7 +211,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[IsrPerm[idx]] = inState[idx];
|
||||
outState[_isrPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@@ -224,7 +224,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = InvSBox[inState[idx]];
|
||||
outState[idx] = _invSBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@@ -244,10 +244,10 @@ namespace ARMeilleure.Instructions
|
||||
byte row2 = inState[idx + 2]; // C, G, K, O: [row2, col0-col3]
|
||||
byte row3 = inState[idx + 3]; // D, H, L, P: [row3, col0-col3]
|
||||
|
||||
outState[idx + 0] = (byte)((uint)GfMul02[row0] ^ GfMul03[row1] ^ row2 ^ row3);
|
||||
outState[idx + 1] = (byte)((uint)row0 ^ GfMul02[row1] ^ GfMul03[row2] ^ row3);
|
||||
outState[idx + 2] = (byte)((uint)row0 ^ row1 ^ GfMul02[row2] ^ GfMul03[row3]);
|
||||
outState[idx + 3] = (byte)((uint)GfMul03[row0] ^ row1 ^ row2 ^ GfMul02[row3]);
|
||||
outState[idx + 0] = (byte)((uint)_gfMul02[row0] ^ _gfMul03[row1] ^ row2 ^ row3);
|
||||
outState[idx + 1] = (byte)((uint)row0 ^ _gfMul02[row1] ^ _gfMul03[row2] ^ row3);
|
||||
outState[idx + 2] = (byte)((uint)row0 ^ row1 ^ _gfMul02[row2] ^ _gfMul03[row3]);
|
||||
outState[idx + 3] = (byte)((uint)_gfMul03[row0] ^ row1 ^ row2 ^ _gfMul02[row3]);
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@@ -260,7 +260,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[SrPerm[idx]] = inState[idx];
|
||||
outState[_srPerm[idx]] = inState[idx];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
@@ -273,7 +273,7 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
for (int idx = 0; idx <= 15; idx++)
|
||||
{
|
||||
outState[idx] = SBox[inState[idx]];
|
||||
outState[idx] = _sBox[inState[idx]];
|
||||
}
|
||||
|
||||
return new V128(outState);
|
||||
|
@@ -143,6 +143,12 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void EmitCall(ArmEmitterContext context, ulong immediate)
|
||||
{
|
||||
if (context.IsSingleStep)
|
||||
{
|
||||
context.Return(Const(immediate));
|
||||
return;
|
||||
}
|
||||
|
||||
bool isRecursive = immediate == context.EntryAddress;
|
||||
|
||||
if (isRecursive)
|
||||
@@ -157,12 +163,24 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
public static void EmitVirtualCall(ArmEmitterContext context, Operand target)
|
||||
{
|
||||
EmitTableBranch(context, target, isJump: false);
|
||||
if (context.IsSingleStep)
|
||||
{
|
||||
if (target.Type == OperandType.I32)
|
||||
{
|
||||
target = context.ZeroExtend32(OperandType.I64, target);
|
||||
}
|
||||
|
||||
context.Return(target);
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitTableBranch(context, target, isJump: false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void EmitVirtualJump(ArmEmitterContext context, Operand target, bool isReturn)
|
||||
{
|
||||
if (isReturn)
|
||||
if (isReturn || context.IsSingleStep)
|
||||
{
|
||||
if (target.Type == OperandType.I32)
|
||||
{
|
||||
|
@@ -2,6 +2,7 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
|
@@ -11,10 +11,11 @@ using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Abs_S(ArmEmitterContext context)
|
||||
|
@@ -2,13 +2,15 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Cmeq_S(ArmEmitterContext context)
|
||||
|
@@ -2,15 +2,17 @@ using ARMeilleure.Decoders;
|
||||
using ARMeilleure.IntermediateRepresentation;
|
||||
using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper32;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit32
|
||||
{
|
||||
public static void Vceq_V(ArmEmitterContext context)
|
||||
|
@@ -8,10 +8,11 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
public static void Fcvt_S(ArmEmitterContext context)
|
||||
|
@@ -8,12 +8,13 @@ using System.Diagnostics;
|
||||
using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper
|
||||
{
|
||||
#region "Masks"
|
||||
|
@@ -7,12 +7,13 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper32
|
||||
{
|
||||
public static (int, int) GetQuadwordAndSubindex(int index, RegisterSize size)
|
||||
|
@@ -7,12 +7,13 @@ using System.Diagnostics;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func1I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
using Func3I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func1I = Func<Operand, Operand>;
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
using Func3I = Func<Operand, Operand, Operand, Operand>;
|
||||
|
||||
static class InstEmitSimdHelper32Arm64
|
||||
{
|
||||
// Intrinsic Helpers
|
||||
|
@@ -40,36 +40,34 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
long offset = 0;
|
||||
|
||||
for (int rep = 0; rep < op.Reps; rep++)
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
for (int rep = 0; rep < op.Reps; rep++)
|
||||
for (int elem = 0; elem < op.Elems; elem++)
|
||||
for (int sElem = 0; sElem < op.SElems; sElem++)
|
||||
{
|
||||
for (int elem = 0; elem < op.Elems; elem++)
|
||||
int rtt = (op.Rt + rep + sElem) & 0x1f;
|
||||
|
||||
Operand tt = GetVec(rtt);
|
||||
|
||||
Operand address = context.Add(n, Const(offset));
|
||||
|
||||
if (isLoad)
|
||||
{
|
||||
for (int sElem = 0; sElem < op.SElems; sElem++)
|
||||
EmitLoadSimd(context, address, tt, rtt, elem, op.Size);
|
||||
|
||||
if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
|
||||
{
|
||||
int rtt = (op.Rt + rep + sElem) & 0x1f;
|
||||
|
||||
Operand tt = GetVec(rtt);
|
||||
|
||||
Operand address = context.Add(n, Const(offset));
|
||||
|
||||
if (isLoad)
|
||||
{
|
||||
EmitLoadSimd(context, address, tt, rtt, elem, op.Size);
|
||||
|
||||
if (op.RegisterSize == RegisterSize.Simd64 && elem == op.Elems - 1)
|
||||
{
|
||||
context.Copy(tt, context.VectorZeroUpper64(tt));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitStoreSimd(context, address, rtt, elem, op.Size);
|
||||
}
|
||||
|
||||
offset += 1 << op.Size;
|
||||
context.Copy(tt, context.VectorZeroUpper64(tt));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitStoreSimd(context, address, rtt, elem, op.Size);
|
||||
}
|
||||
|
||||
offset += 1 << op.Size;
|
||||
}
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
if (op.WBack)
|
||||
{
|
||||
|
@@ -9,10 +9,11 @@ using System.Reflection;
|
||||
using static ARMeilleure.Instructions.InstEmitHelper;
|
||||
using static ARMeilleure.Instructions.InstEmitSimdHelper;
|
||||
using static ARMeilleure.IntermediateRepresentation.Operand.Factory;
|
||||
using Func2I = System.Func<ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand, ARMeilleure.IntermediateRepresentation.Operand>;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
using Func2I = Func<Operand, Operand, Operand>;
|
||||
|
||||
static partial class InstEmit
|
||||
{
|
||||
#region "Masks"
|
||||
|
@@ -3,6 +3,7 @@ using ARMeilleure.State;
|
||||
using ARMeilleure.Translation;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using ExecutionContext = ARMeilleure.State.ExecutionContext;
|
||||
|
||||
namespace ARMeilleure.Instructions
|
||||
{
|
||||
@@ -200,7 +201,11 @@ namespace ARMeilleure.Instructions
|
||||
|
||||
ExecutionContext context = GetContext();
|
||||
|
||||
context.CheckInterrupt();
|
||||
// If debugging, we'll handle interrupts outside
|
||||
if (!Optimizations.EnableDebugging)
|
||||
{
|
||||
context.CheckInterrupt();
|
||||
}
|
||||
|
||||
Statistics.ResumeTimer();
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
|
@@ -7,9 +7,10 @@ namespace ARMeilleure.IntermediateRepresentation
|
||||
{
|
||||
private struct Data
|
||||
{
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public byte Kind;
|
||||
public byte Type;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
public byte Scale;
|
||||
public Operand BaseAddress;
|
||||
public Operand Index;
|
||||
|
@@ -1,8 +1,8 @@
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
namespace ARMeilleure
|
||||
{
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
public static class Optimizations
|
||||
{
|
||||
// low-core count PPTC
|
||||
@@ -12,6 +12,7 @@ namespace ARMeilleure
|
||||
|
||||
public static bool AllowLcqInFunctionTable { get; set; } = true;
|
||||
public static bool UseUnmanagedDispatchLoop { get; set; } = true;
|
||||
public static bool EnableDebugging { get; set; } = false;
|
||||
|
||||
public static bool UseAdvSimdIfAvailable { get; set; } = true;
|
||||
public static bool UseArm64AesIfAvailable { get; set; } = true;
|
||||
|
@@ -1,4 +1,5 @@
|
||||
using ARMeilleure.Memory;
|
||||
using System.Threading;
|
||||
|
||||
namespace ARMeilleure.State
|
||||
{
|
||||
@@ -10,7 +11,7 @@ namespace ARMeilleure.State
|
||||
|
||||
internal nint NativeContextPtr => _nativeContext.BasePtr;
|
||||
|
||||
private bool _interrupted;
|
||||
internal bool Interrupted { get; private set; }
|
||||
|
||||
private readonly ICounter _counter;
|
||||
|
||||
@@ -65,6 +66,8 @@ namespace ARMeilleure.State
|
||||
|
||||
public bool IsAarch32 { get; set; }
|
||||
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
internal ExecutionMode ExecutionMode
|
||||
{
|
||||
get
|
||||
@@ -90,14 +93,19 @@ namespace ARMeilleure.State
|
||||
|
||||
private readonly ExceptionCallbackNoArgs _interruptCallback;
|
||||
private readonly ExceptionCallback _breakCallback;
|
||||
private readonly ExceptionCallbackNoArgs _stepCallback;
|
||||
private readonly ExceptionCallback _supervisorCallback;
|
||||
private readonly ExceptionCallback _undefinedCallback;
|
||||
|
||||
internal int ShouldStep;
|
||||
public ulong DebugPc { get; set; }
|
||||
|
||||
public ExecutionContext(
|
||||
IJitMemoryAllocator allocator,
|
||||
ICounter counter,
|
||||
ExceptionCallbackNoArgs interruptCallback = null,
|
||||
ExceptionCallback breakCallback = null,
|
||||
ExceptionCallbackNoArgs stepCallback = null,
|
||||
ExceptionCallback supervisorCallback = null,
|
||||
ExceptionCallback undefinedCallback = null)
|
||||
{
|
||||
@@ -105,6 +113,7 @@ namespace ARMeilleure.State
|
||||
_counter = counter;
|
||||
_interruptCallback = interruptCallback;
|
||||
_breakCallback = breakCallback;
|
||||
_stepCallback = stepCallback;
|
||||
_supervisorCallback = supervisorCallback;
|
||||
_undefinedCallback = undefinedCallback;
|
||||
|
||||
@@ -127,9 +136,9 @@ namespace ARMeilleure.State
|
||||
|
||||
internal void CheckInterrupt()
|
||||
{
|
||||
if (_interrupted)
|
||||
if (Interrupted)
|
||||
{
|
||||
_interrupted = false;
|
||||
Interrupted = false;
|
||||
|
||||
_interruptCallback?.Invoke(this);
|
||||
}
|
||||
@@ -139,16 +148,37 @@ namespace ARMeilleure.State
|
||||
|
||||
public void RequestInterrupt()
|
||||
{
|
||||
_interrupted = true;
|
||||
Interrupted = true;
|
||||
}
|
||||
|
||||
public void StepHandler()
|
||||
{
|
||||
_stepCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
public void RequestDebugStep()
|
||||
{
|
||||
Interlocked.Exchange(ref ShouldStep, 1);
|
||||
RequestInterrupt();
|
||||
}
|
||||
|
||||
internal void OnBreak(ulong address, int imm)
|
||||
{
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
DebugPc = Pc;
|
||||
}
|
||||
|
||||
_breakCallback?.Invoke(this, address, imm);
|
||||
}
|
||||
|
||||
internal void OnSupervisorCall(ulong address, int imm)
|
||||
{
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
DebugPc = Pc;
|
||||
}
|
||||
|
||||
_supervisorCallback?.Invoke(this, address, imm);
|
||||
}
|
||||
|
||||
|
@@ -22,6 +22,12 @@ namespace ARMeilleure.State
|
||||
public ulong ExclusiveValueHigh;
|
||||
public int Running;
|
||||
public long Tpidr2El0;
|
||||
|
||||
/// <summary>
|
||||
/// Precise PC value used for debugging.
|
||||
/// This will only be set when Optimizations.EnableDebugging is true.
|
||||
/// </summary>
|
||||
public ulong DebugPrecisePc;
|
||||
}
|
||||
|
||||
private static NativeCtxStorage _dummyStorage = new();
|
||||
@@ -39,6 +45,11 @@ namespace ARMeilleure.State
|
||||
|
||||
public ulong GetPc()
|
||||
{
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
return GetStorage().DebugPrecisePc;
|
||||
}
|
||||
|
||||
// TODO: More precise tracking of PC value.
|
||||
return GetStorage().DispatchAddress;
|
||||
}
|
||||
@@ -268,6 +279,11 @@ namespace ARMeilleure.State
|
||||
return StorageOffset(ref _dummyStorage, ref _dummyStorage.Running);
|
||||
}
|
||||
|
||||
public static int GetDebugPrecisePcOffset()
|
||||
{
|
||||
return StorageOffset(ref _dummyStorage, ref _dummyStorage.DebugPrecisePc);
|
||||
}
|
||||
|
||||
private static int StorageOffset<T>(ref NativeCtxStorage storage, ref T target)
|
||||
{
|
||||
return (int)Unsafe.ByteOffset(ref Unsafe.As<NativeCtxStorage, T>(ref storage), ref target);
|
||||
|
@@ -52,6 +52,7 @@ namespace ARMeilleure.Translation
|
||||
public bool HighCq { get; }
|
||||
public bool HasPtc { get; }
|
||||
public Aarch32Mode Mode { get; }
|
||||
public bool IsSingleStep { get; }
|
||||
|
||||
private int _ifThenBlockStateIndex = 0;
|
||||
private Condition[] _ifThenBlockState = [];
|
||||
@@ -66,7 +67,8 @@ namespace ARMeilleure.Translation
|
||||
ulong entryAddress,
|
||||
bool highCq,
|
||||
bool hasPtc,
|
||||
Aarch32Mode mode)
|
||||
Aarch32Mode mode,
|
||||
bool isSingleStep)
|
||||
{
|
||||
Memory = memory;
|
||||
CountTable = countTable;
|
||||
@@ -76,6 +78,7 @@ namespace ARMeilleure.Translation
|
||||
HighCq = highCq;
|
||||
HasPtc = hasPtc;
|
||||
Mode = mode;
|
||||
IsSingleStep = isSingleStep;
|
||||
|
||||
_labels = new Dictionary<ulong, Operand>();
|
||||
}
|
||||
@@ -218,28 +221,18 @@ namespace ARMeilleure.Translation
|
||||
{
|
||||
switch (condition)
|
||||
{
|
||||
|
||||
case Condition.Eq:
|
||||
return ICompareEqual(n, m);
|
||||
case Condition.Ne:
|
||||
return ICompareNotEqual(n, m);
|
||||
case Condition.GeUn:
|
||||
return ICompareGreaterOrEqualUI(n, m);
|
||||
case Condition.LtUn:
|
||||
return ICompareLessUI(n, m);
|
||||
case Condition.GtUn:
|
||||
return ICompareGreaterUI(n, m);
|
||||
case Condition.LeUn:
|
||||
return ICompareLessOrEqualUI(n, m);
|
||||
case Condition.Ge:
|
||||
return ICompareGreaterOrEqual(n, m);
|
||||
case Condition.Lt:
|
||||
return ICompareLess(n, m);
|
||||
case Condition.Gt:
|
||||
return ICompareGreater(n, m);
|
||||
case Condition.Le:
|
||||
return ICompareLessOrEqual(n, m);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (n, m);
|
||||
case Condition.GeUn: return ICompareGreaterOrEqualUI(n, m);
|
||||
case Condition.LtUn: return ICompareLessUI (n, m);
|
||||
case Condition.GtUn: return ICompareGreaterUI (n, m);
|
||||
case Condition.LeUn: return ICompareLessOrEqualUI (n, m);
|
||||
case Condition.Ge: return ICompareGreaterOrEqual (n, m);
|
||||
case Condition.Lt: return ICompareLess (n, m);
|
||||
case Condition.Gt: return ICompareGreater (n, m);
|
||||
case Condition.Le: return ICompareLessOrEqual (n, m);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
else if (cmpName == InstName.Adds && _optOpLastCompare is IOpCodeAluImm op)
|
||||
@@ -264,20 +257,14 @@ namespace ARMeilleure.Translation
|
||||
|
||||
switch (condition)
|
||||
{
|
||||
|
||||
case Condition.Eq:
|
||||
return ICompareEqual(n, m);
|
||||
case Condition.Ne:
|
||||
return ICompareNotEqual(n, m);
|
||||
case Condition.Ge:
|
||||
return ICompareGreaterOrEqual(n, m);
|
||||
case Condition.Lt:
|
||||
return ICompareLess(n, m);
|
||||
case Condition.Gt:
|
||||
return ICompareGreater(n, m);
|
||||
case Condition.Le:
|
||||
return ICompareLessOrEqual(n, m);
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case Condition.Eq: return ICompareEqual (n, m);
|
||||
case Condition.Ne: return ICompareNotEqual (n, m);
|
||||
case Condition.Ge: return ICompareGreaterOrEqual(n, m);
|
||||
case Condition.Lt: return ICompareLess (n, m);
|
||||
case Condition.Gt: return ICompareGreater (n, m);
|
||||
case Condition.Le: return ICompareLessOrEqual (n, m);
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,17 +22,18 @@ using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Threading;
|
||||
using static ARMeilleure.Translation.PTC.PtcFormatter;
|
||||
using Arm64HardwareCapabilities = ARMeilleure.CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = ARMeilleure.CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
namespace ARMeilleure.Translation.PTC
|
||||
{
|
||||
using Arm64HardwareCapabilities = CodeGen.Arm64.HardwareCapabilities;
|
||||
using X86HardwareCapabilities = CodeGen.X86.HardwareCapabilities;
|
||||
|
||||
class Ptc : IPtcLoadState
|
||||
{
|
||||
private const string OuterHeaderMagicString = "PTCohd\0\0";
|
||||
private const string InnerHeaderMagicString = "PTCihd\0\0";
|
||||
|
||||
private const uint InternalVersion = 7008; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
private const uint InternalVersion = 7009; //! To be incremented manually for each change to the ARMeilleure project.
|
||||
|
||||
private const string ActualDir = "0";
|
||||
private const string BackupDir = "1";
|
||||
@@ -302,6 +303,13 @@ namespace ARMeilleure.Translation.PTC
|
||||
return false;
|
||||
}
|
||||
|
||||
if (outerHeader.DebuggerMode != Optimizations.EnableDebugging)
|
||||
{
|
||||
InvalidateCompressedStream(compressedStream);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
nint intPtr = nint.Zero;
|
||||
|
||||
try
|
||||
@@ -478,6 +486,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
MemoryManagerMode = GetMemoryManagerMode(),
|
||||
OSPlatform = GetOSPlatform(),
|
||||
Architecture = (uint)RuntimeInformation.ProcessArchitecture,
|
||||
DebuggerMode = Optimizations.EnableDebugging,
|
||||
|
||||
UncompressedStreamSize =
|
||||
(long)Unsafe.SizeOf<InnerHeader>() +
|
||||
@@ -1067,7 +1076,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
return osPlatform;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 86*/)]
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1/*, Size = 87*/)]
|
||||
private struct OuterHeader
|
||||
{
|
||||
public ulong Magic;
|
||||
@@ -1079,6 +1088,7 @@ namespace ARMeilleure.Translation.PTC
|
||||
public byte MemoryManagerMode;
|
||||
public uint OSPlatform;
|
||||
public uint Architecture;
|
||||
public bool DebuggerMode;
|
||||
|
||||
public long UncompressedStreamSize;
|
||||
|
||||
|
@@ -297,20 +297,12 @@ namespace ARMeilleure.Translation
|
||||
|
||||
switch (register.Type)
|
||||
{
|
||||
|
||||
case RegisterType.Flag:
|
||||
intMask = (1L << RegsCount) << register.Index;
|
||||
break;
|
||||
case RegisterType.Integer:
|
||||
intMask = 1L << register.Index;
|
||||
break;
|
||||
case RegisterType.FpFlag:
|
||||
vecMask = (1L << RegsCount) << register.Index;
|
||||
break;
|
||||
case RegisterType.Vector:
|
||||
vecMask = 1L << register.Index;
|
||||
break;
|
||||
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case RegisterType.Flag: intMask = (1L << RegsCount) << register.Index; break;
|
||||
case RegisterType.Integer: intMask = 1L << register.Index; break;
|
||||
case RegisterType.FpFlag: vecMask = (1L << RegsCount) << register.Index; break;
|
||||
case RegisterType.Vector: vecMask = 1L << register.Index; break;
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
|
||||
return new RegisterMask(intMask, vecMask);
|
||||
|
@@ -119,7 +119,25 @@ namespace ARMeilleure.Translation
|
||||
|
||||
NativeInterface.RegisterThread(context, Memory, this);
|
||||
|
||||
if (Optimizations.UseUnmanagedDispatchLoop)
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
context.DebugPc = address;
|
||||
do
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref context.ShouldStep, 0, 1) == 1)
|
||||
{
|
||||
context.DebugPc = Step(context, context.DebugPc);
|
||||
context.StepHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
context.DebugPc = ExecuteSingle(context, context.DebugPc);
|
||||
}
|
||||
context.CheckInterrupt();
|
||||
}
|
||||
while (context.Running && context.DebugPc != 0);
|
||||
}
|
||||
else if (Optimizations.UseUnmanagedDispatchLoop)
|
||||
{
|
||||
Stubs.DispatchLoop(context.NativeContextPtr, address);
|
||||
}
|
||||
@@ -175,7 +193,7 @@ namespace ARMeilleure.Translation
|
||||
return nextAddr;
|
||||
}
|
||||
|
||||
public ulong Step(State.ExecutionContext context, ulong address)
|
||||
private ulong Step(State.ExecutionContext context, ulong address)
|
||||
{
|
||||
TranslatedFunction func = Translate(address, context.ExecutionMode, highCq: false, singleStep: true);
|
||||
|
||||
@@ -186,6 +204,8 @@ namespace ARMeilleure.Translation
|
||||
return address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal TranslatedFunction GetOrTranslate(ulong address, ExecutionMode mode)
|
||||
{
|
||||
if (!Functions.TryGetValue(address, out TranslatedFunction func))
|
||||
@@ -229,7 +249,8 @@ namespace ARMeilleure.Translation
|
||||
address,
|
||||
highCq,
|
||||
_ptc.State != PtcState.Disabled,
|
||||
mode: Aarch32Mode.User);
|
||||
mode: Aarch32Mode.User,
|
||||
isSingleStep: singleStep);
|
||||
|
||||
Logger.StartPass(PassName.Decoding);
|
||||
|
||||
@@ -367,9 +388,13 @@ namespace ARMeilleure.Translation
|
||||
|
||||
if (block.Exit)
|
||||
{
|
||||
// Left option here as it may be useful if we need to return to managed rather than tail call in
|
||||
// future. (eg. for debug)
|
||||
bool useReturns = false;
|
||||
// Return to managed rather than tail call.
|
||||
bool useReturns = Optimizations.EnableDebugging;
|
||||
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
EmitDebugPrecisePcUpdate(context, block.Address);
|
||||
}
|
||||
|
||||
InstEmitFlowHelper.EmitVirtualJump(context, Const(block.Address), isReturn: useReturns);
|
||||
}
|
||||
@@ -393,6 +418,11 @@ namespace ARMeilleure.Translation
|
||||
}
|
||||
}
|
||||
|
||||
if (Optimizations.EnableDebugging)
|
||||
{
|
||||
EmitDebugPrecisePcUpdate(context, opCode.Address);
|
||||
}
|
||||
|
||||
Operand lblPredicateSkip = default;
|
||||
|
||||
if (context.IsInIfThenBlock && context.CurrentIfThenBlockCond != Condition.Al)
|
||||
@@ -489,6 +519,14 @@ namespace ARMeilleure.Translation
|
||||
context.MarkLabel(lblExit);
|
||||
}
|
||||
|
||||
internal static void EmitDebugPrecisePcUpdate(EmitterContext context, ulong address)
|
||||
{
|
||||
long debugPrecisePcOffs = NativeContext.GetDebugPrecisePcOffset();
|
||||
|
||||
Operand debugPrecisePcAddr = context.Add(context.LoadArgument(OperandType.I64, 0), Const(debugPrecisePcOffs));
|
||||
context.Store(debugPrecisePcAddr, Const(address));
|
||||
}
|
||||
|
||||
public void InvalidateJitCacheRegion(ulong address, ulong size)
|
||||
{
|
||||
ulong[] overlapAddresses = [];
|
||||
|
@@ -12,7 +12,7 @@ using static SDL2.SDL;
|
||||
|
||||
namespace Ryujinx.Audio.Backends.SDL2
|
||||
{
|
||||
public partial class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
||||
public class SDL2HardwareDeviceDriver : IHardwareDeviceDriver
|
||||
{
|
||||
private readonly ManualResetEvent _updateRequiredEvent;
|
||||
private readonly ManualResetEvent _pauseEvent;
|
||||
@@ -22,36 +22,10 @@ namespace Ryujinx.Audio.Backends.SDL2
|
||||
|
||||
public float Volume { get; set; }
|
||||
|
||||
// A safe method to get default audio information.
|
||||
private static int GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture)
|
||||
{
|
||||
int result;
|
||||
spec = new SDL_AudioSpec();
|
||||
IntPtr specPtr = IntPtr.Zero;
|
||||
|
||||
try
|
||||
{
|
||||
// Reserve memory
|
||||
specPtr = Marshal.AllocHGlobal(Marshal.SizeOf<SDL_AudioSpec>());
|
||||
// Call method
|
||||
result = SDL_GetDefaultAudioInfo(name, specPtr, isCapture);
|
||||
// Copy result to managed structure
|
||||
spec = Marshal.PtrToStructure<SDL_AudioSpec>(specPtr);
|
||||
}
|
||||
finally
|
||||
{
|
||||
// Free the unmanaged memory to prevent memory leaks
|
||||
if (specPtr != IntPtr.Zero)
|
||||
{
|
||||
Marshal.FreeHGlobal(specPtr);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
[LibraryImport("SDL2")]
|
||||
private static partial int SDL_GetDefaultAudioInfo(nint name, nint spec, int isCapture);
|
||||
// TODO: Add this to SDL2-CS
|
||||
// NOTE: We use a DllImport here because of marshaling issue for spec.
|
||||
[DllImport("SDL2")]
|
||||
private static extern int SDL_GetDefaultAudioInfo(nint name, out SDL_AudioSpec spec, int isCapture);
|
||||
|
||||
public SDL2HardwareDeviceDriver()
|
||||
{
|
||||
@@ -61,7 +35,7 @@ namespace Ryujinx.Audio.Backends.SDL2
|
||||
|
||||
SDL2Driver.Instance.Initialize();
|
||||
|
||||
int res = GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
|
||||
int res = SDL_GetDefaultAudioInfo(nint.Zero, out SDL_AudioSpec spec, 0);
|
||||
|
||||
if (res != 0)
|
||||
{
|
||||
|
@@ -23,7 +23,7 @@ namespace Ryujinx.Audio.Backends.SoundIo.Native
|
||||
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||
public delegate void JackCallbackDelegate(nint msg);
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct SoundIoStruct
|
||||
{
|
||||
public nint UserData;
|
||||
|
@@ -20,7 +20,9 @@ namespace Ryujinx.Audio.Renderer.Common
|
||||
public uint Unknown24;
|
||||
public uint RenderInfoSize;
|
||||
|
||||
#pragma warning disable IDE0051, CS0169 // Remove unused field
|
||||
private Array4<int> _reserved;
|
||||
#pragma warning restore IDE0051, CS0169
|
||||
|
||||
public uint TotalSize;
|
||||
|
||||
|
@@ -12,8 +12,9 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
private const int SamplesPerFrame = 14;
|
||||
private const int NibblesPerFrame = SamplesPerFrame + 2;
|
||||
private const int BytesPerFrame = 8;
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private const int BitsPerFrame = BytesPerFrame * 8;
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static uint GetAdpcmDataSize(int sampleCount)
|
||||
@@ -80,14 +81,14 @@ namespace Ryujinx.Audio.Renderer.Dsp
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private static short GetCoefficientAtIndex(ReadOnlySpan<short> coefficients, int index)
|
||||
{
|
||||
if ((uint)index < (uint)coefficients.Length)
|
||||
if ((uint)index >= (uint)coefficients.Length)
|
||||
{
|
||||
return coefficients[index];
|
||||
Logger.Error?.Print(LogClass.AudioRenderer, $"Out of bound read for coefficient at index {index}");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Logger.Error?.Print(LogClass.AudioRenderer, $"Out of bound read for coefficient at index {index}");
|
||||
|
||||
return 0;
|
||||
return coefficients[index];
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
@@ -41,10 +41,10 @@ namespace Ryujinx.Audio.Renderer.Server
|
||||
private UpsamplerManager _upsamplerManager;
|
||||
private bool _isActive;
|
||||
private BehaviourContext _behaviourContext;
|
||||
|
||||
#pragma warning disable IDE0052 // Remove unread private member
|
||||
private ulong _totalElapsedTicksUpdating;
|
||||
private ulong _totalElapsedTicks;
|
||||
|
||||
#pragma warning restore IDE0052
|
||||
private int _sessionId;
|
||||
private Memory<MemoryPoolState> _memoryPools;
|
||||
|
||||
|
@@ -33,7 +33,7 @@ namespace Ryujinx.BuildValidationTasks
|
||||
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...");
|
||||
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, rebuild locally to fix...");
|
||||
|
||||
try
|
||||
{
|
||||
@@ -86,7 +86,7 @@ namespace Ryujinx.BuildValidationTasks
|
||||
}
|
||||
|
||||
if (isGitRunner && encounteredIssue)
|
||||
throw new JsonException("1 or more locales are invalid!");
|
||||
throw new JsonException("1 or more locales are invalid! Rebuild locally to fix...");
|
||||
|
||||
string jsonString = JsonSerializer.Serialize(json, _jsonOptions);
|
||||
|
||||
@@ -102,6 +102,7 @@ namespace Ryujinx.BuildValidationTasks
|
||||
|
||||
struct LocalesJson
|
||||
{
|
||||
public Dictionary<string, string> Info { get; set; }
|
||||
public List<string> Languages { get; set; }
|
||||
public List<LocalesEntry> Locales { get; set; }
|
||||
}
|
||||
|
@@ -10,8 +10,18 @@
|
||||
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
|
||||
Command="dotnet Ryujinx.BuildValidationTasks.dll "$(ProjectDir)..\..\\""
|
||||
ConsoleToMsBuild="true"
|
||||
Condition="'$(RuntimeIdentifier)' == ''"
|
||||
/>
|
||||
Condition="'$(RuntimeIdentifier)' == ''"
|
||||
IgnoreExitCode="true">
|
||||
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
|
||||
<Output TaskParameter="ExitCode" PropertyName="BuildExitCode"/>
|
||||
</Exec>
|
||||
|
||||
<PropertyGroup Condition=" '$(OutputOfExec.IndexOf(Unhandled exception))' != '-1'">
|
||||
<ErrorOutput>$(OutputOfExec.Substring($(OutputOfExec.IndexOf("Unhandled exception"))))</ErrorOutput>
|
||||
<ErrorOutput>$(ErrorOutput.Substring(0, $(ErrorOutput.IndexOf(';'))))</ErrorOutput>
|
||||
</PropertyGroup>
|
||||
|
||||
<Error Text="$(ErrorOutput)" Condition=" '$(BuildExitCode)' != '0'"/>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
</Project>
|
||||
|
@@ -14,12 +14,13 @@ namespace Ryujinx.Common.Collections
|
||||
/// Adds a new node into the tree.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to be added</param>
|
||||
/// <param name="parent">Node to be added under</param>
|
||||
/// <exception cref="ArgumentNullException"><paramref name="node"/> is null</exception>
|
||||
public void Add(T node)
|
||||
public void Add(T node, T parent = null)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(node);
|
||||
|
||||
Insert(node);
|
||||
Insert(node, parent);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -76,9 +77,11 @@ namespace Ryujinx.Common.Collections
|
||||
/// Inserts a new node into the tree.
|
||||
/// </summary>
|
||||
/// <param name="node">Node to be inserted</param>
|
||||
private void Insert(T node)
|
||||
/// <param name="parent">Node to be inserted under</param>
|
||||
private void Insert(T node, T parent = null)
|
||||
{
|
||||
T newNode = BSTInsert(node);
|
||||
T newNode = parent != null ? InsertWithParent(node, parent) : BSTInsert(node);
|
||||
|
||||
RestoreBalanceAfterInsertion(newNode);
|
||||
}
|
||||
|
||||
@@ -122,10 +125,78 @@ namespace Ryujinx.Common.Collections
|
||||
else if (newNode.CompareTo(parent) < 0)
|
||||
{
|
||||
parent.Left = newNode;
|
||||
|
||||
newNode.Successor = parent;
|
||||
|
||||
if (parent.Predecessor != null)
|
||||
{
|
||||
newNode.Predecessor = parent.Predecessor;
|
||||
parent.Predecessor = newNode;
|
||||
newNode.Predecessor.Successor = newNode;
|
||||
}
|
||||
|
||||
parent.Predecessor = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Right = newNode;
|
||||
|
||||
newNode.Predecessor = parent;
|
||||
|
||||
if (parent.Successor != null)
|
||||
{
|
||||
newNode.Successor = parent.Successor;
|
||||
newNode.Successor.Predecessor = newNode;
|
||||
}
|
||||
|
||||
parent.Successor = newNode;
|
||||
}
|
||||
Count++;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Insertion Mechanism for a Binary Search Tree (BST).
|
||||
/// <br></br>
|
||||
/// Inserts a new node directly under a parent node
|
||||
/// where all children in the left subtree are less than <paramref name="newNode"/>,
|
||||
/// and all children in the right subtree are greater than <paramref name="newNode"/>.
|
||||
/// </summary>
|
||||
/// <param name="newNode">Node to be inserted</param>
|
||||
/// <param name="parent">Node to be inserted under</param>
|
||||
/// <returns>The inserted Node</returns>
|
||||
private T InsertWithParent(T newNode, T parent)
|
||||
{
|
||||
newNode.Parent = parent;
|
||||
|
||||
if (newNode.CompareTo(parent) < 0)
|
||||
{
|
||||
parent.Left = newNode;
|
||||
|
||||
newNode.Successor = parent;
|
||||
|
||||
if (parent.Predecessor != null)
|
||||
{
|
||||
newNode.Predecessor = parent.Predecessor;
|
||||
parent.Predecessor = newNode;
|
||||
newNode.Predecessor.Successor = newNode;
|
||||
}
|
||||
|
||||
parent.Predecessor = newNode;
|
||||
}
|
||||
else
|
||||
{
|
||||
parent.Right = newNode;
|
||||
|
||||
newNode.Predecessor = parent;
|
||||
|
||||
if (parent.Successor != null)
|
||||
{
|
||||
newNode.Successor = parent.Successor;
|
||||
newNode.Successor.Predecessor = newNode;
|
||||
}
|
||||
|
||||
parent.Successor = newNode;
|
||||
}
|
||||
|
||||
Count++;
|
||||
@@ -159,7 +230,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
else
|
||||
{
|
||||
T element = Minimum(RightOf(nodeToDelete));
|
||||
T element = nodeToDelete.Successor;
|
||||
|
||||
child = RightOf(element);
|
||||
parent = ParentOf(element);
|
||||
@@ -187,6 +258,9 @@ namespace Ryujinx.Common.Collections
|
||||
element.Left = old.Left;
|
||||
element.Right = old.Right;
|
||||
element.Parent = old.Parent;
|
||||
element.Predecessor = old.Predecessor;
|
||||
if (element.Predecessor != null)
|
||||
element.Predecessor.Successor = element;
|
||||
|
||||
if (ParentOf(old) == null)
|
||||
{
|
||||
@@ -241,6 +315,11 @@ namespace Ryujinx.Common.Collections
|
||||
{
|
||||
RestoreBalanceAfterRemoval(child);
|
||||
}
|
||||
|
||||
if (old.Successor != null)
|
||||
old.Successor.Predecessor = old.Predecessor;
|
||||
if (old.Predecessor != null)
|
||||
old.Predecessor.Successor = old.Successor;
|
||||
|
||||
return old;
|
||||
}
|
||||
|
@@ -9,8 +9,7 @@ namespace Ryujinx.Common.Collections
|
||||
public T Left;
|
||||
public T Right;
|
||||
public T Parent;
|
||||
|
||||
public T Predecessor => IntrusiveRedBlackTreeImpl<T>.PredecessorOf((T)this);
|
||||
public T Successor => IntrusiveRedBlackTreeImpl<T>.SuccessorOf((T)this);
|
||||
public T Predecessor;
|
||||
public T Successor;
|
||||
}
|
||||
}
|
||||
|
@@ -109,7 +109,7 @@ namespace Ryujinx.Common.Collections
|
||||
Node<TKey, TValue> node = GetNode(key);
|
||||
if (node != null)
|
||||
{
|
||||
Node<TKey, TValue> successor = SuccessorOf(node);
|
||||
Node<TKey, TValue> successor = node.Successor;
|
||||
|
||||
return successor != null ? successor.Key : default;
|
||||
}
|
||||
@@ -127,7 +127,7 @@ namespace Ryujinx.Common.Collections
|
||||
Node<TKey, TValue> node = GetNode(key);
|
||||
if (node != null)
|
||||
{
|
||||
Node<TKey, TValue> predecessor = PredecessorOf(node);
|
||||
Node<TKey, TValue> predecessor = node.Predecessor;
|
||||
|
||||
return predecessor != null ? predecessor.Key : default;
|
||||
}
|
||||
@@ -136,20 +136,19 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all the nodes in the dictionary as key/value pairs into <paramref name="list"/>.
|
||||
/// Adds all the nodes in the dictionary as key/value pairs into a list.
|
||||
/// <br></br>
|
||||
/// The key/value pairs will be added in Level Order.
|
||||
/// </summary>
|
||||
/// <param name="list">List to add the tree pairs into</param>
|
||||
public List<KeyValuePair<TKey, TValue>> AsLevelOrderList()
|
||||
{
|
||||
List<KeyValuePair<TKey, TValue>> list = [];
|
||||
|
||||
Queue<Node<TKey, TValue>> nodes = new();
|
||||
|
||||
if (Root != null)
|
||||
if (this.Root != null)
|
||||
{
|
||||
nodes.Enqueue(Root);
|
||||
nodes.Enqueue(this.Root);
|
||||
}
|
||||
|
||||
while (nodes.TryDequeue(out Node<TKey, TValue> node))
|
||||
@@ -170,7 +169,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds all the nodes in the dictionary into <paramref name="list"/>.
|
||||
/// Adds all the nodes in the dictionary into a list.
|
||||
/// </summary>
|
||||
/// <returns>A list of all KeyValuePairs sorted by Key Order</returns>
|
||||
public List<KeyValuePair<TKey, TValue>> AsList()
|
||||
@@ -284,7 +283,7 @@ namespace Ryujinx.Common.Collections
|
||||
}
|
||||
|
||||
Node<TKey, TValue> newNode = new(key, value, parent);
|
||||
if (newNode.Parent == null)
|
||||
if (parent == null)
|
||||
{
|
||||
Root = newNode;
|
||||
}
|
||||
@@ -522,7 +521,7 @@ namespace Ryujinx.Common.Collections
|
||||
|
||||
public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
|
||||
{
|
||||
if (arrayIndex < 0 || array.Length - arrayIndex < Count)
|
||||
if (arrayIndex < 0 || array.Length - arrayIndex < this.Count)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException(nameof(arrayIndex));
|
||||
}
|
||||
|
@@ -36,6 +36,8 @@ namespace Ryujinx.Common.Configuration
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||
{
|
||||
return aspectRatio switch
|
||||
|
@@ -18,6 +18,8 @@ namespace Ryujinx.Common.Configuration
|
||||
public DirtyHack Hack => hack;
|
||||
public int Value => value;
|
||||
|
||||
|
||||
|
||||
public ulong Pack() => Raw.PackBitFields(PackedFormat);
|
||||
|
||||
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||
|
@@ -10,7 +10,7 @@ using System.Runtime.Intrinsics.X86;
|
||||
|
||||
namespace Ryujinx.Common
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct Hash128(ulong low, ulong high) : IEquatable<Hash128>
|
||||
{
|
||||
public ulong Low = low;
|
||||
|
@@ -13,6 +13,7 @@ namespace Ryujinx.Common.Logging
|
||||
Cpu,
|
||||
Emulation,
|
||||
FFmpeg,
|
||||
GdbStub,
|
||||
Font,
|
||||
Gpu,
|
||||
Hid,
|
||||
|
@@ -219,34 +219,16 @@ namespace Ryujinx.Common.Logging
|
||||
switch (logLevel)
|
||||
{
|
||||
#pragma warning disable IDE0055 // Disable formatting
|
||||
case LogLevel.Debug:
|
||||
Debug = enabled ? new Log(LogLevel.Debug) : new Log?();
|
||||
break;
|
||||
case LogLevel.Info:
|
||||
Info = enabled ? new Log(LogLevel.Info) : new Log?();
|
||||
break;
|
||||
case LogLevel.Warning:
|
||||
Warning = enabled ? new Log(LogLevel.Warning) : new Log?();
|
||||
break;
|
||||
case LogLevel.Error:
|
||||
Error = enabled ? new Log(LogLevel.Error) : new Log?();
|
||||
break;
|
||||
case LogLevel.Guest:
|
||||
Guest = enabled ? new Log(LogLevel.Guest) : new Log?();
|
||||
break;
|
||||
case LogLevel.AccessLog:
|
||||
AccessLog = enabled ? new Log(LogLevel.AccessLog) : new Log?();
|
||||
break;
|
||||
case LogLevel.Stub:
|
||||
Stub = enabled ? new Log(LogLevel.Stub) : new Log?();
|
||||
break;
|
||||
case LogLevel.Trace:
|
||||
Trace = enabled ? new Log(LogLevel.Trace) : new Log?();
|
||||
break;
|
||||
case LogLevel.Notice:
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Unknown Log Level", nameof(logLevel));
|
||||
case LogLevel.Debug : Debug = enabled ? new Log(LogLevel.Debug) : new Log?(); break;
|
||||
case LogLevel.Info : Info = enabled ? new Log(LogLevel.Info) : new Log?(); break;
|
||||
case LogLevel.Warning : Warning = enabled ? new Log(LogLevel.Warning) : new Log?(); break;
|
||||
case LogLevel.Error : Error = enabled ? new Log(LogLevel.Error) : new Log?(); break;
|
||||
case LogLevel.Guest : Guest = enabled ? new Log(LogLevel.Guest) : new Log?(); break;
|
||||
case LogLevel.AccessLog : AccessLog = enabled ? new Log(LogLevel.AccessLog) : new Log?(); break;
|
||||
case LogLevel.Stub : Stub = enabled ? new Log(LogLevel.Stub) : new Log?(); break;
|
||||
case LogLevel.Trace : Trace = enabled ? new Log(LogLevel.Trace) : new Log?(); break;
|
||||
case LogLevel.Notice : break;
|
||||
default: throw new ArgumentException("Unknown Log Level", nameof(logLevel));
|
||||
#pragma warning restore IDE0055
|
||||
}
|
||||
}
|
||||
|
@@ -2,9 +2,9 @@ using System;
|
||||
using System.Diagnostics.Contracts;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
#pragma warning disable CS0169, IDE0051 // Remove unused private member
|
||||
namespace Ryujinx.Common.Memory
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array1<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -15,7 +15,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array2<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -27,7 +26,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array3<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -39,7 +37,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array4<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -51,7 +48,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array5<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -63,7 +59,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array6<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -75,7 +70,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array7<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -87,7 +81,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array8<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -99,7 +92,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array9<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -111,7 +103,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array10<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -123,7 +114,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array11<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -135,7 +125,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array12<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -147,7 +136,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array13<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -159,7 +147,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array14<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -171,7 +158,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array15<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -183,7 +169,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array16<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -195,7 +180,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array17<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -207,7 +191,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array18<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -219,7 +202,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array19<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -231,7 +213,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array20<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -243,7 +224,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array21<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -255,7 +235,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array22<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -267,7 +246,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array23<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -279,7 +257,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array24<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -292,7 +269,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array25<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -305,7 +281,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array26<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -318,7 +293,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array27<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -331,7 +305,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array28<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -344,7 +317,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array29<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -357,7 +329,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array30<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -370,7 +341,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array31<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -383,7 +353,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array32<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -396,7 +365,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array33<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -409,7 +377,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array34<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -422,7 +389,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array35<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -435,7 +401,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array36<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -448,7 +413,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array37<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -461,7 +425,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array38<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -474,7 +437,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array39<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -487,7 +449,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array40<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -500,7 +461,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array41<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -513,7 +473,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array42<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -526,7 +485,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array43<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -539,7 +497,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array44<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -552,7 +509,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array45<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -565,7 +521,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array46<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -578,7 +533,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array47<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -591,7 +545,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array48<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -604,7 +557,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array49<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -617,7 +569,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array50<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -630,7 +581,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array51<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -643,7 +593,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array52<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -656,7 +605,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array53<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -669,7 +617,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array54<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -682,7 +629,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array55<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -695,7 +641,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array56<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -708,7 +653,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array57<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -721,7 +665,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array58<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -734,7 +677,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array59<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -747,7 +689,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array60<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -759,7 +700,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array61<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -771,7 +711,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array62<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -783,7 +722,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array63<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -795,7 +733,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array64<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -807,7 +744,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array65<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -819,7 +755,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array73<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -832,7 +767,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array96<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -845,7 +779,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array127<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -858,7 +791,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array128<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -871,7 +803,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array140<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -885,7 +816,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array256<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -898,7 +828,6 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
public struct Array384<T> : IArray<T> where T : unmanaged
|
||||
{
|
||||
T _e0;
|
||||
@@ -915,4 +844,4 @@ namespace Ryujinx.Common.Memory
|
||||
public Span<T> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, Length);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma warning restore CS0169, IDE0051
|
||||
|
@@ -94,7 +94,7 @@ namespace Ryujinx.Common.PreciseSleep
|
||||
Bias = GetBias(0);
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Timespec
|
||||
{
|
||||
public long tv_sec; // Seconds
|
||||
|
@@ -1,5 +1,10 @@
|
||||
using Ryujinx.Common.Utilities;
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Reflection;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ryujinx.Common
|
||||
{
|
||||
@@ -32,4 +37,6 @@ namespace Ryujinx.Common
|
||||
? $"https://git.ryujinx.app/ryubing/ryujinx/-/compare/Canary-{currentVersion}...Canary-{newVersion}"
|
||||
: $"https://git.ryujinx.app/ryubing/ryujinx/-/releases/{newVersion}";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@@ -28,10 +28,12 @@ namespace Ryujinx.Common.SystemInterop
|
||||
{
|
||||
public int GdiplusVersion;
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public nint DebugEventCallback;
|
||||
public int SuppressBackgroundThread;
|
||||
public int SuppressExternalCodecs;
|
||||
public int StartupParameters;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
public static StartupInputEx Default => new()
|
||||
{
|
||||
|
@@ -12,7 +12,7 @@ namespace Ryujinx.Common.SystemInterop
|
||||
[SupportedOSPlatform("windows")]
|
||||
public partial class WindowsMultimediaTimerResolution : IDisposable
|
||||
{
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct TimeCaps
|
||||
{
|
||||
public uint wPeriodMin;
|
||||
|
@@ -93,6 +93,7 @@ namespace Ryujinx.Common
|
||||
//The Pokémon Franchise
|
||||
"0100f4300bf2c000", // New Pokémon Snap
|
||||
"0100000011d90000", // Pokémon Brilliant Diamond
|
||||
"010008c01e742000", // Pokémon Friends
|
||||
"01001f5010dfa000", // Pokémon Legends: Arceus
|
||||
"01003d200baa2000", // Pokémon Mystery Dungeon - Rescue Team DX
|
||||
"0100a3d008c5c000", // Pokémon Scarlet
|
||||
@@ -195,6 +196,7 @@ namespace Ryujinx.Common
|
||||
"01008d100d43e000", // Saints Row IV
|
||||
"0100de600beee000", // Saints Row: The Third - The Full Package
|
||||
"01001180021fa000", // Shovel Knight: Specter of Torment
|
||||
"0100e1D01eb2e000", // Squeakross: Home Squeak Home
|
||||
"0100e65002bb8000", // Stardew Valley
|
||||
"0100d7a01b7a2000", // Star Wars: Bounty Hunter
|
||||
"0100800015926000", // Suika Game
|
||||
|
@@ -9,8 +9,8 @@ namespace Ryujinx.Common.Utilities
|
||||
[StructLayout(LayoutKind.Sequential, Size = 16)]
|
||||
public struct Buffer16
|
||||
{
|
||||
public ulong Low { get; set; }
|
||||
public ulong High { get; set; }
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong _dummy0;
|
||||
[DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly ulong _dummy1;
|
||||
|
||||
public byte this[int i]
|
||||
{
|
||||
|
@@ -241,7 +241,7 @@ namespace Ryujinx.Common.Utilities
|
||||
|
||||
public IndentedStringBuilder Append(object value)
|
||||
{
|
||||
Append(value.ToString());
|
||||
this.Append(value.ToString());
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -271,7 +271,7 @@ namespace Ryujinx.Common.Utilities
|
||||
{
|
||||
_builder.Append(value);
|
||||
|
||||
AppendLine();
|
||||
this.AppendLine();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@@ -32,6 +32,7 @@ namespace Ryujinx.Common.Utilities
|
||||
CyclingEnabled = false;
|
||||
}
|
||||
|
||||
|
||||
public static float Speed { get; set; } = 1;
|
||||
|
||||
private static readonly Lock _lock = new();
|
||||
|
10
src/Ryujinx.Cpu/AppleHv/Arm/ExceptionLevel.cs
Normal file
10
src/Ryujinx.Cpu/AppleHv/Arm/ExceptionLevel.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Ryujinx.Cpu.AppleHv.Arm
|
||||
{
|
||||
enum ExceptionLevel : uint
|
||||
{
|
||||
PstateMask = 0xfffffff0,
|
||||
EL1h = 0b0101,
|
||||
El1t = 0b0100,
|
||||
EL0 = 0b0000,
|
||||
}
|
||||
}
|
17
src/Ryujinx.Cpu/AppleHv/DummyDiskCacheLoadState.cs
Normal file
17
src/Ryujinx.Cpu/AppleHv/DummyDiskCacheLoadState.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
using System;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
public class DummyDiskCacheLoadState : IDiskCacheLoadState
|
||||
{
|
||||
#pragma warning disable CS0067 // The event is never used
|
||||
/// <inheritdoc/>
|
||||
public event Action<LoadState, int, int> StateChanged;
|
||||
#pragma warning restore CS0067
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Cancel()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@@ -6,11 +6,11 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
struct HvVcpuExitException
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public ulong Syndrome;
|
||||
public ulong VirtualAddress;
|
||||
public ulong PhysicalAddress;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
enum HvExitReason : uint
|
||||
@@ -23,10 +23,10 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
struct HvVcpuExit
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public HvExitReason Reason;
|
||||
public HvVcpuExitException Exception;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
enum HvReg : uint
|
||||
|
@@ -11,7 +11,18 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
class HvExecutionContext : IExecutionContext
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public ulong Pc => _impl.ElrEl1;
|
||||
public ulong Pc
|
||||
{
|
||||
get
|
||||
{
|
||||
uint currentEl = Pstate & ~((uint)ExceptionLevel.PstateMask);
|
||||
if (currentEl == (uint)ExceptionLevel.EL1h)
|
||||
{
|
||||
return _impl.ElrEl1;
|
||||
}
|
||||
return _impl.Pc;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public long TpidrEl0
|
||||
@@ -48,6 +59,9 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
set => _impl.Fpsr = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool IsAarch32
|
||||
{
|
||||
@@ -67,6 +81,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
private readonly ICounter _counter;
|
||||
private readonly IHvExecutionContext _shadowContext;
|
||||
private IHvExecutionContext _impl;
|
||||
private int _shouldStep;
|
||||
|
||||
private readonly ExceptionCallbacks _exceptionCallbacks;
|
||||
|
||||
@@ -103,6 +118,11 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
_exceptionCallbacks.BreakCallback?.Invoke(this, address, imm);
|
||||
}
|
||||
|
||||
private void StepHandler()
|
||||
{
|
||||
_exceptionCallbacks.StepCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
private void SupervisorCallHandler(ulong address, int imm)
|
||||
{
|
||||
_exceptionCallbacks.SupervisorCallback?.Invoke(this, address, imm);
|
||||
@@ -127,6 +147,30 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RequestDebugStep()
|
||||
{
|
||||
Interlocked.Exchange(ref _shouldStep, 1);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong DebugPc
|
||||
{
|
||||
get => Pc;
|
||||
set
|
||||
{
|
||||
uint currentEl = Pstate & ~((uint)ExceptionLevel.PstateMask);
|
||||
if (currentEl == (uint)ExceptionLevel.EL1h)
|
||||
{
|
||||
_impl.ElrEl1 = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
_impl.Pc = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void StopRunning()
|
||||
{
|
||||
@@ -142,6 +186,22 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
while (Running)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref _shouldStep, 0, 1) == 1)
|
||||
{
|
||||
uint currentEl = Pstate & ~((uint)ExceptionLevel.PstateMask);
|
||||
if (currentEl == (uint)ExceptionLevel.EL1h)
|
||||
{
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpu.Handle, HvSysReg.SPSR_EL1, out ulong spsr).ThrowOnError();
|
||||
spsr |= (1 << 21);
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu.Handle, HvSysReg.SPSR_EL1, spsr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Pstate |= (1 << 21);
|
||||
}
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpu.Handle, HvSysReg.MDSCR_EL1, 1);
|
||||
}
|
||||
|
||||
HvApi.hv_vcpu_run(vcpu.Handle).ThrowOnError();
|
||||
|
||||
HvExitReason reason = vcpu.ExitInfo->Reason;
|
||||
@@ -209,6 +269,20 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
SupervisorCallHandler(elr - 4UL, id);
|
||||
vcpu = RentFromPool(memoryManager.AddressSpace, vcpu);
|
||||
break;
|
||||
case ExceptionClass.SoftwareStepLowerEl:
|
||||
HvApi.hv_vcpu_get_sys_reg(vcpuHandle, HvSysReg.SPSR_EL1, out ulong spsr).ThrowOnError();
|
||||
spsr &= ~((ulong)(1 << 21));
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.SPSR_EL1, spsr).ThrowOnError();
|
||||
HvApi.hv_vcpu_set_sys_reg(vcpuHandle, HvSysReg.MDSCR_EL1, 0);
|
||||
ReturnToPool(vcpu);
|
||||
StepHandler();
|
||||
vcpu = RentFromPool(memoryManager.AddressSpace, vcpu);
|
||||
break;
|
||||
case ExceptionClass.BrkAarch64:
|
||||
ReturnToPool(vcpu);
|
||||
BreakHandler(elr, (ushort)esr);
|
||||
vcpu = RentFromPool(memoryManager.AddressSpace, vcpu);
|
||||
break;
|
||||
default:
|
||||
throw new Exception($"Unhandled guest exception {ec}.");
|
||||
}
|
||||
@@ -219,10 +293,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
// TODO: Invalidate only the range that was modified?
|
||||
return HvAddressSpace.KernelRegionTlbiEretAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HvAddressSpace.KernelRegionEretAddress;
|
||||
}
|
||||
return HvAddressSpace.KernelRegionEretAddress;
|
||||
}
|
||||
|
||||
private static void DataAbort(MemoryTracking tracking, ulong vcpu, uint esr)
|
||||
|
@@ -18,6 +18,8 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
public bool IsAarch32 { get; set; }
|
||||
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
private readonly ulong[] _x;
|
||||
private readonly V128[] _v;
|
||||
|
||||
@@ -46,5 +48,14 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
_v[index] = value;
|
||||
}
|
||||
|
||||
public void RequestInterrupt()
|
||||
{
|
||||
}
|
||||
|
||||
public bool GetAndClearInterruptRequested()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ using ARMeilleure.State;
|
||||
using Ryujinx.Memory;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
@@ -13,6 +14,8 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
private static readonly SetSimdFpReg _setSimdFpReg;
|
||||
private static readonly nint _setSimdFpRegNativePtr;
|
||||
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
static HvExecutionContextVcpu()
|
||||
{
|
||||
// .NET does not support passing vectors by value, so we need to pass a pointer and use a native
|
||||
@@ -135,6 +138,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
}
|
||||
|
||||
private readonly ulong _vcpu;
|
||||
private int _interruptRequested;
|
||||
|
||||
public HvExecutionContextVcpu(ulong vcpu)
|
||||
{
|
||||
@@ -180,8 +184,16 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
public void RequestInterrupt()
|
||||
{
|
||||
ulong vcpu = _vcpu;
|
||||
HvApi.hv_vcpus_exit(ref vcpu, 1);
|
||||
if (Interlocked.Exchange(ref _interruptRequested, 1) == 0)
|
||||
{
|
||||
ulong vcpu = _vcpu;
|
||||
HvApi.hv_vcpus_exit(ref vcpu, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public bool GetAndClearInterruptRequested()
|
||||
{
|
||||
return Interlocked.Exchange(ref _interruptRequested, 0) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
|
||||
uint Fpcr { get; set; }
|
||||
uint Fpsr { get; set; }
|
||||
ulong ThreadUid { get; set; }
|
||||
|
||||
ulong GetX(int index);
|
||||
void SetX(int index, ulong value);
|
||||
@@ -39,5 +40,8 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
SetV(i, context.GetV(i));
|
||||
}
|
||||
}
|
||||
|
||||
void RequestInterrupt();
|
||||
bool GetAndClearInterruptRequested();
|
||||
}
|
||||
}
|
||||
|
@@ -4,10 +4,10 @@ namespace Ryujinx.Cpu
|
||||
{
|
||||
public class DummyDiskCacheLoadState : IDiskCacheLoadState
|
||||
{
|
||||
#pragma warning disable CS0067 // The event is never used
|
||||
/// <inheritdoc/>
|
||||
public event Action<LoadState, int, int> StateChanged;
|
||||
|
||||
public DummyDiskCacheLoadState() => StateChanged?.Invoke(LoadState.Unloaded, 0, 0);
|
||||
#pragma warning restore CS0067
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Cancel()
|
||||
|
@@ -29,6 +29,11 @@ namespace Ryujinx.Cpu
|
||||
/// </summary>
|
||||
public readonly ExceptionCallback BreakCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CPU software interrupts caused by single-stepping.
|
||||
/// </summary>
|
||||
public readonly ExceptionCallbackNoArgs StepCallback;
|
||||
|
||||
/// <summary>
|
||||
/// Handler for CPU software interrupts caused by the Arm SVC instruction.
|
||||
/// </summary>
|
||||
@@ -47,16 +52,19 @@ namespace Ryujinx.Cpu
|
||||
/// </remarks>
|
||||
/// <param name="interruptCallback">Handler for CPU interrupts triggered using <see cref="IExecutionContext.RequestInterrupt"/></param>
|
||||
/// <param name="breakCallback">Handler for CPU software interrupts caused by the Arm BRK instruction</param>
|
||||
/// <param name="stepCallback">Handler for CPU software interrupts caused by single-stepping</param>
|
||||
/// <param name="supervisorCallback">Handler for CPU software interrupts caused by the Arm SVC instruction</param>
|
||||
/// <param name="undefinedCallback">Handler for CPU software interrupts caused by any undefined Arm instruction</param>
|
||||
public ExceptionCallbacks(
|
||||
ExceptionCallbackNoArgs interruptCallback = null,
|
||||
ExceptionCallback breakCallback = null,
|
||||
ExceptionCallbackNoArgs stepCallback = null,
|
||||
ExceptionCallback supervisorCallback = null,
|
||||
ExceptionCallback undefinedCallback = null)
|
||||
{
|
||||
InterruptCallback = interruptCallback;
|
||||
BreakCallback = breakCallback;
|
||||
StepCallback = stepCallback;
|
||||
SupervisorCallback = supervisorCallback;
|
||||
UndefinedCallback = undefinedCallback;
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Cpu
|
||||
{
|
||||
@@ -46,6 +47,11 @@ namespace Ryujinx.Cpu
|
||||
/// </summary>
|
||||
bool IsAarch32 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Thread UID.
|
||||
/// </summary>
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whenever the CPU is still running code.
|
||||
/// </summary>
|
||||
@@ -108,5 +114,23 @@ namespace Ryujinx.Cpu
|
||||
/// If you only need to pause the thread temporarily, use <see cref="RequestInterrupt"/> instead.
|
||||
/// </remarks>
|
||||
void StopRunning();
|
||||
|
||||
/// <summary>
|
||||
/// Requests the thread to stop running temporarily and call <see cref="ExceptionCallbacks.InterruptCallback"/>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The thread might not pause immediately.
|
||||
/// One must not assume that guest code is no longer being executed by the thread after calling this function.
|
||||
/// After single stepping, the thread should call call <see cref="ExceptionCallbacks.StepCallback"/>.
|
||||
/// </remarks>
|
||||
void RequestDebugStep();
|
||||
|
||||
/// <summary>
|
||||
/// Current Program Counter (for debugging).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// PC register for the debugger. Must not be accessed while the thread isn't stopped for debugging.
|
||||
/// </remarks>
|
||||
ulong DebugPc { get; set; }
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using ExecutionContext = ARMeilleure.State.ExecutionContext;
|
||||
|
||||
namespace Ryujinx.Cpu.Jit
|
||||
{
|
||||
@@ -53,6 +54,13 @@ namespace Ryujinx.Cpu.Jit
|
||||
set => _impl.IsAarch32 = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong ThreadUid
|
||||
{
|
||||
get => _impl.ThreadUid;
|
||||
set => _impl.ThreadUid = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public bool Running => _impl.Running;
|
||||
|
||||
@@ -65,6 +73,7 @@ namespace Ryujinx.Cpu.Jit
|
||||
counter,
|
||||
InterruptHandler,
|
||||
BreakHandler,
|
||||
StepHandler,
|
||||
SupervisorCallHandler,
|
||||
UndefinedHandler);
|
||||
|
||||
@@ -93,6 +102,11 @@ namespace Ryujinx.Cpu.Jit
|
||||
_exceptionCallbacks.BreakCallback?.Invoke(this, address, imm);
|
||||
}
|
||||
|
||||
private void StepHandler(ExecutionContext context)
|
||||
{
|
||||
_exceptionCallbacks.StepCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
private void SupervisorCallHandler(ExecutionContext context, ulong address, int imm)
|
||||
{
|
||||
_exceptionCallbacks.SupervisorCallback?.Invoke(this, address, imm);
|
||||
@@ -109,6 +123,16 @@ namespace Ryujinx.Cpu.Jit
|
||||
_impl.RequestInterrupt();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void RequestDebugStep() => _impl.RequestDebugStep();
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ulong DebugPc
|
||||
{
|
||||
get => _impl.DebugPc;
|
||||
set => _impl.DebugPc = value;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void StopRunning()
|
||||
{
|
||||
|
@@ -1,6 +1,8 @@
|
||||
using ARMeilleure;
|
||||
using ARMeilleure.Memory;
|
||||
using ARMeilleure.State;
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
namespace Ryujinx.Cpu.LightningJit.State
|
||||
{
|
||||
@@ -51,6 +53,8 @@ namespace Ryujinx.Cpu.LightningJit.State
|
||||
}
|
||||
|
||||
public bool IsAarch32 { get; set; }
|
||||
|
||||
public ulong ThreadUid { get; set; }
|
||||
|
||||
internal ExecutionMode ExecutionMode
|
||||
{
|
||||
@@ -77,15 +81,20 @@ namespace Ryujinx.Cpu.LightningJit.State
|
||||
|
||||
private readonly ExceptionCallbackNoArgs _interruptCallback;
|
||||
private readonly ExceptionCallback _breakCallback;
|
||||
private readonly ExceptionCallbackNoArgs _stepCallback;
|
||||
private readonly ExceptionCallback _supervisorCallback;
|
||||
private readonly ExceptionCallback _undefinedCallback;
|
||||
|
||||
internal int ShouldStep;
|
||||
public ulong DebugPc { get; set; }
|
||||
|
||||
public ExecutionContext(IJitMemoryAllocator allocator, ICounter counter, ExceptionCallbacks exceptionCallbacks)
|
||||
{
|
||||
_nativeContext = new NativeContext(allocator);
|
||||
_counter = counter;
|
||||
_interruptCallback = exceptionCallbacks.InterruptCallback;
|
||||
_breakCallback = exceptionCallbacks.BreakCallback;
|
||||
_stepCallback = exceptionCallbacks.StepCallback;
|
||||
_supervisorCallback = exceptionCallbacks.SupervisorCallback;
|
||||
_undefinedCallback = exceptionCallbacks.UndefinedCallback;
|
||||
|
||||
@@ -117,6 +126,17 @@ namespace Ryujinx.Cpu.LightningJit.State
|
||||
_interrupted = true;
|
||||
}
|
||||
|
||||
public void StepHandler()
|
||||
{
|
||||
_stepCallback?.Invoke(this);
|
||||
}
|
||||
|
||||
public void RequestDebugStep()
|
||||
{
|
||||
Interlocked.Exchange(ref ShouldStep, 1);
|
||||
RequestInterrupt();
|
||||
}
|
||||
|
||||
internal void OnBreak(ulong address, int imm)
|
||||
{
|
||||
_breakCallback?.Invoke(this, address, imm);
|
||||
|
@@ -15,6 +15,7 @@ namespace Ryujinx.Cpu
|
||||
/// <inheritdoc/>
|
||||
public ulong Counter => (ulong)(ElapsedSeconds * Frequency);
|
||||
|
||||
|
||||
public long TickScalar { get; set; }
|
||||
|
||||
private static long _acumElapsedTicks;
|
||||
|
@@ -143,7 +143,7 @@ namespace Ryujinx.Graphics.GAL
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is TextureCreateInfo info && Equals(info);
|
||||
return obj is TextureCreateInfo info && this.Equals(info);
|
||||
}
|
||||
|
||||
public static bool operator ==(TextureCreateInfo left, TextureCreateInfo right)
|
||||
|
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.GAL
|
||||
{
|
||||
public enum ViewportSwizzle
|
||||
|
@@ -98,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
/// </summary>
|
||||
unsafe struct ComputeClassState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetObject;
|
||||
public readonly int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public readonly int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
@@ -430,6 +430,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Compute
|
||||
public readonly int StopShaderPerformanceCounterCounterMask => (int)(StopShaderPerformanceCounter & 0xFF);
|
||||
public fixed uint Reserved33E8[6];
|
||||
public Array256<uint> SetMmeShadowScratch;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -179,7 +179,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
/// </summary>
|
||||
unsafe struct DmaClassState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public fixed uint Reserved00[64];
|
||||
public uint Nop;
|
||||
public fixed uint Reserved104[15];
|
||||
@@ -266,6 +266,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
public fixed uint Reserved740[629];
|
||||
public uint PmTriggerEnd;
|
||||
public fixed uint Reserved1118[2490];
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
/// </summary>
|
||||
struct DmaTexture
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public MemoryLayout MemoryLayout;
|
||||
public int Width;
|
||||
public int Height;
|
||||
@@ -15,6 +15,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Dma
|
||||
public int RegionZ;
|
||||
public ushort RegionX;
|
||||
public ushort RegionY;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -25,9 +25,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
||||
|
||||
struct CompressedMethod
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Method;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
public readonly int MethodAddressOld => (int)((Method >> 2) & 0x7FF);
|
||||
public readonly int MethodAddress => (int)(Method & 0xFFF);
|
||||
public readonly int SubdeviceMask => (int)((Method >> 4) & 0xFFF);
|
||||
|
@@ -36,15 +36,15 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
||||
|
||||
struct GPEntry
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Entry0;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
public readonly Entry0Fetch Entry0Fetch => (Entry0Fetch)(Entry0 & 0x1);
|
||||
public readonly int Entry0Get => (int)((Entry0 >> 2) & 0x3FFFFFFF);
|
||||
public readonly int Entry0Operand => (int)(Entry0);
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Entry1;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
public readonly int Entry1GetHi => (int)(Entry1 & 0xFF);
|
||||
public readonly Entry1Priv Entry1Priv => (Entry1Priv)((Entry1 >> 8) & 0x1);
|
||||
public readonly Entry1Level Entry1Level => (Entry1Level)((Entry1 >> 9) & 0x1);
|
||||
|
@@ -151,7 +151,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
||||
/// </summary>
|
||||
struct GPFifoClassState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetObject;
|
||||
public readonly int SetObjectNvclass => (int)(SetObject & 0xFFFF);
|
||||
public readonly int SetObjectEngine => (int)((SetObject >> 16) & 0x1F);
|
||||
@@ -228,6 +228,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.GPFifo
|
||||
public uint LoadMmeStartAddressRamPointer;
|
||||
public uint LoadMmeStartAddressRam;
|
||||
public uint SetMmeShadowRamControl;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -113,7 +113,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
/// </summary>
|
||||
unsafe struct InlineToMemoryClassState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetObject;
|
||||
public readonly int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public readonly int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
@@ -178,6 +178,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.InlineToMemory
|
||||
public uint SetI2mSpareNoop03;
|
||||
public fixed uint Reserved200[3200];
|
||||
public Array256<uint> SetMmeShadowScratch;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -469,11 +469,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.MME
|
||||
for (int i = 0; i < maxDrawCount; i++)
|
||||
{
|
||||
FifoWord count = FetchParam();
|
||||
|
||||
_ = FetchParam(); // Instance count
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
FifoWord instanceCount = FetchParam();
|
||||
FifoWord firstIndex = FetchParam();
|
||||
_ = FetchParam(); // First vertex
|
||||
_ = FetchParam(); // First instance
|
||||
FifoWord firstVertex = FetchParam();
|
||||
FifoWord firstInstance = FetchParam();
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
if (i == 0)
|
||||
{
|
||||
|
@@ -9,7 +9,9 @@ namespace Ryujinx.Graphics.Gpu.Engine
|
||||
[StructLayout(LayoutKind.Sequential, Size = 1024)]
|
||||
struct MmeShadowScratch
|
||||
{
|
||||
#pragma warning disable CS0169 // The private field is never used
|
||||
private uint _e0;
|
||||
#pragma warning restore CS0169
|
||||
public ref uint this[int index] => ref AsSpan()[index];
|
||||
public Span<uint> AsSpan() => MemoryMarshal.CreateSpan(ref _e0, 256);
|
||||
}
|
||||
|
@@ -16,8 +16,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
private int _inlineIndexBufferSize;
|
||||
private int _inlineIndexCount;
|
||||
private uint[] _buffer;
|
||||
|
||||
#pragma warning disable IDE0051 // Remove unused private member
|
||||
private readonly int _bufferOffset;
|
||||
#pragma warning restore IDE0051
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if any index buffer data has been pushed.
|
||||
|
@@ -1,3 +1,5 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
/// <summary>
|
||||
|
@@ -26,8 +26,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct TessMode
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Packed;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the tessellation abstract patch type.
|
||||
@@ -62,7 +63,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct TfBufferState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 Enable;
|
||||
public GpuVa Address;
|
||||
public int Size;
|
||||
@@ -70,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public uint Padding0;
|
||||
public uint Padding1;
|
||||
public uint Padding2;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -78,12 +79,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct TfState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public int BufferIndex;
|
||||
public int VaryingsCount;
|
||||
public int Stride;
|
||||
public uint Padding;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -91,7 +92,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct RtColorState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public GpuVa Address;
|
||||
public int WidthOrStride;
|
||||
public int Height;
|
||||
@@ -107,7 +108,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public int Padding3;
|
||||
public int Padding4;
|
||||
public int Padding5;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,7 +116,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ViewportTransform
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public float ScaleX;
|
||||
public float ScaleY;
|
||||
public float ScaleZ;
|
||||
@@ -124,6 +125,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public float TranslateZ;
|
||||
public uint Swizzle;
|
||||
public uint SubpixelPrecisionBias;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks viewport swizzle of the position X component.
|
||||
@@ -167,14 +169,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ViewportExtents
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public ushort X;
|
||||
public ushort Width;
|
||||
public ushort Y;
|
||||
public ushort Height;
|
||||
public float DepthNear;
|
||||
public float DepthFar;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -182,10 +184,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct VertexBufferDrawState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public int First;
|
||||
public int Count;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -193,12 +195,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ClearColors
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public float Red;
|
||||
public float Green;
|
||||
public float Blue;
|
||||
public float Alpha;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -206,11 +208,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct DepthBiasState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 PointEnable;
|
||||
public Boolean32 LineEnable;
|
||||
public Boolean32 FillEnable;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -229,14 +231,14 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ScissorState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 Enable;
|
||||
public ushort X1;
|
||||
public ushort X2;
|
||||
public ushort Y1;
|
||||
public ushort Y2;
|
||||
public uint Padding;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -244,11 +246,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct StencilBackMasks
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public int FuncRef;
|
||||
public int Mask;
|
||||
public int FuncMask;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -256,12 +258,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct RtDepthStencilState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public GpuVa Address;
|
||||
public ZetaFormat Format;
|
||||
public MemoryLayout MemoryLayout;
|
||||
public int LayerSize;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -269,12 +271,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ScreenScissorState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public ushort X;
|
||||
public ushort Width;
|
||||
public ushort Y;
|
||||
public ushort Height;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -317,8 +319,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct VertexAttribState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Attribute;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the index of the vertex buffer this attribute belongs to.
|
||||
@@ -380,8 +383,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct RtControl
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Packed;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the number of active draw buffers.
|
||||
@@ -408,7 +412,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct Size3D
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public int Width;
|
||||
public int Height;
|
||||
public ushort Depth;
|
||||
@@ -418,6 +422,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
{
|
||||
return (Flags & 1) == 0;
|
||||
}
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -425,7 +430,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct StencilTestState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 Enable;
|
||||
public StencilOp FrontSFail;
|
||||
public StencilOp FrontDpFail;
|
||||
@@ -434,7 +439,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public int FrontFuncRef;
|
||||
public int FrontFuncMask;
|
||||
public int FrontMask;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -452,11 +457,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct RgbHalf
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint R;
|
||||
public uint G;
|
||||
public uint B;
|
||||
public uint Padding;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the red color component as a 16-bit float value.
|
||||
@@ -506,10 +512,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct PoolState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public GpuVa Address;
|
||||
public int MaximumId;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -517,13 +523,13 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct StencilBackTestState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 TwoSided;
|
||||
public StencilOp BackSFail;
|
||||
public StencilOp BackDpFail;
|
||||
public StencilOp BackDpPass;
|
||||
public CompareOp BackFunc;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -531,10 +537,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct PrimitiveRestartState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 Enable;
|
||||
public int Index;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -543,12 +549,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct IndexBufferState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public GpuVa Address;
|
||||
public GpuVa EndAddress;
|
||||
public IndexType Type;
|
||||
public int First;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -556,11 +562,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct FaceState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 CullEnable;
|
||||
public FrontFace FrontFace;
|
||||
public Face CullFace;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -578,10 +584,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct LogicalOpState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 Enable;
|
||||
public LogicalOp LogicalOp;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -639,10 +645,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct VertexBufferState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Control;
|
||||
public GpuVa Address;
|
||||
public int Divisor;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Vertex buffer stride, defined as the number of bytes occupied by each vertex in memory.
|
||||
@@ -668,7 +675,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct BlendStateCommon
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 SeparateAlpha;
|
||||
public BlendOp ColorOp;
|
||||
public BlendFactor ColorSrcFactor;
|
||||
@@ -677,7 +684,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public BlendFactor AlphaSrcFactor;
|
||||
public uint Unknown0x1354;
|
||||
public BlendFactor AlphaDstFactor;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -685,7 +692,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct BlendState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public Boolean32 SeparateAlpha;
|
||||
public BlendOp ColorOp;
|
||||
public BlendFactor ColorSrcFactor;
|
||||
@@ -694,7 +701,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public BlendFactor AlphaSrcFactor;
|
||||
public BlendFactor AlphaDstFactor;
|
||||
public uint Padding;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -702,7 +709,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct ShaderState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Control;
|
||||
public uint Offset;
|
||||
public uint Unknown0x8;
|
||||
@@ -719,6 +726,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public uint Unknown0x34;
|
||||
public uint Unknown0x38;
|
||||
public uint Unknown0x3c;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks shader enable information.
|
||||
@@ -736,16 +744,16 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
struct UniformBufferState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public int Size;
|
||||
public GpuVa Address;
|
||||
public int Offset;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
unsafe struct ThreedClassState : IShadowState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetObject;
|
||||
public readonly int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public readonly int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
@@ -1044,6 +1052,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
public Array4<Array32<uint>> TfVaryingLocations;
|
||||
public fixed uint Reserved2A00[640];
|
||||
public Array256<uint> SetMmeShadowScratch;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -486,10 +486,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
/// </summary>
|
||||
struct RenderSolidPrimPoint
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetX;
|
||||
public uint Y;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -497,7 +497,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
/// </summary>
|
||||
unsafe struct TwodClassState : IShadowState
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint SetObject;
|
||||
public readonly int SetObjectClassId => (int)(SetObject & 0xFFFF);
|
||||
public readonly int SetObjectEngineId => (int)((SetObject >> 16) & 0x1F);
|
||||
@@ -811,6 +811,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
public readonly bool MmeDmaWriteMethodBarrierV => (MmeDmaWriteMethodBarrier & 0x1) != 0;
|
||||
public fixed uint ReservedDF0[2436];
|
||||
public Array256<uint> SetMmeShadowScratch;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
/// </summary>
|
||||
struct TwodTexture
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public ColorFormat Format;
|
||||
public Boolean32 LinearLayout;
|
||||
public MemoryLayout MemoryLayout;
|
||||
@@ -17,6 +17,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Twod
|
||||
public int Width;
|
||||
public int Height;
|
||||
public GpuVa Address;
|
||||
|
||||
#pragma warning restore CS0649
|
||||
}
|
||||
}
|
||||
|
@@ -5,9 +5,10 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
|
||||
/// </summary>
|
||||
struct GpuVa
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint High;
|
||||
public uint Low;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Packs the split address into a 64-bits address value.
|
||||
|
@@ -5,8 +5,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
|
||||
/// </summary>
|
||||
struct MemoryLayout
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Packed;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
public readonly int UnpackGobBlocksInX()
|
||||
{
|
||||
|
@@ -5,11 +5,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Types
|
||||
/// </summary>
|
||||
struct SbDescriptor
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint AddressLow;
|
||||
public uint AddressHigh;
|
||||
public int Size;
|
||||
public int Padding;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
public readonly ulong PackAddress()
|
||||
{
|
||||
|
@@ -98,6 +98,7 @@ namespace Ryujinx.Graphics.Gpu
|
||||
/// </summary>
|
||||
internal DirtyHacks DirtyHacks { get; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Host hardware capabilities.
|
||||
/// </summary>
|
||||
|
@@ -1,5 +1,6 @@
|
||||
using Ryujinx.Graphics.GAL;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Image
|
||||
{
|
||||
@@ -554,6 +555,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{ VertexAttributeFormat.A2B10G10R10Uscaled, Format.R10G10B10A2Uscaled },
|
||||
{ VertexAttributeFormat.A2B10G10R10Sscaled, Format.R10G10B10A2Sscaled },
|
||||
};
|
||||
#pragma warning restore IDE0055
|
||||
|
||||
// Note: Some of those formats have been changed and requires conversion on the shader,
|
||||
// as GPUs don't support them when used as buffer texture format.
|
||||
@@ -638,7 +640,6 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
{ VertexAttributeFormat.A2B10G10R10Sint, (Format.R10G10B10A2Uint, 4) }, // Sint -> Uint
|
||||
{ VertexAttributeFormat.A2B10G10R10Uscaled, (Format.R10G10B10A2Uint, 4) }, // Uscaled -> Uint
|
||||
{ VertexAttributeFormat.A2B10G10R10Sscaled, (Format.R10G10B10A2Sint, 4) } // Sscaled -> Sint
|
||||
#pragma warning restore IDE0055
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
|
@@ -53,6 +53,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
|
||||
private const float Frac8ToF32 = 1.0f / 256.0f;
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Word0;
|
||||
public uint Word1;
|
||||
public uint Word2;
|
||||
@@ -61,6 +62,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
public float BorderColorG;
|
||||
public float BorderColorB;
|
||||
public float BorderColorA;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks the texture wrap mode along the X axis.
|
||||
|
@@ -9,7 +9,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
/// </summary>
|
||||
struct TextureDescriptor : ITextureDescriptor, IEquatable<TextureDescriptor>
|
||||
{
|
||||
|
||||
#pragma warning disable CS0649 // Field is never assigned to
|
||||
public uint Word0;
|
||||
public uint Word1;
|
||||
public uint Word2;
|
||||
@@ -18,6 +18,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
||||
public uint Word5;
|
||||
public uint Word6;
|
||||
public uint Word7;
|
||||
#pragma warning restore CS0649
|
||||
|
||||
/// <summary>
|
||||
/// Unpacks Maxwell texture format integer.
|
||||
|
@@ -15,7 +15,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <summary>
|
||||
/// Buffer, used to store vertex and index data, uniform and storage buffers, and others.
|
||||
/// </summary>
|
||||
class Buffer : IRange, ISyncActionHandler, IDisposable
|
||||
class Buffer : INonOverlappingRange, ISyncActionHandler, IDisposable
|
||||
{
|
||||
private const ulong GranularBufferThreshold = 4096;
|
||||
|
||||
@@ -35,7 +35,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <summary>
|
||||
/// Size of the buffer in bytes.
|
||||
/// </summary>
|
||||
public ulong Size { get; }
|
||||
public ulong Size { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// End address of the buffer in guest memory.
|
||||
@@ -60,13 +60,13 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <remarks>
|
||||
/// This is null until at least one modification occurs.
|
||||
/// </remarks>
|
||||
private BufferModifiedRangeList _modifiedRanges = null;
|
||||
private BufferModifiedRangeList _modifiedRanges;
|
||||
|
||||
/// <summary>
|
||||
/// A structure that is used to flush buffer data back to a host mapped buffer for cached readback.
|
||||
/// Only used if the buffer data is explicitly owned by device local memory.
|
||||
/// </summary>
|
||||
private BufferPreFlush _preFlush = null;
|
||||
private BufferPreFlush _preFlush;
|
||||
|
||||
/// <summary>
|
||||
/// Usage tracking state that determines what type of backing the buffer should use.
|
||||
@@ -110,7 +110,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ulong size,
|
||||
BufferStage stage,
|
||||
bool sparseCompatible,
|
||||
IEnumerable<Buffer> baseBuffers = null)
|
||||
List<Buffer> baseBuffers)
|
||||
{
|
||||
_context = context;
|
||||
_physicalMemory = physicalMemory;
|
||||
@@ -126,21 +126,22 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
_useGranular = size > GranularBufferThreshold;
|
||||
|
||||
IEnumerable<IRegionHandle> baseHandles = null;
|
||||
List<IRegionHandle> baseHandles = null;
|
||||
|
||||
if (baseBuffers != null)
|
||||
if (baseBuffers.Count != 0)
|
||||
{
|
||||
baseHandles = baseBuffers.SelectMany(buffer =>
|
||||
baseHandles = new List<IRegionHandle>();
|
||||
foreach (Buffer buffer in baseBuffers)
|
||||
{
|
||||
if (buffer._useGranular)
|
||||
{
|
||||
return buffer._memoryTrackingGranular.GetHandles();
|
||||
baseHandles.AddRange((buffer._memoryTrackingGranular.GetHandles()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return Enumerable.Repeat(buffer._memoryTracking, 1);
|
||||
baseHandles.Add(buffer._memoryTracking);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (_useGranular)
|
||||
@@ -171,9 +172,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
_memoryTracking.RegisterPreciseAction(PreciseAction);
|
||||
}
|
||||
|
||||
_externalFlushDelegate = new RegionSignal(ExternalFlush);
|
||||
_loadDelegate = new Action<ulong, ulong>(LoadRegion);
|
||||
_modifiedDelegate = new Action<ulong, ulong>(RegionModified);
|
||||
_externalFlushDelegate = ExternalFlush;
|
||||
_loadDelegate = LoadRegion;
|
||||
_modifiedDelegate = RegionModified;
|
||||
|
||||
_virtualDependenciesLock = new ReaderWriterLockSlim();
|
||||
}
|
||||
@@ -247,6 +248,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
return Address < address + size && address < EndAddress;
|
||||
}
|
||||
|
||||
public INonOverlappingRange Split(ulong splitAddress)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if a given range is fully contained in the buffer.
|
||||
/// </summary>
|
||||
@@ -435,7 +441,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="from">The buffer to inherit from</param>
|
||||
public void InheritModifiedRanges(Buffer from)
|
||||
{
|
||||
if (from._modifiedRanges != null && from._modifiedRanges.HasRanges)
|
||||
if (from._modifiedRanges is { HasRanges: true })
|
||||
{
|
||||
if (from._syncActionRegistered && !_syncActionRegistered)
|
||||
{
|
||||
@@ -443,7 +449,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
_syncActionRegistered = true;
|
||||
}
|
||||
|
||||
void registerRangeAction(ulong address, ulong size)
|
||||
void RegisterRangeAction(ulong address, ulong size)
|
||||
{
|
||||
if (_useGranular)
|
||||
{
|
||||
@@ -457,7 +463,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
EnsureRangeList();
|
||||
|
||||
_modifiedRanges.InheritRanges(from._modifiedRanges, registerRangeAction);
|
||||
_modifiedRanges.InheritRanges(from._modifiedRanges, RegisterRangeAction);
|
||||
}
|
||||
|
||||
if (from._dirtyStart != ulong.MaxValue)
|
||||
@@ -499,14 +505,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
// Cut off the start.
|
||||
|
||||
if (end < _dirtyEnd)
|
||||
{
|
||||
_dirtyStart = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
_dirtyStart = ulong.MaxValue;
|
||||
}
|
||||
_dirtyStart = end < _dirtyEnd ? end : ulong.MaxValue;
|
||||
}
|
||||
else if (end >= _dirtyEnd)
|
||||
{
|
||||
|
@@ -56,7 +56,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="parent">Parent buffer</param>
|
||||
/// <param name="stage">Initial buffer stage</param>
|
||||
/// <param name="baseBuffers">Buffers to inherit state from</param>
|
||||
public BufferBackingState(GpuContext context, Buffer parent, BufferStage stage, IEnumerable<Buffer> baseBuffers = null)
|
||||
public BufferBackingState(GpuContext context, Buffer parent, BufferStage stage, List<Buffer> baseBuffers)
|
||||
{
|
||||
_size = (int)parent.Size;
|
||||
_systemMemoryType = context.Capabilities.MemoryType;
|
||||
@@ -72,7 +72,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
BufferStage storageFlags = stage & BufferStage.StorageMask;
|
||||
|
||||
if (parent.Size > DeviceLocalSizeThreshold && baseBuffers == null)
|
||||
if (parent.Size > DeviceLocalSizeThreshold && baseBuffers.Count == 0)
|
||||
{
|
||||
_desiredType = BufferBackingType.DeviceMemory;
|
||||
}
|
||||
@@ -100,7 +100,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// TODO: Might be nice to force atomic access to be device local for any stage.
|
||||
}
|
||||
|
||||
if (baseBuffers != null)
|
||||
if (baseBuffers.Count != 0)
|
||||
{
|
||||
foreach (Buffer buffer in baseBuffers)
|
||||
{
|
||||
|
@@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL;
|
||||
using Ryujinx.Memory.Range;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Ryujinx.Graphics.Gpu.Memory
|
||||
@@ -39,11 +38,9 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// Only modified from the GPU thread. Must lock for add/remove.
|
||||
/// Must lock for any access from other threads.
|
||||
/// </remarks>
|
||||
private readonly RangeList<Buffer> _buffers;
|
||||
private readonly NonOverlappingRangeList<Buffer> _buffers;
|
||||
private readonly MultiRangeList<MultiRangeBuffer> _multiRangeBuffers;
|
||||
|
||||
private Buffer[] _bufferOverlaps;
|
||||
|
||||
private readonly Dictionary<ulong, BufferCacheEntry> _dirtyCache;
|
||||
private readonly Dictionary<ulong, BufferCacheEntry> _modifiedCache;
|
||||
private bool _pruneCaches;
|
||||
@@ -64,8 +61,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
_buffers = [];
|
||||
_multiRangeBuffers = [];
|
||||
|
||||
_bufferOverlaps = new Buffer[OverlapsBufferInitialCapacity];
|
||||
|
||||
_dirtyCache = new Dictionary<ulong, BufferCacheEntry>();
|
||||
|
||||
// There are a lot more entries on the modified cache, so it is separate from the one for ForceDirty.
|
||||
@@ -79,24 +74,23 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="e">Event arguments</param>
|
||||
public void MemoryUnmappedHandler(object sender, UnmapEventArgs e)
|
||||
{
|
||||
Buffer[] overlaps = new Buffer[10];
|
||||
int overlapCount;
|
||||
|
||||
MultiRange range = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size);
|
||||
|
||||
for (int index = 0; index < range.Count; index++)
|
||||
{
|
||||
MemoryRange subRange = range.GetSubRange(index);
|
||||
|
||||
_buffers.Lock.EnterReadLock();
|
||||
(RangeItem<Buffer> first, RangeItem<Buffer> last) = _buffers.FindOverlaps(subRange.Address, subRange.Size);
|
||||
|
||||
lock (_buffers)
|
||||
RangeItem<Buffer> current = first;
|
||||
while (last != null && current != last.Next)
|
||||
{
|
||||
overlapCount = _buffers.FindOverlaps(subRange.Address, subRange.Size, ref overlaps);
|
||||
current.Value.Unmapped(subRange.Address, subRange.Size);
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
for (int i = 0; i < overlapCount; i++)
|
||||
{
|
||||
overlaps[i].Unmapped(subRange.Address, subRange.Size);
|
||||
}
|
||||
_buffers.Lock.ExitReadLock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +131,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <returns>Physical ranges of the buffer, after address translation</returns>
|
||||
public MultiRange TranslateAndCreateMultiBuffers(MemoryManager memoryManager, ulong gpuVa, ulong size, BufferStage stage)
|
||||
{
|
||||
if (gpuVa == 0)
|
||||
if (gpuVa == 0 || size == 0)
|
||||
{
|
||||
return new MultiRange(MemoryManager.PteUnmapped, size);
|
||||
}
|
||||
@@ -336,7 +330,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
ulong alignedEndAddress = (endAddress + alignmentMask) & ~alignmentMask;
|
||||
ulong alignedSize = alignedEndAddress - alignedAddress;
|
||||
|
||||
Buffer buffer = _buffers.FindFirstOverlap(alignedAddress, alignedSize);
|
||||
Buffer buffer = _buffers.FindOverlap(alignedAddress, alignedSize).Value;
|
||||
BufferRange bufferRange = buffer.GetRange(alignedAddress, alignedSize, false);
|
||||
|
||||
alignedSubRanges[i] = new MemoryRange(alignedAddress, alignedSize);
|
||||
@@ -403,7 +397,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (subRange.Address != MemoryManager.PteUnmapped)
|
||||
{
|
||||
Buffer buffer = _buffers.FindFirstOverlap(subRange.Address, subRange.Size);
|
||||
Buffer buffer = _buffers.FindOverlap(subRange.Address, subRange.Size).Value;
|
||||
|
||||
virtualBuffer.AddPhysicalDependency(buffer, subRange.Address, dstOffset, subRange.Size);
|
||||
physicalBuffers.Add(buffer);
|
||||
@@ -495,10 +489,10 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="stage">The type of usage that created the buffer</param>
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage)
|
||||
{
|
||||
Buffer[] overlaps = _bufferOverlaps;
|
||||
int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
(RangeItem<Buffer> first, RangeItem<Buffer> last) = _buffers.FindOverlaps(address, size);
|
||||
|
||||
if (overlapsCount != 0)
|
||||
if (first is not null)
|
||||
{
|
||||
// The buffer already exists. We can just return the existing buffer
|
||||
// if the buffer we need is fully contained inside the overlapping buffer.
|
||||
@@ -507,9 +501,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// old buffer(s) to the new buffer.
|
||||
|
||||
ulong endAddress = address + size;
|
||||
Buffer overlap0 = overlaps[0];
|
||||
|
||||
if (overlap0.Address > address || overlap0.EndAddress < endAddress)
|
||||
if (first.Address > address || first.EndAddress < endAddress)
|
||||
{
|
||||
bool anySparseCompatible = false;
|
||||
|
||||
@@ -522,53 +515,52 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
// sequential memory.
|
||||
// Allowing for 2 pages (rather than just one) is necessary to catch cases where the
|
||||
// range crosses a page, and after alignment, ends having a size of 2 pages.
|
||||
if (overlapsCount == 1 &&
|
||||
address >= overlap0.Address &&
|
||||
endAddress - overlap0.EndAddress <= BufferAlignmentSize * 2)
|
||||
if (first == last &&
|
||||
address >= first.Address &&
|
||||
endAddress - first.EndAddress <= BufferAlignmentSize * 2)
|
||||
{
|
||||
// Try to grow the buffer by 1.5x of its current size.
|
||||
// This improves performance in the cases where the buffer is resized often by small amounts.
|
||||
ulong existingSize = overlap0.Size;
|
||||
ulong existingSize = first.Value.Size;
|
||||
ulong growthSize = (existingSize + Math.Min(existingSize >> 1, MaxDynamicGrowthSize)) & ~BufferAlignmentMask;
|
||||
|
||||
size = Math.Max(size, growthSize);
|
||||
endAddress = address + size;
|
||||
|
||||
overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
(first, last) = _buffers.FindOverlaps(address, size);
|
||||
}
|
||||
|
||||
address = Math.Min(address, first.Address);
|
||||
endAddress = Math.Max(endAddress, last.EndAddress);
|
||||
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
List<Buffer> overlaps = [];
|
||||
|
||||
RangeItem<Buffer> current = first;
|
||||
while (current != last.Next)
|
||||
{
|
||||
Buffer buffer = overlaps[index];
|
||||
|
||||
anySparseCompatible |= buffer.SparseCompatible;
|
||||
|
||||
address = Math.Min(address, buffer.Address);
|
||||
endAddress = Math.Max(endAddress, buffer.EndAddress);
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
_buffers.Remove(buffer);
|
||||
}
|
||||
anySparseCompatible |= current.Value.SparseCompatible;
|
||||
overlaps.Add(current.Value);
|
||||
_buffers.Remove(current.Value);
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlaps, overlapsCount);
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, anySparseCompatible, overlaps);
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false);
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible: false, []);
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
|
||||
ShrinkOverlapsBufferIfNeeded();
|
||||
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -582,72 +574,68 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="alignment">Alignment of the start address of the buffer</param>
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, ulong alignment)
|
||||
{
|
||||
Buffer[] overlaps = _bufferOverlaps;
|
||||
int overlapsCount = _buffers.FindOverlapsNonOverlapping(address, size, ref overlaps);
|
||||
bool sparseAligned = alignment >= SparseBufferAlignmentSize;
|
||||
|
||||
_buffers.Lock.EnterWriteLock();
|
||||
(RangeItem<Buffer> first, RangeItem<Buffer> last) = _buffers.FindOverlaps(address, size);
|
||||
|
||||
if (overlapsCount != 0)
|
||||
if (first is not null)
|
||||
{
|
||||
// If the buffer already exists, make sure if covers the entire range,
|
||||
// and make sure it is properly aligned, otherwise sparse mapping may fail.
|
||||
|
||||
ulong endAddress = address + size;
|
||||
Buffer overlap0 = overlaps[0];
|
||||
|
||||
if (overlap0.Address > address ||
|
||||
overlap0.EndAddress < endAddress ||
|
||||
(overlap0.Address & (alignment - 1)) != 0 ||
|
||||
(!overlap0.SparseCompatible && sparseAligned))
|
||||
if (first.Address > address ||
|
||||
first.EndAddress < endAddress ||
|
||||
(first.Address & (alignment - 1)) != 0 ||
|
||||
(!first.Value.SparseCompatible && sparseAligned))
|
||||
{
|
||||
// We need to make sure the new buffer is properly aligned.
|
||||
// However, after the range is aligned, it is possible that it
|
||||
// overlaps more buffers, so try again after each extension
|
||||
// and ensure we cover all overlaps.
|
||||
|
||||
int oldOverlapsCount;
|
||||
RangeItem<Buffer> oldFirst;
|
||||
endAddress = Math.Max(endAddress, last.EndAddress);
|
||||
|
||||
do
|
||||
{
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
{
|
||||
Buffer buffer = overlaps[index];
|
||||
|
||||
address = Math.Min(address, buffer.Address);
|
||||
endAddress = Math.Max(endAddress, buffer.EndAddress);
|
||||
}
|
||||
address = Math.Min(address, first.Address);
|
||||
|
||||
address &= ~(alignment - 1);
|
||||
|
||||
oldOverlapsCount = overlapsCount;
|
||||
overlapsCount = _buffers.FindOverlapsNonOverlapping(address, endAddress - address, ref overlaps);
|
||||
}
|
||||
while (oldOverlapsCount != overlapsCount);
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
{
|
||||
_buffers.Remove(overlaps[index]);
|
||||
}
|
||||
oldFirst = first;
|
||||
(first, last) = _buffers.FindOverlaps(address, endAddress - address);
|
||||
}
|
||||
while (oldFirst != first);
|
||||
|
||||
ulong newSize = endAddress - address;
|
||||
|
||||
CreateBufferAligned(address, newSize, stage, sparseAligned, overlaps, overlapsCount);
|
||||
|
||||
List<Buffer> overlaps = [];
|
||||
|
||||
RangeItem<Buffer> current = first;
|
||||
while (current != last.Next)
|
||||
{
|
||||
overlaps.Add(current.Value);
|
||||
_buffers.Remove(current.Value);
|
||||
|
||||
current = current.Next;
|
||||
}
|
||||
|
||||
Buffer newBuffer = CreateBufferAligned(address, newSize, stage, sparseAligned, overlaps);
|
||||
|
||||
_buffers.Add(newBuffer);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No overlap, just create a new buffer.
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned);
|
||||
Buffer buffer = new(_context, _physicalMemory, address, size, stage, sparseAligned, []);
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
_buffers.Add(buffer);
|
||||
}
|
||||
|
||||
ShrinkOverlapsBufferIfNeeded();
|
||||
_buffers.Lock.ExitWriteLock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -660,17 +648,11 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
/// <param name="stage">The type of usage that created the buffer</param>
|
||||
/// <param name="sparseCompatible">Indicates if the buffer can be used in a sparse buffer mapping</param>
|
||||
/// <param name="overlaps">Buffers overlapping the range</param>
|
||||
/// <param name="overlapsCount">Total of overlaps</param>
|
||||
private void CreateBufferAligned(ulong address, ulong size, BufferStage stage, bool sparseCompatible, Buffer[] overlaps, int overlapsCount)
|
||||
private Buffer CreateBufferAligned(ulong address, ulong size, BufferStage stage, bool sparseCompatible, List<Buffer> overlaps)
|
||||
{
|
||||
Buffer newBuffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible, overlaps.Take(overlapsCount));
|
||||
Buffer newBuffer = new(_context, _physicalMemory, address, size, stage, sparseCompatible, overlaps);
|
||||
|
||||
lock (_buffers)
|
||||
{
|
||||
_buffers.Add(newBuffer);
|
||||
}
|
||||
|
||||
for (int index = 0; index < overlapsCount; index++)
|
||||
for (int index = 0; index < overlaps.Count; index++)
|
||||
{
|
||||
Buffer buffer = overlaps[index];
|
||||
|
||||
@@ -688,6 +670,8 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
NotifyBuffersModified?.Invoke();
|
||||
|
||||
RecreateMultiRangeBuffers(address, size);
|
||||
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -718,17 +702,6 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resizes the temporary buffer used for range list intersection results, if it has grown too much.
|
||||
/// </summary>
|
||||
private void ShrinkOverlapsBufferIfNeeded()
|
||||
{
|
||||
if (_bufferOverlaps.Length > OverlapsBufferMaxCapacity)
|
||||
{
|
||||
Array.Resize(ref _bufferOverlaps, OverlapsBufferMaxCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Copy a buffer data from a given address to another.
|
||||
/// </summary>
|
||||
@@ -909,7 +882,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
MemoryRange subRange = range.GetSubRange(i);
|
||||
|
||||
Buffer subBuffer = _buffers.FindFirstOverlap(subRange.Address, subRange.Size);
|
||||
Buffer subBuffer = _buffers.FindOverlapFast(subRange.Address, subRange.Size).Value;
|
||||
|
||||
subBuffer.SynchronizeMemory(subRange.Address, subRange.Size);
|
||||
|
||||
@@ -957,7 +930,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
|
||||
if (size != 0)
|
||||
{
|
||||
buffer = _buffers.FindFirstOverlap(address, size);
|
||||
buffer = _buffers.FindOverlapFast(address, size).Value;
|
||||
|
||||
buffer.CopyFromDependantVirtualBuffers();
|
||||
buffer.SynchronizeMemory(address, size);
|
||||
@@ -969,7 +942,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = _buffers.FindFirstOverlap(address, 1);
|
||||
buffer = _buffers.FindOverlapFast(address, 1).Value;
|
||||
}
|
||||
|
||||
return buffer;
|
||||
@@ -1007,7 +980,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
||||
{
|
||||
if (size != 0)
|
||||
{
|
||||
Buffer buffer = _buffers.FindFirstOverlap(address, size);
|
||||
Buffer buffer = _buffers.FindOverlapFast(address, size).Value;
|
||||
|
||||
if (copyBackVirtual)
|
||||
{
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user