mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-09-11 12:25:16 +00:00
Compare commits
136 Commits
Canary-1.2
...
Canary-1.2
Author | SHA1 | Date | |
---|---|---|---|
|
d10a478cce | ||
|
ec1020b165 | ||
|
4082ebad1a | ||
|
da8ea06074 | ||
|
7f9dccb293 | ||
|
8e4a77aba0 | ||
|
8fd8a776c9 | ||
|
eec92c242c | ||
|
42a739d34c | ||
|
f362bef43d | ||
|
f5ce539de9 | ||
|
4f699afe7a | ||
|
6caab1aa37 | ||
|
9baaa2b8f8 | ||
|
7f376b4f45 | ||
|
32cdccde12 | ||
|
cbd851d00e | ||
|
f463ea1c5d | ||
|
1dd69912b1 | ||
|
1fbb0d8e7d | ||
|
9ee3f1ff36 | ||
|
d052d74ac4 | ||
|
df91c4c57a | ||
|
2aaaa7872f | ||
|
b5999583d6 | ||
|
8b3a945b5f | ||
|
09107b67ff | ||
|
12b264af44 | ||
|
0c21b07f19 | ||
|
18625cf775 | ||
|
77a9246825 | ||
|
709eeda94a | ||
|
7d54424048 | ||
|
664c63c6a8 | ||
|
153d1ef06b | ||
|
e1e4e5d2d5 | ||
|
44ee4190e6 | ||
|
9408452f93 | ||
|
38833ff60a | ||
|
1faa72f22f | ||
|
56e45ae648 | ||
|
07074272ca | ||
|
9eb273a0f7 | ||
|
ccddaa77d1 | ||
|
01c2e67334 | ||
|
4c646721d6 | ||
|
d3bc3a1081 | ||
|
c69881a0a2 | ||
|
1bc0159139 | ||
|
0733b7d0a1 | ||
|
9df1366fa1 | ||
|
c73b5bdf46 | ||
|
9754d247b5 | ||
|
267e9f6350 | ||
|
d7b3dd12d1 | ||
|
c9b2a6b1f1 | ||
|
17233d30da | ||
|
2bf48f57d2 | ||
|
412d4065b8 | ||
|
e6644626fc | ||
|
0bacdb8765 | ||
|
0ca4d6e921 | ||
|
f0aa7eedf6 | ||
|
41acc4b1f3 | ||
|
7aede70ba9 | ||
|
a0a4f78cff | ||
|
16a60fdf12 | ||
|
4d7350fc6e | ||
|
b05eab21a2 | ||
|
ff667a5c84 | ||
|
2f540dc88c | ||
|
3cb996bf5c | ||
|
852823104f | ||
|
3094df54dd | ||
|
278fe9d4f0 | ||
|
a560d2efdb | ||
|
a270dc721c | ||
|
23b0b22400 | ||
|
3dfbf55611 | ||
|
cb355f504d | ||
|
b5483d8fe0 | ||
|
8259f790d7 | ||
|
1ea345faa7 | ||
|
5913ceda40 | ||
|
decd37ce6d | ||
|
67ec10feea | ||
|
4c7cb54ec6 | ||
|
f898a5ecf4 | ||
|
2fac0f4db1 | ||
|
0f18df982f | ||
|
d9fe0da345 | ||
|
1f0fa525a3 | ||
|
e15a207656 | ||
|
77ef82d92a | ||
|
ba199f4325 | ||
|
4171913baf | ||
|
5b36a9cf9f | ||
|
a460eda195 | ||
|
c77c1acd08 | ||
|
d68295e57d | ||
|
bb3d95722e | ||
|
2fa3a7bfa1 | ||
|
381921390a | ||
|
221524d879 | ||
|
9cddf3b66b | ||
|
0adaa4cb96 | ||
|
ff6628149d | ||
|
8db5a7e98b | ||
|
8e00cb5232 | ||
|
362f62cd39 | ||
|
2cd54d0da0 | ||
|
b97b8ca8f5 | ||
|
d7d4225e0d | ||
|
a9e0fac9dc | ||
|
1b9656e960 | ||
|
8994e7476c | ||
|
b3944a18b7 | ||
|
18c957f90b | ||
|
1a005f96e7 | ||
|
072cd2824a | ||
|
9da97bc911 | ||
|
39252b7267 | ||
|
ec11bf2af9 | ||
|
8ae72c1a00 | ||
|
06abba25c1 | ||
|
de00a71690 | ||
|
315a1819c0 | ||
|
4ffb8aef12 | ||
|
290a6ad5de | ||
|
eda4f4349b | ||
|
5fbcb1f3a7 | ||
|
d00754477e | ||
|
0bc1eddaeb | ||
|
baad1e313f | ||
|
a1e6d11dcb | ||
|
3d168a8bfa |
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -32,7 +32,7 @@ kernel:
|
|||||||
|
|
||||||
infra:
|
infra:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props']
|
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props', 'src/Ryujinx.BuildValidationTasks/**']
|
||||||
|
|
||||||
documentation:
|
documentation:
|
||||||
- changed-files:
|
- changed-files:
|
||||||
|
23
.github/workflows/build.yml
vendored
23
.github/workflows/build.yml
vendored
@@ -64,14 +64,9 @@ jobs:
|
|||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx --self-contained
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
||||||
|
|
||||||
- name: Publish Ryujinx.Headless.SDL2
|
|
||||||
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ env.RYUJINX_BASE_VERSION }}" -p:DebugType=embedded -p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" -p:ExtraDefineConstants=DISABLE_UPDATER src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
- name: Set executable bit
|
- name: Set executable bit
|
||||||
run: |
|
run: |
|
||||||
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
chmod +x ./publish/Ryujinx ./publish/Ryujinx.sh
|
||||||
chmod +x ./publish_sdl2_headless/Ryujinx.Headless.SDL2 ./publish_sdl2_headless/Ryujinx.sh
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
if: github.event_name == 'pull_request' && matrix.platform.os == 'ubuntu-latest'
|
||||||
|
|
||||||
- name: Build AppImage
|
- name: Build AppImage
|
||||||
@@ -119,13 +114,6 @@ jobs:
|
|||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}-AppImage
|
||||||
path: publish_appimage
|
path: publish_appimage
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.platform.zip_os_name }}
|
|
||||||
path: publish_sdl2_headless
|
|
||||||
if: github.event_name == 'pull_request' && matrix.platform.os != 'macos-13'
|
|
||||||
|
|
||||||
build_macos:
|
build_macos:
|
||||||
name: macOS Universal (${{ matrix.configuration }})
|
name: macOS Universal (${{ matrix.configuration }})
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -171,20 +159,9 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp publish ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ env.RYUJINX_BASE_VERSION }}" "${{ steps.git_short_hash.outputs.result }}" "${{ matrix.configuration }}" "-p:ExtraDefineConstants=DISABLE_UPDATER"
|
|
||||||
|
|
||||||
- name: Upload Ryujinx artifact
|
- name: Upload Ryujinx artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
||||||
path: "publish/*.tar.gz"
|
path: "publish/*.tar.gz"
|
||||||
if: github.event_name == 'pull_request'
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
- name: Upload Ryujinx.Headless.SDL2 artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: nogui-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-macos_universal
|
|
||||||
path: "publish_headless/*.tar.gz"
|
|
||||||
if: github.event_name == 'pull_request'
|
|
||||||
|
58
.github/workflows/canary.yml
vendored
58
.github/workflows/canary.yml
vendored
@@ -21,9 +21,9 @@ env:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.2"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "canary"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
@@ -43,8 +43,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.git.createRef({
|
github.rest.git.createRef({
|
||||||
owner: context.repo.owner,
|
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
||||||
repo: context.repo.repo,
|
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}",
|
||||||
ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}',
|
ref: 'refs/tags/Canary-${{ steps.version_info.outputs.build_version }}',
|
||||||
sha: context.sha
|
sha: context.sha
|
||||||
})
|
})
|
||||||
@@ -54,7 +54,19 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
body: |
|
||||||
|
# Canary builds:
|
||||||
|
|
||||||
|
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with.
|
||||||
|
|
||||||
|
| Platform | Artifact |
|
||||||
|
|--|--|
|
||||||
|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
|
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
|
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
|
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
@@ -104,7 +116,6 @@ jobs:
|
|||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_ava/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless/publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
@@ -113,11 +124,6 @@ jobs:
|
|||||||
rm publish/libarmeilleure-jitsupport.dylib
|
rm publish/libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
7z a ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
|
||||||
7z a ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Packing Linux builds
|
- name: Packing Linux builds
|
||||||
@@ -128,12 +134,6 @@ jobs:
|
|||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
chmod +x publish/Ryujinx.sh publish/Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
tar -czvf ../release_output/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm publish/libarmeilleure-jitsupport.dylib
|
|
||||||
chmod +x publish/Ryujinx.sh publish/Ryujinx.Headless.SDL2
|
|
||||||
tar -czvf ../release_output/nogui-ryujinx-canary-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
#- name: Build AppImage (Linux)
|
#- name: Build AppImage (Linux)
|
||||||
@@ -179,9 +179,21 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
artifacts: "release_output/*.tar.gz,release_output/*.zip"
|
||||||
#artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
|
#artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
body: |
|
||||||
|
# Canary builds:
|
||||||
|
|
||||||
|
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with.
|
||||||
|
|
||||||
|
| Platform | Artifact |
|
||||||
|
|--|--|
|
||||||
|
| Windows 64-bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
|
| Linux 64-bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
|
| Linux ARM 64-bit | [Canary Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
|
| macOS | [Canary macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
@@ -238,17 +250,13 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish_ava ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 1
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
name: "Canary ${{ steps.version_info.outputs.build_version }}"
|
||||||
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
|
artifacts: "publish_ava/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
|
10
.github/workflows/nightly_pr_comment.yml
vendored
10
.github/workflows/nightly_pr_comment.yml
vendored
@@ -38,20 +38,16 @@ jobs:
|
|||||||
return core.error(`No artifacts found`);
|
return core.error(`No artifacts found`);
|
||||||
}
|
}
|
||||||
let body = `Download the artifacts for this pull request:\n`;
|
let body = `Download the artifacts for this pull request:\n`;
|
||||||
let hidden_headless_artifacts = `\n\n <details><summary>GUI-less</summary>\n`;
|
|
||||||
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
let hidden_debug_artifacts = `\n\n <details><summary>Only for Developers</summary>\n`;
|
||||||
for (const art of artifacts) {
|
for (const art of artifacts) {
|
||||||
|
const url = `https://github.com/Ryubing/Ryujinx/actions/runs/${run_id}/artifacts/${art.id}`;
|
||||||
if(art.name.includes('Debug')) {
|
if(art.name.includes('Debug')) {
|
||||||
hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
hidden_debug_artifacts += `\n* [${art.name}](${url})`;
|
||||||
} else if(art.name.includes('nogui-ryujinx')) {
|
|
||||||
hidden_headless_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
|
||||||
} else {
|
} else {
|
||||||
body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
|
body += `\n* [${art.name}](${url})`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hidden_headless_artifacts += `\n</details>`;
|
|
||||||
hidden_debug_artifacts += `\n</details>`;
|
hidden_debug_artifacts += `\n</details>`;
|
||||||
body += hidden_headless_artifacts;
|
|
||||||
body += hidden_debug_artifacts;
|
body += hidden_debug_artifacts;
|
||||||
|
|
||||||
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
|
||||||
|
47
.github/workflows/release.yml
vendored
47
.github/workflows/release.yml
vendored
@@ -21,7 +21,7 @@ env:
|
|||||||
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
DOTNET_CLI_TELEMETRY_OPTOUT: 1
|
||||||
RYUJINX_BASE_VERSION: "1.2"
|
RYUJINX_BASE_VERSION: "1.2"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
RYUJINX_TARGET_RELEASE_CHANNEL_NAME: "release"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
|
RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "Ryubing"
|
||||||
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx"
|
||||||
RELEASE: 1
|
RELEASE: 1
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
script: |
|
script: |
|
||||||
github.rest.git.createRef({
|
github.rest.git.createRef({
|
||||||
owner: context.repo.owner,
|
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}",
|
||||||
repo: context.repo.repo,
|
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}",
|
||||||
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
ref: 'refs/tags/${{ steps.version_info.outputs.build_version }}',
|
||||||
sha: context.sha
|
sha: context.sha
|
||||||
})
|
})
|
||||||
@@ -53,7 +53,16 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
body: |
|
||||||
|
# Stable builds:
|
||||||
|
| Platform | Artifact |
|
||||||
|
|--|--|
|
||||||
|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
|
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
|
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
|
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
|
||||||
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
|
||||||
@@ -103,7 +112,6 @@ jobs:
|
|||||||
- name: Publish
|
- name: Publish
|
||||||
run: |
|
run: |
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx --self-contained
|
||||||
dotnet publish -c Release -r "${{ matrix.platform.name }}" -o ./publish_sdl2_headless -p:Version="${{ steps.version_info.outputs.build_version }}" -p:SourceRevisionId="${{ steps.version_info.outputs.git_short_hash }}" -p:DebugType=embedded src/Ryujinx.Headless.SDL2 --self-contained
|
|
||||||
|
|
||||||
- name: Packing Windows builds
|
- name: Packing Windows builds
|
||||||
if: matrix.platform.os == 'windows-latest'
|
if: matrix.platform.os == 'windows-latest'
|
||||||
@@ -112,11 +120,6 @@ jobs:
|
|||||||
rm libarmeilleure-jitsupport.dylib
|
rm libarmeilleure-jitsupport.dylib
|
||||||
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
7z a ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
rm libarmeilleure-jitsupport.dylib
|
|
||||||
7z a ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.zip ../publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Build AppImage (Linux)
|
- name: Build AppImage (Linux)
|
||||||
@@ -163,11 +166,6 @@ jobs:
|
|||||||
chmod +x Ryujinx.sh Ryujinx
|
chmod +x Ryujinx.sh Ryujinx
|
||||||
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
tar -czvf ../release_output/ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
||||||
popd
|
popd
|
||||||
|
|
||||||
pushd publish_sdl2_headless
|
|
||||||
chmod +x Ryujinx.sh Ryujinx.Headless.SDL2
|
|
||||||
tar -czvf ../release_output/nogui-ryujinx-${{ steps.version_info.outputs.build_version }}-${{ matrix.platform.zip_os_name }}.tar.gz ../publish
|
|
||||||
popd
|
|
||||||
shell: bash
|
shell: bash
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
@@ -176,7 +174,16 @@ jobs:
|
|||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
body: |
|
||||||
|
# Stable builds:
|
||||||
|
| Platform | Artifact |
|
||||||
|
|--|--|
|
||||||
|
| Windows 64-bit | [Stable Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
|
||||||
|
| Linux 64-bit | [Stable Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
|
||||||
|
| Linux ARM 64-bit | [Stable Linux ARM Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
|
||||||
|
| macOS | [Stable macOS Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
|
||||||
|
|
||||||
|
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
@@ -233,17 +240,13 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
./distribution/macos/create_macos_build_ava.sh . publish_tmp_ava publish ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
||||||
|
|
||||||
- name: Publish macOS Ryujinx.Headless.SDL2
|
|
||||||
run: |
|
|
||||||
./distribution/macos/create_macos_build_headless.sh . publish_tmp_headless publish_headless ./distribution/macos/entitlements.xml "${{ steps.version_info.outputs.build_version }}" "${{ steps.version_info.outputs.git_short_hash }}" Release 0
|
|
||||||
|
|
||||||
- name: Pushing new release
|
- name: Pushing new release
|
||||||
uses: ncipollo/release-action@v1
|
uses: ncipollo/release-action@v1
|
||||||
with:
|
with:
|
||||||
name: ${{ steps.version_info.outputs.build_version }}
|
name: ${{ steps.version_info.outputs.build_version }}
|
||||||
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
|
artifacts: "publish/*.tar.gz"
|
||||||
tag: ${{ steps.version_info.outputs.build_version }}
|
tag: ${{ steps.version_info.outputs.build_version }}
|
||||||
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
|
body: ""
|
||||||
omitBodyDuringUpdate: true
|
omitBodyDuringUpdate: true
|
||||||
allowUpdates: true
|
allowUpdates: true
|
||||||
replacesArtifacts: true
|
replacesArtifacts: true
|
||||||
|
@@ -5,7 +5,7 @@ If you wish to build the emulator yourself, follow these steps:
|
|||||||
|
|
||||||
### Step 1
|
### Step 1
|
||||||
|
|
||||||
Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0).
|
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0).
|
||||||
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
|
||||||
|
|
||||||
### Step 2
|
### Step 2
|
||||||
|
6
Directory.Build.props
Normal file
6
Directory.Build.props
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
@@ -10,6 +10,9 @@
|
|||||||
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.10" />
|
<PackageVersion Include="Avalonia.Markup.Xaml.Loader" Version="11.0.10" />
|
||||||
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.18" />
|
<PackageVersion Include="Avalonia.Svg" Version="11.0.0.18" />
|
||||||
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.18" />
|
<PackageVersion Include="Avalonia.Svg.Skia" Version="11.0.0.18" />
|
||||||
|
<PackageVersion Include="Microsoft.Build.Framework" Version="17.11.4" />
|
||||||
|
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.12.6" />
|
||||||
|
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.4.0" />
|
<PackageVersion Include="Projektanker.Icons.Avalonia" Version="9.4.0" />
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.FontAwesome" Version="9.4.0"/>
|
||||||
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
<PackageVersion Include="Projektanker.Icons.Avalonia.MaterialDesign" Version="9.4.0"/>
|
||||||
@@ -41,6 +44,7 @@
|
|||||||
<PackageVersion Include="Gommon" Version="2.6.8" />
|
<PackageVersion Include="Gommon" Version="2.6.8" />
|
||||||
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
<PackageVersion Include="securifybv.ShellLink" Version="0.1.0" />
|
||||||
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
<PackageVersion Include="shaderc.net" Version="0.1.0" />
|
||||||
|
<PackageVersion Include="SharpMetal" Version="1.0.0-preview21" />
|
||||||
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
<PackageVersion Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan" Version="2.21.0" />
|
||||||
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
<PackageVersion Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.21.0" />
|
||||||
@@ -48,8 +52,8 @@
|
|||||||
<PackageVersion Include="SkiaSharp" Version="2.88.7" />
|
<PackageVersion Include="SkiaSharp" Version="2.88.7" />
|
||||||
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
|
||||||
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
<PackageVersion Include="SPB" Version="0.0.4-build32" />
|
||||||
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
|
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
|
||||||
<PackageVersion Include="System.Management" Version="8.0.0" />
|
<PackageVersion Include="System.Management" Version="9.0.0" />
|
||||||
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
47
README.md
47
README.md
@@ -1,35 +1,26 @@
|
|||||||
<h1 align="center">
|
<table align="center">
|
||||||
|
<tr>
|
||||||
|
<td align="center" width="25%">
|
||||||
|
<img src="https://raw.githubusercontent.com/GreemDev/ryuassets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
|
||||||
|
</td>
|
||||||
|
<td align="center" width="75%">
|
||||||
|
|
||||||
|
# Ryujinx
|
||||||
|
|
||||||
|
[](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml)
|
||||||
|
[](https://github.com/GreemDev/Ryujinx/releases/latest)
|
||||||
<br>
|
<br>
|
||||||
<img src="https://raw.githubusercontent.com/GreemDev/Ryujinx/master/distribution/misc/Logo.svg" alt="Ryujinx" width="150"></a>
|
[](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml)
|
||||||
<br>
|
[](https://github.com/GreemDev/Ryujinx-Canary/releases/latest)
|
||||||
<b>Ryujinx</b>
|
</td>
|
||||||
<br>
|
</tr>
|
||||||
<sub><sup><b>(REE-YOU-JINX)</b></sup></sub>
|
</table>
|
||||||
<br>
|
|
||||||
<a href="https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml">
|
|
||||||
<img src="https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml/badge.svg"
|
|
||||||
alt="">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/GreemDev/Ryujinx/releases/latest">
|
|
||||||
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx"
|
|
||||||
alt="Latest Release">
|
|
||||||
</a>
|
|
||||||
<br>
|
|
||||||
<a href="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml">
|
|
||||||
<img src="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg"
|
|
||||||
alt="">
|
|
||||||
</a>
|
|
||||||
<a href="https://github.com/GreemDev/Ryujinx-Canary/releases/latest">
|
|
||||||
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary"
|
|
||||||
alt="Latest Canary Release">
|
|
||||||
</a>
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
|
||||||
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
|
||||||
It was written from scratch and development on the project began in September 2017.
|
It was written from scratch and development on the project began in September 2017.
|
||||||
Ryujinx is available on Github under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
|
Ryujinx is available on GitHub under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
|
||||||
<br />
|
<br />
|
||||||
</p>
|
</p>
|
||||||
<p align="center">
|
<p align="center">
|
||||||
@@ -63,7 +54,7 @@ failing to meet this requirement may result in a poor gameplay experience or une
|
|||||||
|
|
||||||
## Latest build
|
## Latest build
|
||||||
|
|
||||||
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love.
|
Stable builds are made every so often onto a separate "release" branch that then gets put into the releases you know and love.
|
||||||
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
These stable builds exist so that the end user can get a more **enjoyable and stable experience**.
|
||||||
|
|
||||||
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
You can find the latest stable release [here](https://github.com/GreemDev/Ryujinx/releases/latest).
|
||||||
@@ -91,7 +82,7 @@ If you are planning to contribute or just want to learn more about this project
|
|||||||
It translates the ARM code to a custom IR, performs a few optimizations, and turns that into x86 code.
|
It translates the ARM code to a custom IR, performs a few optimizations, and turns that into x86 code.
|
||||||
There are three memory manager options available depending on the user's preference, leveraging both software-based (slower) and host-mapped modes (much faster).
|
There are three memory manager options available depending on the user's preference, leveraging both software-based (slower) and host-mapped modes (much faster).
|
||||||
The fastest option (host, unchecked) is set by default.
|
The fastest option (host, unchecked) is set by default.
|
||||||
Ryujinx also features an optional Profiled Persistent Translation Cache, which essentially caches translated functions so that they do not need to be translated every time the game loads.
|
Ryujinx also features an optional Profiled Persistent Translation Cache, which essentially caches translated functions so that they do not need to be translated every time the game loads.
|
||||||
The net result is a significant reduction in load times (the amount of time between launching a game and arriving at the title screen) for nearly every game.
|
The net result is a significant reduction in load times (the amount of time between launching a game and arriving at the title screen) for nearly every game.
|
||||||
NOTE: This feature is enabled by default in the Options menu > System tab.
|
NOTE: This feature is enabled by default in the Options menu > System tab.
|
||||||
You must launch the game at least twice to the title screen or beyond before performance improvements are unlocked on the third launch!
|
You must launch the game at least twice to the title screen or beyond before performance improvements are unlocked on the third launch!
|
||||||
|
38
Ryujinx.sln
38
Ryujinx.sln
@@ -57,14 +57,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.SDL2.Common", "src\
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Audio.Backends.SDL2", "src\Ryujinx.Audio.Backends.SDL2\Ryujinx.Audio.Backends.SDL2.csproj", "{D99A395A-8569-4DB0-B336-900647890052}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Headless.SDL2", "src\Ryujinx.Headless.SDL2\Ryujinx.Headless.SDL2.csproj", "{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Nvdec.FFmpeg", "src\Ryujinx.Graphics.Nvdec.FFmpeg\Ryujinx.Graphics.Nvdec.FFmpeg.csproj", "{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx", "src\Ryujinx\Ryujinx.csproj", "{7C1B2721-13DA-4B62-B046-C626605ECCE6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.UI.Common", "src\Ryujinx.UI.Common\Ryujinx.UI.Common.csproj", "{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Generators", "src\Ryujinx.Horizon.Generators\Ryujinx.Horizon.Generators.csproj", "{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Graphics.Vulkan", "src\Ryujinx.Graphics.Vulkan\Ryujinx.Graphics.Vulkan.csproj", "{D4D09B08-D580-4D69-B886-C35D2853F6C8}"
|
||||||
@@ -81,13 +77,22 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.Horizon.Kernel.Gene
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ryujinx.HLE.Generators", "src\Ryujinx.HLE.Generators\Ryujinx.HLE.Generators.csproj", "{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal", "src\Ryujinx.Graphics.Metal\Ryujinx.Graphics.Metal.csproj", "{C08931FA-1191-417A-864F-3882D93E683B}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
{A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E} = {A602AE97-91A5-4608-8DF1-EBF4ED7A0B9E}
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.BuildValidationTasks", "src\Ryujinx.BuildValidationTasks\Ryujinx.BuildValidationTasks.csproj", "{4A89A234-4F19-497D-A576-DDE8CDFC5B22}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ryujinx.Graphics.Metal.SharpMetalExtensions", "src/Ryujinx.Graphics.Metal.SharpMetalExtensions\Ryujinx.Graphics.Metal.SharpMetalExtensions.csproj", "{81EA598C-DBA1-40B0-8DA4-4796B78F2037}"
|
||||||
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{36F870C1-3E5F-485F-B426-F0645AF78751}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
.editorconfig = .editorconfig
|
.editorconfig = .editorconfig
|
||||||
|
.github\workflows\build.yml = .github\workflows\build.yml
|
||||||
|
.github\workflows\canary.yml = .github\workflows\canary.yml
|
||||||
Directory.Packages.props = Directory.Packages.props
|
Directory.Packages.props = Directory.Packages.props
|
||||||
.github/workflows/release.yml = .github/workflows/release.yml
|
.github\workflows\release.yml = .github\workflows\release.yml
|
||||||
.github/workflows/canary.yml = .github/workflows/canary.yml
|
|
||||||
.github/workflows/build.yml = .github/workflows/build.yml
|
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
@@ -204,10 +209,6 @@ Global
|
|||||||
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D99A395A-8569-4DB0-B336-900647890052}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{390DC343-5CB4-4C79-A5DD-E3ED235E4C49}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BEE1C184-C9A4-410B-8DFC-FB74D5C93AEB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -216,10 +217,6 @@ Global
|
|||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
{7C1B2721-13DA-4B62-B046-C626605ECCE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{BA161CA0-CD65-4E6E-B644-51C8D1E542DC}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6AE2A5E8-4C5A-48B9-997B-E1455C0355C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
@@ -252,6 +249,17 @@ Global
|
|||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
{B575BCDE-2FD8-4A5D-8756-31CDD7FE81F0}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
@@ -13,7 +13,7 @@ mkdir -p AppDir/usr/bin
|
|||||||
|
|
||||||
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
cp distribution/linux/Ryujinx.desktop AppDir/Ryujinx.desktop
|
||||||
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
cp distribution/linux/appimage/AppRun AppDir/AppRun
|
||||||
cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
|
cp distribution/misc/Logo.svg AppDir/Ryujinx.svg
|
||||||
|
|
||||||
|
|
||||||
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
cp -r "$BUILDDIR"/* AppDir/usr/bin/
|
||||||
|
Binary file not shown.
@@ -17,7 +17,7 @@ error_handler() {
|
|||||||
set the button_pressed to the button returned of the result
|
set the button_pressed to the button returned of the result
|
||||||
|
|
||||||
if the button_pressed is \"Open Download Page\" then
|
if the button_pressed is \"Open Download Page\" then
|
||||||
open location \"https://ryujinx.org/download\"
|
open location \"https://ryujinx.app/download\"
|
||||||
end if
|
end if
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -54,4 +54,4 @@ if [ "$#" -le 3 ]; then
|
|||||||
open -a "$INSTALL_DIRECTORY"
|
open -a "$INSTALL_DIRECTORY"
|
||||||
else
|
else
|
||||||
open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
|
open -a "$INSTALL_DIRECTORY" --args "${APP_ARGUMENTS[@]}"
|
||||||
fi
|
fi
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.2 MiB |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"sdk": {
|
"sdk": {
|
||||||
"version": "8.0.100",
|
"version": "9.0.100",
|
||||||
"rollForward": "latestFeature"
|
"rollForward": "latestFeature"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using ARMeilleure.Common;
|
using ARMeilleure.Common;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace ARMeilleure.Decoders
|
namespace ARMeilleure.Decoders
|
||||||
{
|
{
|
||||||
@@ -149,7 +150,7 @@ namespace ARMeilleure.Decoders
|
|||||||
return (((long)opCode << 45) >> 48) & ~3;
|
return (((long)opCode << 45) >> 48) & ~3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool VectorArgumentsInvalid(bool q, params int[] args)
|
public static bool VectorArgumentsInvalid(bool q, params ReadOnlySpan<int> args)
|
||||||
{
|
{
|
||||||
if (q)
|
if (q)
|
||||||
{
|
{
|
||||||
|
@@ -264,7 +264,7 @@ namespace ARMeilleure.Instructions
|
|||||||
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params V128[] tb)
|
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params ReadOnlySpan<V128> tb)
|
||||||
{
|
{
|
||||||
byte[] res = new byte[16];
|
byte[] res = new byte[16];
|
||||||
|
|
||||||
|
@@ -337,7 +337,7 @@ namespace ARMeilleure.IntermediateRepresentation
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Operation Operation(Intrinsic intrin, Operand dest, params Operand[] srcs)
|
public static Operation Operation(Intrinsic intrin, Operand dest, params ReadOnlySpan<Operand> srcs)
|
||||||
{
|
{
|
||||||
Operation result = Make(Instruction.Extended, 0, srcs.Length);
|
Operation result = Make(Instruction.Extended, 0, srcs.Length);
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace ARMeilleure.Translation.Cache
|
namespace ARMeilleure.Translation.Cache
|
||||||
{
|
{
|
||||||
@@ -26,7 +27,7 @@ namespace ARMeilleure.Translation.Cache
|
|||||||
|
|
||||||
private static readonly List<CacheEntry> _cacheEntries = new();
|
private static readonly List<CacheEntry> _cacheEntries = new();
|
||||||
|
|
||||||
private static readonly object _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
|
@@ -559,27 +559,27 @@ namespace ARMeilleure.Translation
|
|||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Operand AddIntrinsic(Intrinsic intrin, params Operand[] args)
|
public Operand AddIntrinsic(Intrinsic intrin, params ReadOnlySpan<Operand> args)
|
||||||
{
|
{
|
||||||
return Add(intrin, Local(OperandType.V128), args);
|
return Add(intrin, Local(OperandType.V128), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Operand AddIntrinsicInt(Intrinsic intrin, params Operand[] args)
|
public Operand AddIntrinsicInt(Intrinsic intrin, params ReadOnlySpan<Operand> args)
|
||||||
{
|
{
|
||||||
return Add(intrin, Local(OperandType.I32), args);
|
return Add(intrin, Local(OperandType.I32), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Operand AddIntrinsicLong(Intrinsic intrin, params Operand[] args)
|
public Operand AddIntrinsicLong(Intrinsic intrin, params ReadOnlySpan<Operand> args)
|
||||||
{
|
{
|
||||||
return Add(intrin, Local(OperandType.I64), args);
|
return Add(intrin, Local(OperandType.I64), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddIntrinsicNoRet(Intrinsic intrin, params Operand[] args)
|
public void AddIntrinsicNoRet(Intrinsic intrin, params ReadOnlySpan<Operand> args)
|
||||||
{
|
{
|
||||||
Add(intrin, default, args);
|
Add(intrin, default, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Operand Add(Intrinsic intrin, Operand dest, params Operand[] sources)
|
private Operand Add(Intrinsic intrin, Operand dest, params ReadOnlySpan<Operand> sources)
|
||||||
{
|
{
|
||||||
NewNextBlockIfNeeded();
|
NewNextBlockIfNeeded();
|
||||||
|
|
||||||
|
@@ -59,7 +59,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
private readonly ManualResetEvent _waitEvent;
|
private readonly ManualResetEvent _waitEvent;
|
||||||
|
|
||||||
private readonly object _lock;
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
@@ -89,8 +89,6 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
_waitEvent = new ManualResetEvent(true);
|
_waitEvent = new ManualResetEvent(true);
|
||||||
|
|
||||||
_lock = new object();
|
|
||||||
|
|
||||||
_disposed = false;
|
_disposed = false;
|
||||||
|
|
||||||
TitleIdText = TitleIdTextDefault;
|
TitleIdText = TitleIdTextDefault;
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using ARMeilleure.State;
|
using ARMeilleure.State;
|
||||||
|
using Humanizer;
|
||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
@@ -41,7 +42,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
|
|
||||||
private readonly ManualResetEvent _waitEvent;
|
private readonly ManualResetEvent _waitEvent;
|
||||||
|
|
||||||
private readonly object _lock;
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
private bool _disposed;
|
private bool _disposed;
|
||||||
|
|
||||||
@@ -58,15 +59,13 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_ptc = ptc;
|
_ptc = ptc;
|
||||||
|
|
||||||
_timer = new Timer(SaveInterval * 1000d);
|
_timer = new Timer(SaveInterval.Seconds());
|
||||||
_timer.Elapsed += PreSave;
|
_timer.Elapsed += TimerElapsed;
|
||||||
|
|
||||||
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
_outerHeaderMagic = BinaryPrimitives.ReadUInt64LittleEndian(EncodingCache.UTF8NoBOM.GetBytes(OuterHeaderMagicString).AsSpan());
|
||||||
|
|
||||||
_waitEvent = new ManualResetEvent(true);
|
_waitEvent = new ManualResetEvent(true);
|
||||||
|
|
||||||
_lock = new object();
|
|
||||||
|
|
||||||
_disposed = false;
|
_disposed = false;
|
||||||
|
|
||||||
ProfiledFuncs = new Dictionary<ulong, FuncProfile>();
|
ProfiledFuncs = new Dictionary<ulong, FuncProfile>();
|
||||||
@@ -74,6 +73,9 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
Enabled = false;
|
Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TimerElapsed(object _, ElapsedEventArgs __)
|
||||||
|
=> new Thread(PreSave) { Name = "Ptc.DiskWriter" }.Start();
|
||||||
|
|
||||||
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
public void AddEntry(ulong address, ExecutionMode mode, bool highCq)
|
||||||
{
|
{
|
||||||
if (IsAddressInStaticCodeRange(address))
|
if (IsAddressInStaticCodeRange(address))
|
||||||
@@ -264,7 +266,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
compressedStream.SetLength(0L);
|
compressedStream.SetLength(0L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PreSave(object source, ElapsedEventArgs e)
|
private void PreSave()
|
||||||
{
|
{
|
||||||
_waitEvent.Reset();
|
_waitEvent.Reset();
|
||||||
|
|
||||||
@@ -430,7 +432,7 @@ namespace ARMeilleure.Translation.PTC
|
|||||||
{
|
{
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
|
|
||||||
_timer.Elapsed -= PreSave;
|
_timer.Elapsed -= TimerElapsed;
|
||||||
_timer.Dispose();
|
_timer.Dispose();
|
||||||
|
|
||||||
Wait();
|
Wait();
|
||||||
|
@@ -5,6 +5,7 @@ using Ryujinx.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.OpenAL
|
namespace Ryujinx.Audio.Backends.OpenAL
|
||||||
{
|
{
|
||||||
@@ -18,7 +19,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
|
|||||||
private ulong _playedSampleCount;
|
private ulong _playedSampleCount;
|
||||||
private float _volume;
|
private float _volume;
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
|
||||||
{
|
{
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
|
@@ -11,7 +11,7 @@ namespace Ryujinx.Audio
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used to control the waiters registration.
|
/// Lock used to control the waiters registration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Events signaled when the driver played audio buffers.
|
/// Events signaled when the driver played audio buffers.
|
||||||
|
@@ -2,6 +2,7 @@ using Ryujinx.Common;
|
|||||||
using Ryujinx.Common.Memory;
|
using Ryujinx.Common.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Backends.Common
|
namespace Ryujinx.Audio.Backends.Common
|
||||||
{
|
{
|
||||||
@@ -12,7 +13,7 @@ namespace Ryujinx.Audio.Backends.Common
|
|||||||
{
|
{
|
||||||
private const int RingBufferAlignment = 2048;
|
private const int RingBufferAlignment = 2048;
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
private MemoryOwner<byte> _bufferOwner;
|
private MemoryOwner<byte> _bufferOwner;
|
||||||
private Memory<byte> _buffer;
|
private Memory<byte> _buffer;
|
||||||
|
@@ -9,20 +9,12 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
{
|
{
|
||||||
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
|
||||||
{
|
{
|
||||||
private readonly ManualResetEvent _updateRequiredEvent;
|
private readonly ManualResetEvent _updateRequiredEvent = new(false);
|
||||||
private readonly ManualResetEvent _pauseEvent;
|
private readonly ManualResetEvent _pauseEvent = new(true);
|
||||||
|
|
||||||
public static bool IsSupported => true;
|
public static bool IsSupported => true;
|
||||||
|
|
||||||
public float Volume { get; set; }
|
public float Volume { get; set; } = 1f;
|
||||||
|
|
||||||
public DummyHardwareDeviceDriver()
|
|
||||||
{
|
|
||||||
_updateRequiredEvent = new ManualResetEvent(false);
|
|
||||||
_pauseEvent = new ManualResetEvent(true);
|
|
||||||
|
|
||||||
Volume = 1f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
public IHardwareDeviceSession OpenDeviceSession(Direction direction, IVirtualMemoryManager memoryManager, SampleFormat sampleFormat, uint sampleRate, uint channelCount)
|
||||||
{
|
{
|
||||||
@@ -60,7 +52,7 @@ namespace Ryujinx.Audio.Backends.Dummy
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing)
|
private void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
|
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AudioInputManager : IDisposable
|
public class AudioInputManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _sessionLock = new();
|
private readonly Lock _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The lock of the parent.
|
/// The lock of the parent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _parentLock;
|
private readonly Lock _parentLock;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The dispose state.
|
/// The dispose state.
|
||||||
@@ -62,7 +62,7 @@ namespace Ryujinx.Audio.Input
|
|||||||
/// <param name="parentLock">The lock of the manager</param>
|
/// <param name="parentLock">The lock of the manager</param>
|
||||||
/// <param name="deviceSession">The hardware device session</param>
|
/// <param name="deviceSession">The hardware device session</param>
|
||||||
/// <param name="bufferEvent">The buffer release event of the audio input</param>
|
/// <param name="bufferEvent">The buffer release event of the audio input</param>
|
||||||
public AudioInputSystem(AudioInputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
|
public AudioInputSystem(AudioInputManager manager, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
_parentLock = parentLock;
|
_parentLock = parentLock;
|
||||||
|
@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class AudioOutputManager : IDisposable
|
public class AudioOutputManager : IDisposable
|
||||||
{
|
{
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _sessionLock = new();
|
private readonly Lock _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// THe lock of the parent.
|
/// THe lock of the parent.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _parentLock;
|
private readonly Lock _parentLock;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The dispose state.
|
/// The dispose state.
|
||||||
@@ -62,7 +62,7 @@ namespace Ryujinx.Audio.Output
|
|||||||
/// <param name="parentLock">The lock of the manager</param>
|
/// <param name="parentLock">The lock of the manager</param>
|
||||||
/// <param name="deviceSession">The hardware device session</param>
|
/// <param name="deviceSession">The hardware device session</param>
|
||||||
/// <param name="bufferEvent">The buffer release event of the audio output</param>
|
/// <param name="bufferEvent">The buffer release event of the audio output</param>
|
||||||
public AudioOutputSystem(AudioOutputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
|
public AudioOutputSystem(AudioOutputManager manager, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
|
||||||
{
|
{
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
_parentLock = parentLock;
|
_parentLock = parentLock;
|
||||||
|
@@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
{
|
{
|
||||||
public class AudioRenderSystem : IDisposable
|
public class AudioRenderSystem : IDisposable
|
||||||
{
|
{
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
private AudioRendererRenderingDevice _renderingDevice;
|
private AudioRendererRenderingDevice _renderingDevice;
|
||||||
private AudioRendererExecutionMode _executionMode;
|
private AudioRendererExecutionMode _executionMode;
|
||||||
|
@@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used for session allocation.
|
/// Lock used for session allocation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _sessionLock = new();
|
private readonly Lock _sessionLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
/// Lock used to control the <see cref="AudioProcessor"/> running state.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _audioProcessorLock = new();
|
private readonly Lock _audioProcessorLock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The session ids allocation table.
|
/// The session ids allocation table.
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Global lock of the object.
|
/// Global lock of the object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The upsamplers instances.
|
/// The upsamplers instances.
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
73
src/Ryujinx.BuildValidationTasks/LocaleValidationTask.cs
Normal file
73
src/Ryujinx.BuildValidationTasks/LocaleValidationTask.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
using System;
|
||||||
|
using Microsoft.Build.Utilities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.IO;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Microsoft.Build.Framework;
|
||||||
|
|
||||||
|
namespace Ryujinx.BuildValidationTasks
|
||||||
|
{
|
||||||
|
public class LocaleValidationTask : Task
|
||||||
|
{
|
||||||
|
public override bool Execute()
|
||||||
|
{
|
||||||
|
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
|
||||||
|
|
||||||
|
if (path.Split(["src"], StringSplitOptions.None).Length == 1)
|
||||||
|
{
|
||||||
|
//i assume that we are in a build directory in the solution dir
|
||||||
|
path = new FileInfo(path).Directory!.Parent!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = path.Split(["src"], StringSplitOptions.None)[0];
|
||||||
|
path = new FileInfo(path).Directory!.GetDirectories("src")[0].GetDirectories("Ryujinx")[0].GetDirectories("Assets")[0].GetFiles("locales.json")[0].FullName;
|
||||||
|
}
|
||||||
|
|
||||||
|
string data;
|
||||||
|
|
||||||
|
using (StreamReader sr = new(path))
|
||||||
|
{
|
||||||
|
data = sr.ReadToEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
LocalesJson json = JsonConvert.DeserializeObject<LocalesJson>(data);
|
||||||
|
|
||||||
|
for (int i = 0; i < json.Locales.Count; i++)
|
||||||
|
{
|
||||||
|
LocalesEntry locale = json.Locales[i];
|
||||||
|
|
||||||
|
foreach (string langCode in json.Languages.Where(it => !locale.Translations.ContainsKey(it)))
|
||||||
|
{
|
||||||
|
locale.Translations.Add(langCode, string.Empty);
|
||||||
|
Log.LogMessage(MessageImportance.High, $"Added '{langCode}' to Locale '{locale.ID}'");
|
||||||
|
}
|
||||||
|
|
||||||
|
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
|
||||||
|
json.Locales[i] = locale;
|
||||||
|
}
|
||||||
|
|
||||||
|
string jsonString = JsonConvert.SerializeObject(json, Formatting.Indented);
|
||||||
|
|
||||||
|
using (StreamWriter sw = new(path))
|
||||||
|
{
|
||||||
|
sw.Write(jsonString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesJson
|
||||||
|
{
|
||||||
|
public List<string> Languages { get; set; }
|
||||||
|
public List<LocalesEntry> Locales { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct LocalesEntry
|
||||||
|
{
|
||||||
|
public string ID { get; set; }
|
||||||
|
public Dictionary<string, string> Translations { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.Build.Utilities.Core" />
|
||||||
|
<PackageReference Include="Newtonsoft.Json" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<UsingTask TaskName="Ryujinx.BuildValidationTasks.LocaleValidationTask" TaskFactory="TaskHostFactory" AssemblyFile="$(OutDir)Ryujinx.BuildValidationTasks.dll" />
|
||||||
|
|
||||||
|
<Target Name="LocalesJsonValidation" AfterTargets="AfterRebuild">
|
||||||
|
<LocaleValidationTask />
|
||||||
|
</Target>
|
||||||
|
|
||||||
|
</Project>
|
35
src/Ryujinx.Common/BitTricks.cs
Normal file
35
src/Ryujinx.Common/BitTricks.cs
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
namespace Ryujinx.Common
|
||||||
|
{
|
||||||
|
public class BitTricks
|
||||||
|
{
|
||||||
|
// Never actually written bit packing logic before, so I looked it up.
|
||||||
|
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
|
||||||
|
|
||||||
|
public static ulong PackBitFields(uint[] values, byte[] bitFields)
|
||||||
|
{
|
||||||
|
ulong retVal = values[0]; //we set the first value right away
|
||||||
|
for (int f = 1; f < values.Length; f++)
|
||||||
|
{
|
||||||
|
retVal <<= bitFields[f]; // we shift the previous value
|
||||||
|
retVal += values[f];// and add our current value
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static uint[] UnpackBitFields(ulong packed, byte[] bitFields)
|
||||||
|
{
|
||||||
|
int fields = bitFields.Length - 1; // number of fields to unpack
|
||||||
|
uint[] retArr = new uint[fields + 1]; // init return array
|
||||||
|
int curPos = 0; // current field bit position (start)
|
||||||
|
int lastEnd; // position where last field ended
|
||||||
|
for (int f = fields; f >= 0; f--) // loop from last
|
||||||
|
{
|
||||||
|
lastEnd = curPos; // we store where the last value ended
|
||||||
|
curPos += bitFields[f]; // we get where the current value starts
|
||||||
|
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
|
||||||
|
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
|
||||||
|
}
|
||||||
|
return retArr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -35,6 +35,8 @@ namespace Ryujinx.Common.Configuration
|
|||||||
#pragma warning restore IDE0055
|
#pragma warning restore IDE0055
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static float ToFloatY(this AspectRatio aspectRatio)
|
public static float ToFloatY(this AspectRatio aspectRatio)
|
||||||
{
|
{
|
||||||
|
61
src/Ryujinx.Common/Configuration/DirtyHacks.cs
Normal file
61
src/Ryujinx.Common/Configuration/DirtyHacks.cs
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace Ryujinx.Common.Configuration
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum DirtyHacks : byte
|
||||||
|
{
|
||||||
|
Xc2MenuSoftlockFix = 1,
|
||||||
|
ShaderCompilationThreadSleep = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
public record EnabledDirtyHack(DirtyHacks Hack, int Value)
|
||||||
|
{
|
||||||
|
public static readonly byte[] PackedFormat = [8, 32];
|
||||||
|
|
||||||
|
public ulong Pack() => BitTricks.PackBitFields([(uint)Hack, (uint)Value], PackedFormat);
|
||||||
|
|
||||||
|
public static EnabledDirtyHack Unpack(ulong packedHack)
|
||||||
|
{
|
||||||
|
var unpackedFields = BitTricks.UnpackBitFields(packedHack, PackedFormat);
|
||||||
|
if (unpackedFields is not [var hack, var value])
|
||||||
|
throw new ArgumentException(nameof(packedHack));
|
||||||
|
|
||||||
|
return new EnabledDirtyHack((DirtyHacks)hack, (int)value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DirtyHackCollection : Dictionary<DirtyHacks, int>
|
||||||
|
{
|
||||||
|
public DirtyHackCollection(EnabledDirtyHack[] hacks)
|
||||||
|
{
|
||||||
|
foreach ((DirtyHacks dirtyHacks, int value) in hacks)
|
||||||
|
{
|
||||||
|
Add(dirtyHacks, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public DirtyHackCollection(ulong[] packedHacks)
|
||||||
|
{
|
||||||
|
foreach ((DirtyHacks dirtyHacks, int value) in packedHacks.Select(EnabledDirtyHack.Unpack))
|
||||||
|
{
|
||||||
|
Add(dirtyHacks, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ulong[] PackEntries() =>
|
||||||
|
this
|
||||||
|
.Select(it =>
|
||||||
|
BitTricks.PackBitFields([(uint)it.Key, (uint)it.Value], EnabledDirtyHack.PackedFormat))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
public static implicit operator DirtyHackCollection(EnabledDirtyHack[] hacks) => new(hacks);
|
||||||
|
public static implicit operator DirtyHackCollection(ulong[] packedHacks) => new(packedHacks);
|
||||||
|
|
||||||
|
public new int this[DirtyHacks hack] => TryGetValue(hack, out var value) ? value : -1;
|
||||||
|
|
||||||
|
public bool IsEnabled(DirtyHacks hack) => ContainsKey(hack);
|
||||||
|
}
|
||||||
|
}
|
@@ -6,7 +6,9 @@ namespace Ryujinx.Common.Configuration
|
|||||||
[JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))]
|
[JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))]
|
||||||
public enum GraphicsBackend
|
public enum GraphicsBackend
|
||||||
{
|
{
|
||||||
|
Auto,
|
||||||
Vulkan,
|
Vulkan,
|
||||||
OpenGl,
|
OpenGl,
|
||||||
|
Metal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
namespace Ryujinx.Common.Configuration.Hid.Controller
|
namespace Ryujinx.Common.Configuration.Hid.Controller
|
||||||
{
|
{
|
||||||
public class JoyconConfigControllerStick<TButton, TStick> where TButton : unmanaged where TStick : unmanaged
|
public class JoyconConfigControllerStick<TButton, TStick>
|
||||||
|
where TButton : unmanaged
|
||||||
|
where TStick : unmanaged
|
||||||
{
|
{
|
||||||
public TStick Joystick { get; set; }
|
public TStick Joystick { get; set; }
|
||||||
public bool InvertStickX { get; set; }
|
public bool InvertStickX { get; set; }
|
||||||
|
@@ -9,5 +9,6 @@ namespace Ryujinx.Common.Configuration
|
|||||||
Bilinear,
|
Bilinear,
|
||||||
Nearest,
|
Nearest,
|
||||||
Fsr,
|
Fsr,
|
||||||
|
Area,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -8,10 +8,10 @@ namespace Ryujinx.Common
|
|||||||
public static class StreamExtensions
|
public static class StreamExtensions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes a <see cref="ReadOnlySpan{int}" /> to this stream.
|
/// Writes an int span to this stream.
|
||||||
///
|
///
|
||||||
/// This default implementation converts each buffer value to a stack-allocated
|
/// This default implementation converts each buffer value to a stack-allocated
|
||||||
/// byte array, then writes it to the Stream using <cref="System.Stream.Write(byte[])" />.
|
/// byte array, then writes it to the Stream using <see cref="Stream.Write(ReadOnlySpan{byte})" />.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="stream">The stream to be written to</param>
|
/// <param name="stream">The stream to be written to</param>
|
||||||
/// <param name="buffer">The buffer of values to be written</param>
|
/// <param name="buffer">The buffer of values to be written</param>
|
||||||
|
@@ -3,10 +3,28 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class ConsoleHelper
|
public static partial class ConsoleHelper
|
||||||
{
|
{
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
[LibraryImport("kernel32")]
|
||||||
|
private static partial nint GetConsoleWindow();
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
[LibraryImport("user32")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
[LibraryImport("user32")]
|
||||||
|
private static partial nint GetForegroundWindow();
|
||||||
|
|
||||||
|
[SupportedOSPlatform("windows")]
|
||||||
|
[LibraryImport("user32")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
private static partial bool SetForegroundWindow(nint hWnd);
|
||||||
|
|
||||||
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
|
public static bool SetConsoleWindowStateSupported => OperatingSystem.IsWindows();
|
||||||
|
|
||||||
public static void SetConsoleWindowState(bool show)
|
public static void SetConsoleWindowState(bool show)
|
||||||
@@ -35,16 +53,11 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SetForegroundWindow(hWnd);
|
||||||
|
|
||||||
|
hWnd = GetForegroundWindow();
|
||||||
|
|
||||||
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
|
ShowWindow(hWnd, show ? SW_SHOW : SW_HIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
[LibraryImport("kernel32")]
|
|
||||||
private static partial nint GetConsoleWindow();
|
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
|
||||||
[LibraryImport("user32")]
|
|
||||||
[return: MarshalAs(UnmanagedType.Bool)]
|
|
||||||
private static partial bool ShowWindow(nint hWnd, int nCmdShow);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -8,7 +8,7 @@ using System.Linq;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class FileAssociationHelper
|
public static partial class FileAssociationHelper
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
[LibraryImport("shell32.dll", SetLastError = true)]
|
[LibraryImport("shell32.dll", SetLastError = true)]
|
||||||
public static partial void SHChangeNotify(uint wEventId, uint uFlags, nint dwItem1, nint dwItem2);
|
public static partial void SHChangeNotify(uint wEventId, uint uFlags, nint dwItem1, nint dwItem2);
|
||||||
|
|
||||||
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows()) && !ReleaseInformation.IsFlatHubBuild;
|
public static bool IsTypeAssociationSupported => (OperatingSystem.IsLinux() || OperatingSystem.IsWindows());
|
||||||
|
|
||||||
public static bool AreMimeTypesRegistered
|
public static bool AreMimeTypesRegistered
|
||||||
{
|
{
|
||||||
@@ -132,7 +132,7 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
|
|
||||||
if (uninstall)
|
if (uninstall)
|
||||||
{
|
{
|
||||||
// If the types don't already exist, there's nothing to do and we can call this operation successful.
|
// If the types don't already exist, there's nothing to do, and we can call this operation successful.
|
||||||
if (!AreMimeTypesRegisteredWindows())
|
if (!AreMimeTypesRegisteredWindows())
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
@@ -3,7 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("linux")]
|
[SupportedOSPlatform("linux")]
|
||||||
public static class LinuxHelper
|
public static class LinuxHelper
|
@@ -2,7 +2,7 @@ using System;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
[SupportedOSPlatform("macos")]
|
[SupportedOSPlatform("macos")]
|
||||||
public static partial class ObjectiveC
|
public static partial class ObjectiveC
|
@@ -1,10 +1,11 @@
|
|||||||
|
using Gommon;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using System;
|
using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common.Helper
|
namespace Ryujinx.Common.Helper
|
||||||
{
|
{
|
||||||
public static partial class OpenHelper
|
public static partial class OpenHelper
|
||||||
{
|
{
|
||||||
@@ -34,6 +35,8 @@ namespace Ryujinx.UI.Common.Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void OpenFolder(FilePath path) => OpenFolder(path.Path);
|
||||||
|
|
||||||
public static void LocateFile(string path)
|
public static void LocateFile(string path)
|
||||||
{
|
{
|
||||||
if (File.Exists(path))
|
if (File.Exists(path))
|
@@ -4,6 +4,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
@@ -157,21 +158,16 @@ namespace Ryujinx.Common.Logging
|
|||||||
_time.Restart();
|
_time.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ILogTarget GetTarget(string targetName)
|
private static ILogTarget GetTarget(string targetName)
|
||||||
{
|
=> _logTargets.FirstOrDefault(target => target.Name.Equals(targetName));
|
||||||
foreach (var target in _logTargets)
|
|
||||||
{
|
|
||||||
if (target.Name.Equals(targetName))
|
|
||||||
{
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void AddTarget(ILogTarget target)
|
public static void AddTarget(ILogTarget target)
|
||||||
{
|
{
|
||||||
|
if (_logTargets.Any(t => t.Name == target.Name))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
_logTargets.Add(target);
|
_logTargets.Add(target);
|
||||||
|
|
||||||
Updated += target.Log;
|
Updated += target.Log;
|
||||||
|
@@ -27,11 +27,7 @@ namespace Ryujinx.Common.Logging.Targets
|
|||||||
|
|
||||||
private readonly int _overflowTimeout;
|
private readonly int _overflowTimeout;
|
||||||
|
|
||||||
string ILogTarget.Name { get => _target.Name; }
|
string ILogTarget.Name => _target.Name;
|
||||||
|
|
||||||
public AsyncLogTargetWrapper(ILogTarget target)
|
|
||||||
: this(target, -1)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
|
public AsyncLogTargetWrapper(ILogTarget target, int queueLimit = -1, AsyncLogTargetOverflowAction overflowAction = AsyncLogTargetOverflowAction.Block)
|
||||||
{
|
{
|
||||||
|
@@ -124,7 +124,7 @@ namespace Ryujinx.Common.PreciseSleep
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
private readonly List<NanosleepThread> _threads = new();
|
private readonly List<NanosleepThread> _threads = new();
|
||||||
private readonly List<NanosleepThread> _active = new();
|
private readonly List<NanosleepThread> _active = new();
|
||||||
private readonly Stack<NanosleepThread> _free = new();
|
private readonly Stack<NanosleepThread> _free = new();
|
||||||
|
@@ -50,7 +50,7 @@ namespace Ryujinx.Common.SystemInterop
|
|||||||
private long _lastTicks = PerformanceCounter.ElapsedTicks;
|
private long _lastTicks = PerformanceCounter.ElapsedTicks;
|
||||||
private long _lastId;
|
private long _lastId;
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
private readonly List<WaitingObject> _waitingObjects = new();
|
private readonly List<WaitingObject> _waitingObjects = new();
|
||||||
|
|
||||||
private WindowsGranularTimer()
|
private WindowsGranularTimer()
|
||||||
|
@@ -6,7 +6,6 @@ namespace Ryujinx.Common
|
|||||||
// DO NOT EDIT, filled by CI
|
// DO NOT EDIT, filled by CI
|
||||||
public static class ReleaseInformation
|
public static class ReleaseInformation
|
||||||
{
|
{
|
||||||
private const string FlatHubChannel = "flathub";
|
|
||||||
private const string CanaryChannel = "canary";
|
private const string CanaryChannel = "canary";
|
||||||
private const string ReleaseChannel = "release";
|
private const string ReleaseChannel = "release";
|
||||||
|
|
||||||
@@ -29,8 +28,6 @@ namespace Ryujinx.Common
|
|||||||
!ReleaseChannelRepo.StartsWith("%%") &&
|
!ReleaseChannelRepo.StartsWith("%%") &&
|
||||||
!ConfigFileName.StartsWith("%%");
|
!ConfigFileName.StartsWith("%%");
|
||||||
|
|
||||||
public static bool IsFlatHubBuild => IsValid && ReleaseChannelOwner.Equals(FlatHubChannel);
|
|
||||||
|
|
||||||
public static bool IsCanaryBuild => IsValid && ReleaseChannelName.Equals(CanaryChannel);
|
public static bool IsCanaryBuild => IsValid && ReleaseChannelName.Equals(CanaryChannel);
|
||||||
|
|
||||||
public static bool IsReleaseBuild => IsValid && ReleaseChannelName.Equals(ReleaseChannel);
|
public static bool IsReleaseBuild => IsValid && ReleaseChannelName.Equals(ReleaseChannel);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
<DefineConstants Condition=" '$(ExtraDefineConstants)' != '' ">$(DefineConstants);$(ExtraDefineConstants)</DefineConstants>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
|
@@ -1,129 +1,50 @@
|
|||||||
using DiscordRPC;
|
using Gommon;
|
||||||
using Humanizer;
|
using Ryujinx.Common.Configuration;
|
||||||
using Humanizer.Localisation;
|
using System;
|
||||||
using Ryujinx.Common;
|
|
||||||
using Ryujinx.HLE.Loaders.Processes;
|
|
||||||
using Ryujinx.UI.App.Common;
|
|
||||||
using Ryujinx.UI.Common.Configuration;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace Ryujinx.UI.Common
|
namespace Ryujinx.Common
|
||||||
{
|
{
|
||||||
public static class DiscordIntegrationModule
|
public static class TitleIDs
|
||||||
{
|
{
|
||||||
public static Timestamps StartedAt { get; set; }
|
public static ReactiveObject<Optional<string>> CurrentApplication { get; set; } = new();
|
||||||
|
|
||||||
private static string VersionString
|
public static GraphicsBackend SelectGraphicsBackend(string titleId, GraphicsBackend currentBackend)
|
||||||
=> (ReleaseInformation.IsCanaryBuild ? "Canary " : string.Empty) + $"v{ReleaseInformation.Version}";
|
|
||||||
|
|
||||||
private static readonly string _description =
|
|
||||||
ReleaseInformation.IsValid
|
|
||||||
? $"{VersionString} {ReleaseInformation.ReleaseChannelOwner}/{ReleaseInformation.ReleaseChannelSourceRepo}@{ReleaseInformation.BuildGitHash}"
|
|
||||||
: "dev build";
|
|
||||||
|
|
||||||
private const string ApplicationId = "1293250299716173864";
|
|
||||||
|
|
||||||
private const int ApplicationByteLimit = 128;
|
|
||||||
private const string Ellipsis = "…";
|
|
||||||
|
|
||||||
private static DiscordRpcClient _discordClient;
|
|
||||||
private static RichPresence _discordPresenceMain;
|
|
||||||
|
|
||||||
public static void Initialize()
|
|
||||||
{
|
{
|
||||||
_discordPresenceMain = new RichPresence
|
switch (currentBackend)
|
||||||
{
|
{
|
||||||
Assets = new Assets
|
case GraphicsBackend.OpenGl when OperatingSystem.IsMacOS():
|
||||||
{
|
return GraphicsBackend.Vulkan;
|
||||||
LargeImageKey = "ryujinx",
|
case GraphicsBackend.Vulkan or GraphicsBackend.OpenGl or GraphicsBackend.Metal:
|
||||||
LargeImageText = TruncateToByteLength(_description)
|
return currentBackend;
|
||||||
},
|
|
||||||
Details = "Main Menu",
|
|
||||||
State = "Idling",
|
|
||||||
Timestamps = StartedAt
|
|
||||||
};
|
|
||||||
|
|
||||||
ConfigurationState.Instance.EnableDiscordIntegration.Event += Update;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void Update(object sender, ReactiveEventArgs<bool> evnt)
|
|
||||||
{
|
|
||||||
if (evnt.OldValue != evnt.NewValue)
|
|
||||||
{
|
|
||||||
// If the integration was active, disable it and unload everything
|
|
||||||
if (evnt.OldValue)
|
|
||||||
{
|
|
||||||
_discordClient?.Dispose();
|
|
||||||
|
|
||||||
_discordClient = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we need to activate it and the client isn't active, initialize it
|
|
||||||
if (evnt.NewValue && _discordClient == null)
|
|
||||||
{
|
|
||||||
_discordClient = new DiscordRpcClient(ApplicationId);
|
|
||||||
|
|
||||||
_discordClient.Initialize();
|
|
||||||
_discordClient.SetPresence(_discordPresenceMain);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SwitchToPlayingState(ApplicationMetadata appMeta, ProcessResult procRes)
|
|
||||||
{
|
|
||||||
_discordClient?.SetPresence(new RichPresence
|
|
||||||
{
|
|
||||||
Assets = new Assets
|
|
||||||
{
|
|
||||||
LargeImageKey = _discordGameAssetKeys.Contains(procRes.ProgramIdText) ? procRes.ProgramIdText : "game",
|
|
||||||
LargeImageText = TruncateToByteLength($"{appMeta.Title} (v{procRes.DisplayVersion})"),
|
|
||||||
SmallImageKey = "ryujinx",
|
|
||||||
SmallImageText = TruncateToByteLength(_description)
|
|
||||||
},
|
|
||||||
Details = TruncateToByteLength($"Playing {appMeta.Title}"),
|
|
||||||
State = appMeta.LastPlayed.HasValue && appMeta.TimePlayed.TotalSeconds > 5
|
|
||||||
? $"Total play time: {appMeta.TimePlayed.Humanize(2, false, maxUnit: TimeUnit.Hour)}"
|
|
||||||
: "Never played",
|
|
||||||
Timestamps = Timestamps.Now
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void SwitchToMainState() => _discordClient?.SetPresence(_discordPresenceMain);
|
|
||||||
|
|
||||||
private static string TruncateToByteLength(string input)
|
|
||||||
{
|
|
||||||
if (Encoding.UTF8.GetByteCount(input) <= ApplicationByteLimit)
|
|
||||||
{
|
|
||||||
return input;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the length to trim the string to guarantee we have space for the trailing ellipsis.
|
if (!(OperatingSystem.IsMacOS() && RuntimeInformation.ProcessArchitecture is Architecture.Arm64))
|
||||||
int trimLimit = ApplicationByteLimit - Encoding.UTF8.GetByteCount(Ellipsis);
|
return GraphicsBackend.Vulkan;
|
||||||
|
|
||||||
// Make sure the string is long enough to perform the basic trim.
|
return GreatMetalTitles.ContainsIgnoreCase(titleId) ? GraphicsBackend.Metal : GraphicsBackend.Vulkan;
|
||||||
// Amount of bytes != Length of the string
|
|
||||||
if (input.Length > trimLimit)
|
|
||||||
{
|
|
||||||
// Basic trim to best case scenario of 1 byte characters.
|
|
||||||
input = input[..trimLimit];
|
|
||||||
}
|
|
||||||
|
|
||||||
while (Encoding.UTF8.GetByteCount(input) > trimLimit)
|
|
||||||
{
|
|
||||||
// Remove one character from the end of the string at a time.
|
|
||||||
input = input[..^1];
|
|
||||||
}
|
|
||||||
|
|
||||||
return input.TrimEnd() + Ellipsis;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static readonly string[] GreatMetalTitles =
|
||||||
|
[
|
||||||
|
"01006f8002326000", // Animal Crossings: New Horizons
|
||||||
|
"01009bf0072d4000", // Captain Toad: Treasure Tracker
|
||||||
|
"0100a5c00d162000", // Cuphead
|
||||||
|
"010023800d64a000", // Deltarune
|
||||||
|
"010028600EBDA000", // Mario 3D World
|
||||||
|
"0100152000022000", // Mario Kart 8 Deluxe
|
||||||
|
"01005CA01580E000", // Persona 5
|
||||||
|
"01001f5010dfa000", // Pokemon Legends Arceus
|
||||||
|
"01008C0016544000", // Sea of Stars
|
||||||
|
"01006A800016E000", // Smash Ultimate
|
||||||
|
"0100000000010000", // Super Mario Odyessy
|
||||||
|
];
|
||||||
|
|
||||||
|
public static string GetDiscordGameAsset(string titleId)
|
||||||
|
=> DiscordGameAssetKeys.Contains(titleId) ? titleId : "game";
|
||||||
|
|
||||||
public static void Exit()
|
public static readonly string[] DiscordGameAssetKeys =
|
||||||
{
|
|
||||||
_discordClient?.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static readonly string[] _discordGameAssetKeys =
|
|
||||||
[
|
[
|
||||||
"010055d009f78000", // Fire Emblem: Three Houses
|
"010055d009f78000", // Fire Emblem: Three Houses
|
||||||
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
"0100a12011cc8000", // Fire Emblem: Shadow Dragon
|
@@ -1,4 +1,4 @@
|
|||||||
namespace Ryujinx.UI.Common
|
namespace Ryujinx.Common.UI
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represent a common error that could be reported to the user by the emulator.
|
/// Represent a common error that could be reported to the user by the emulator.
|
@@ -1,3 +1,4 @@
|
|||||||
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
@@ -27,9 +28,14 @@ namespace Ryujinx.Common.Utilities
|
|||||||
ReadCommentHandling = JsonCommentHandling.Skip
|
ReadCommentHandling = JsonCommentHandling.Skip
|
||||||
};
|
};
|
||||||
|
|
||||||
public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Serialize(value, typeInfo);
|
public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo)
|
||||||
|
=> JsonSerializer.Serialize(value, typeInfo);
|
||||||
|
|
||||||
public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Deserialize(value, typeInfo);
|
public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo)
|
||||||
|
=> JsonSerializer.Deserialize(value, typeInfo);
|
||||||
|
|
||||||
|
public static T Deserialize<T>(ReadOnlySpan<byte> utf8Value, JsonTypeInfo<T> typeInfo)
|
||||||
|
=> JsonSerializer.Deserialize<T>(utf8Value, typeInfo);
|
||||||
|
|
||||||
public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo)
|
public static void SerializeToFile<T>(string filePath, T value, JsonTypeInfo<T> typeInfo)
|
||||||
{
|
{
|
||||||
|
@@ -230,25 +230,20 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<HostMemoryRange>();
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
||||||
if (guestRegions == null)
|
if (guestRegions == null)
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var regions = new HostMemoryRange[guestRegions.Count];
|
foreach (var guestRegion in guestRegions)
|
||||||
|
|
||||||
for (int i = 0; i < regions.Length; i++)
|
|
||||||
{
|
{
|
||||||
var guestRegion = guestRegions[i];
|
|
||||||
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
||||||
regions[i] = new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -256,23 +251,24 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<MemoryRange>();
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetPhysicalRegionsImpl(va, size);
|
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size))
|
||||||
|
{
|
||||||
|
yield return physicalRegion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
||||||
{
|
{
|
||||||
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pages = GetPagesCount(va, (uint)size, out va);
|
int pages = GetPagesCount(va, (uint)size, out va);
|
||||||
|
|
||||||
var regions = new List<MemoryRange>();
|
|
||||||
|
|
||||||
ulong regionStart = GetPhysicalAddressInternal(va);
|
ulong regionStart = GetPhysicalAddressInternal(va);
|
||||||
ulong regionSize = PageSize;
|
ulong regionSize = PageSize;
|
||||||
|
|
||||||
@@ -280,14 +276,14 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
{
|
{
|
||||||
if (!ValidateAddress(va + PageSize))
|
if (!ValidateAddress(va + PageSize))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
||||||
|
|
||||||
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
||||||
{
|
{
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
regionStart = newPa;
|
regionStart = newPa;
|
||||||
regionSize = 0;
|
regionSize = 0;
|
||||||
}
|
}
|
||||||
@@ -296,9 +292,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
regionSize += PageSize;
|
regionSize += PageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
using Ryujinx.Memory;
|
using Ryujinx.Memory;
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.AppleHv
|
namespace Ryujinx.Cpu.AppleHv
|
||||||
{
|
{
|
||||||
@@ -12,7 +13,7 @@ namespace Ryujinx.Cpu.AppleHv
|
|||||||
|
|
||||||
private static int _addressSpaces;
|
private static int _addressSpaces;
|
||||||
private static HvIpaAllocator _ipaAllocator;
|
private static HvIpaAllocator _ipaAllocator;
|
||||||
private static readonly object _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
|
|
||||||
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
|
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
|
||||||
{
|
{
|
||||||
|
@@ -115,6 +115,9 @@ namespace Ryujinx.Cpu.Jit.HostTracked
|
|||||||
}
|
}
|
||||||
|
|
||||||
private readonly AddressIntrusiveRedBlackTree<Mapping> _mappingTree;
|
private readonly AddressIntrusiveRedBlackTree<Mapping> _mappingTree;
|
||||||
|
|
||||||
|
// type is not Lock due to the unique usage of this mechanism,
|
||||||
|
// an arbitrary object is used as the lock passed in by constructor.
|
||||||
private readonly object _lock;
|
private readonly object _lock;
|
||||||
|
|
||||||
public Block(MemoryTracking tracking, Func<ulong, ulong> readPtCallback, MemoryBlock memory, ulong size, object locker) : base(memory, size)
|
public Block(MemoryTracking tracking, Func<ulong, ulong> readPtCallback, MemoryBlock memory, ulong size, object locker) : base(memory, size)
|
||||||
@@ -174,6 +177,9 @@ namespace Ryujinx.Cpu.Jit.HostTracked
|
|||||||
|
|
||||||
private readonly MemoryTracking _tracking;
|
private readonly MemoryTracking _tracking;
|
||||||
private readonly Func<ulong, ulong> _readPtCallback;
|
private readonly Func<ulong, ulong> _readPtCallback;
|
||||||
|
|
||||||
|
// type is not Lock due to the unique usage of this mechanism,
|
||||||
|
// an arbitrary object is used as the lock passed in by constructor.
|
||||||
private readonly object _lock;
|
private readonly object _lock;
|
||||||
|
|
||||||
public AddressSpacePartitionAllocator(
|
public AddressSpacePartitionAllocator(
|
||||||
|
@@ -250,25 +250,20 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<HostMemoryRange>();
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
var guestRegions = GetPhysicalRegionsImpl(va, size);
|
||||||
if (guestRegions == null)
|
if (guestRegions == null)
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
var regions = new HostMemoryRange[guestRegions.Count];
|
foreach (var guestRegion in guestRegions)
|
||||||
|
|
||||||
for (int i = 0; i < regions.Length; i++)
|
|
||||||
{
|
{
|
||||||
var guestRegion = guestRegions[i];
|
|
||||||
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
nint pointer = _backingMemory.GetPointer(guestRegion.Address, guestRegion.Size);
|
||||||
regions[i] = new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
@@ -276,23 +271,24 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
{
|
{
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
{
|
{
|
||||||
return Enumerable.Empty<MemoryRange>();
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetPhysicalRegionsImpl(va, size);
|
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size))
|
||||||
|
{
|
||||||
|
yield return physicalRegion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
||||||
{
|
{
|
||||||
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pages = GetPagesCount(va, (uint)size, out va);
|
int pages = GetPagesCount(va, (uint)size, out va);
|
||||||
|
|
||||||
var regions = new List<MemoryRange>();
|
|
||||||
|
|
||||||
ulong regionStart = GetPhysicalAddressInternal(va);
|
ulong regionStart = GetPhysicalAddressInternal(va);
|
||||||
ulong regionSize = PageSize;
|
ulong regionSize = PageSize;
|
||||||
|
|
||||||
@@ -300,14 +296,14 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
{
|
{
|
||||||
if (!ValidateAddress(va + PageSize))
|
if (!ValidateAddress(va + PageSize))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
||||||
|
|
||||||
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
||||||
{
|
{
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
regionStart = newPa;
|
regionStart = newPa;
|
||||||
regionSize = 0;
|
regionSize = 0;
|
||||||
}
|
}
|
||||||
@@ -316,9 +312,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
regionSize += PageSize;
|
regionSize += PageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@@ -475,17 +475,15 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
return GetPhysicalRegionsImpl(va, size);
|
return GetPhysicalRegionsImpl(va, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
|
||||||
{
|
{
|
||||||
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pages = GetPagesCount(va, (uint)size, out va);
|
int pages = GetPagesCount(va, (uint)size, out va);
|
||||||
|
|
||||||
var regions = new List<MemoryRange>();
|
|
||||||
|
|
||||||
ulong regionStart = GetPhysicalAddressInternal(va);
|
ulong regionStart = GetPhysicalAddressInternal(va);
|
||||||
ulong regionSize = PageSize;
|
ulong regionSize = PageSize;
|
||||||
|
|
||||||
@@ -493,14 +491,14 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
{
|
{
|
||||||
if (!ValidateAddress(va + PageSize))
|
if (!ValidateAddress(va + PageSize))
|
||||||
{
|
{
|
||||||
return null;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
ulong newPa = GetPhysicalAddressInternal(va + PageSize);
|
||||||
|
|
||||||
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
if (GetPhysicalAddressInternal(va) + PageSize != newPa)
|
||||||
{
|
{
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
regionStart = newPa;
|
regionStart = newPa;
|
||||||
regionSize = 0;
|
regionSize = 0;
|
||||||
}
|
}
|
||||||
@@ -509,9 +507,7 @@ namespace Ryujinx.Cpu.Jit
|
|||||||
regionSize += PageSize;
|
regionSize += PageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
regions.Add(new MemoryRange(regionStart, regionSize));
|
yield return new MemoryRange(regionStart, regionSize);
|
||||||
|
|
||||||
return regions;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@@ -478,7 +478,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
|
|||||||
bool skipContext,
|
bool skipContext,
|
||||||
int spillBaseOffset,
|
int spillBaseOffset,
|
||||||
int? resultRegister,
|
int? resultRegister,
|
||||||
params ulong[] callArgs)
|
params ReadOnlySpan<ulong> callArgs)
|
||||||
{
|
{
|
||||||
uint resultMask = 0u;
|
uint resultMask = 0u;
|
||||||
|
|
||||||
|
@@ -307,7 +307,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||||||
int tempRegister;
|
int tempRegister;
|
||||||
int tempGuestAddress = -1;
|
int tempGuestAddress = -1;
|
||||||
|
|
||||||
bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
|
bool inlineLookup = guestAddress.Kind != OperandKind.Constant &&
|
||||||
funcTable is { Sparse: true };
|
funcTable is { Sparse: true };
|
||||||
|
|
||||||
if (guestAddress.Kind == OperandKind.Constant)
|
if (guestAddress.Kind == OperandKind.Constant)
|
||||||
@@ -417,7 +417,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm64.Target.Arm64
|
|||||||
nint funcPtr,
|
nint funcPtr,
|
||||||
int spillBaseOffset,
|
int spillBaseOffset,
|
||||||
int? resultRegister,
|
int? resultRegister,
|
||||||
params ulong[] callArgs)
|
params ReadOnlySpan<ulong> callArgs)
|
||||||
{
|
{
|
||||||
uint resultMask = 0u;
|
uint resultMask = 0u;
|
||||||
|
|
||||||
|
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Cache
|
namespace Ryujinx.Cpu.LightningJit.Cache
|
||||||
{
|
{
|
||||||
@@ -23,7 +24,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
|
|
||||||
private static readonly List<CacheEntry> _cacheEntries = new();
|
private static readonly List<CacheEntry> _cacheEntries = new();
|
||||||
|
|
||||||
private static readonly object _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
|
@@ -4,6 +4,7 @@ using Ryujinx.Memory;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.LightningJit.Cache
|
namespace Ryujinx.Cpu.LightningJit.Cache
|
||||||
{
|
{
|
||||||
@@ -104,7 +105,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
private readonly MemoryCache _sharedCache;
|
private readonly MemoryCache _sharedCache;
|
||||||
private readonly MemoryCache _localCache;
|
private readonly MemoryCache _localCache;
|
||||||
private readonly PageAlignedRangeList _pendingMap;
|
private readonly PageAlignedRangeList _pendingMap;
|
||||||
private readonly object _lock;
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
class ThreadLocalCacheEntry
|
class ThreadLocalCacheEntry
|
||||||
{
|
{
|
||||||
@@ -137,7 +138,6 @@ namespace Ryujinx.Cpu.LightningJit.Cache
|
|||||||
_sharedCache = new(allocator, SharedCacheSize);
|
_sharedCache = new(allocator, SharedCacheSize);
|
||||||
_localCache = new(allocator, LocalCacheSize);
|
_localCache = new(allocator, LocalCacheSize);
|
||||||
_pendingMap = new(_sharedCache.ReprotectAsRx, RegisterFunction);
|
_pendingMap = new(_sharedCache.ReprotectAsRx, RegisterFunction);
|
||||||
_lock = new();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe nint Map(nint framePointer, ReadOnlySpan<byte> code, ulong guestAddress, ulong guestSize)
|
public unsafe nint Map(nint framePointer, ReadOnlySpan<byte> code, ulong guestAddress, ulong guestSize)
|
||||||
|
@@ -8,8 +8,6 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
{
|
{
|
||||||
public IEnumerable<ulong> GetCallStack(nint framePointer, nint codeRegionStart, int codeRegionSize, nint codeRegion2Start, int codeRegion2Size)
|
public IEnumerable<ulong> GetCallStack(nint framePointer, nint codeRegionStart, int codeRegionSize, nint codeRegion2Start, int codeRegion2Size)
|
||||||
{
|
{
|
||||||
List<ulong> functionPointers = new();
|
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
nint functionPointer = Marshal.ReadIntPtr(framePointer, nint.Size);
|
nint functionPointer = Marshal.ReadIntPtr(framePointer, nint.Size);
|
||||||
@@ -20,11 +18,9 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
functionPointers.Add((ulong)functionPointer - 4);
|
yield return (ulong)functionPointer - 4;
|
||||||
framePointer = Marshal.ReadIntPtr(framePointer);
|
framePointer = Marshal.ReadIntPtr(framePointer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return functionPointers;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Cpu.Signal
|
namespace Ryujinx.Cpu.Signal
|
||||||
{
|
{
|
||||||
@@ -59,7 +60,7 @@ namespace Ryujinx.Cpu.Signal
|
|||||||
|
|
||||||
private static MemoryBlock _codeBlock;
|
private static MemoryBlock _codeBlock;
|
||||||
|
|
||||||
private static readonly object _lock = new();
|
private static readonly Lock _lock = new();
|
||||||
private static bool _initialized;
|
private static bool _initialized;
|
||||||
|
|
||||||
static NativeSignalHandler()
|
static NativeSignalHandler()
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@@ -1,12 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum AntiAliasing
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Fxaa,
|
|
||||||
SmaaLow,
|
|
||||||
SmaaMedium,
|
|
||||||
SmaaHigh,
|
|
||||||
SmaaUltra,
|
|
||||||
}
|
|
||||||
}
|
|
18
src/Ryujinx.Graphics.GAL/ComputeSize.cs
Normal file
18
src/Ryujinx.Graphics.GAL/ComputeSize.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
{
|
||||||
|
public readonly struct ComputeSize
|
||||||
|
{
|
||||||
|
public readonly static ComputeSize VtgAsCompute = new ComputeSize(32, 32, 1);
|
||||||
|
|
||||||
|
public readonly int X;
|
||||||
|
public readonly int Y;
|
||||||
|
public readonly int Z;
|
||||||
|
|
||||||
|
public ComputeSize(int x, int y, int z)
|
||||||
|
{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -339,6 +339,84 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get bytes per element for this format.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="format">Texture format</param>
|
||||||
|
/// <returns>Byte size for an element of this format (pixel, vertex attribute, etc)</returns>
|
||||||
|
public static int GetBytesPerElement(this Format format)
|
||||||
|
{
|
||||||
|
int scalarSize = format.GetScalarSize();
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case Format.R8G8Unorm:
|
||||||
|
case Format.R8G8Snorm:
|
||||||
|
case Format.R8G8Uint:
|
||||||
|
case Format.R8G8Sint:
|
||||||
|
case Format.R8G8Uscaled:
|
||||||
|
case Format.R8G8Sscaled:
|
||||||
|
case Format.R16G16Float:
|
||||||
|
case Format.R16G16Unorm:
|
||||||
|
case Format.R16G16Snorm:
|
||||||
|
case Format.R16G16Uint:
|
||||||
|
case Format.R16G16Sint:
|
||||||
|
case Format.R16G16Uscaled:
|
||||||
|
case Format.R16G16Sscaled:
|
||||||
|
case Format.R32G32Float:
|
||||||
|
case Format.R32G32Uint:
|
||||||
|
case Format.R32G32Sint:
|
||||||
|
case Format.R32G32Uscaled:
|
||||||
|
case Format.R32G32Sscaled:
|
||||||
|
return 2 * scalarSize;
|
||||||
|
|
||||||
|
case Format.R8G8B8Unorm:
|
||||||
|
case Format.R8G8B8Snorm:
|
||||||
|
case Format.R8G8B8Uint:
|
||||||
|
case Format.R8G8B8Sint:
|
||||||
|
case Format.R8G8B8Uscaled:
|
||||||
|
case Format.R8G8B8Sscaled:
|
||||||
|
case Format.R16G16B16Float:
|
||||||
|
case Format.R16G16B16Unorm:
|
||||||
|
case Format.R16G16B16Snorm:
|
||||||
|
case Format.R16G16B16Uint:
|
||||||
|
case Format.R16G16B16Sint:
|
||||||
|
case Format.R16G16B16Uscaled:
|
||||||
|
case Format.R16G16B16Sscaled:
|
||||||
|
case Format.R32G32B32Float:
|
||||||
|
case Format.R32G32B32Uint:
|
||||||
|
case Format.R32G32B32Sint:
|
||||||
|
case Format.R32G32B32Uscaled:
|
||||||
|
case Format.R32G32B32Sscaled:
|
||||||
|
return 3 * scalarSize;
|
||||||
|
|
||||||
|
case Format.R8G8B8A8Unorm:
|
||||||
|
case Format.R8G8B8A8Snorm:
|
||||||
|
case Format.R8G8B8A8Uint:
|
||||||
|
case Format.R8G8B8A8Sint:
|
||||||
|
case Format.R8G8B8A8Srgb:
|
||||||
|
case Format.R8G8B8A8Uscaled:
|
||||||
|
case Format.R8G8B8A8Sscaled:
|
||||||
|
case Format.B8G8R8A8Unorm:
|
||||||
|
case Format.B8G8R8A8Srgb:
|
||||||
|
case Format.R16G16B16A16Float:
|
||||||
|
case Format.R16G16B16A16Unorm:
|
||||||
|
case Format.R16G16B16A16Snorm:
|
||||||
|
case Format.R16G16B16A16Uint:
|
||||||
|
case Format.R16G16B16A16Sint:
|
||||||
|
case Format.R16G16B16A16Uscaled:
|
||||||
|
case Format.R16G16B16A16Sscaled:
|
||||||
|
case Format.R32G32B32A32Float:
|
||||||
|
case Format.R32G32B32A32Uint:
|
||||||
|
case Format.R32G32B32A32Sint:
|
||||||
|
case Format.R32G32B32A32Uscaled:
|
||||||
|
case Format.R32G32B32A32Sscaled:
|
||||||
|
return 4 * scalarSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
return scalarSize;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if the texture format is a depth or depth-stencil format.
|
/// Checks if the texture format is a depth or depth-stencil format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.GAL
|
namespace Ryujinx.Graphics.GAL
|
||||||
|
@@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
|
|||||||
public uint ProgramCount { get; set; } = 0;
|
public uint ProgramCount { get; set; } = 0;
|
||||||
|
|
||||||
private Action _interruptAction;
|
private Action _interruptAction;
|
||||||
private readonly object _interruptLock = new();
|
private readonly Lock _interruptLock = new();
|
||||||
|
|
||||||
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;
|
||||||
|
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
using Ryujinx.Graphics.GAL.Multithreading.Commands.Window;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
using Ryujinx.Graphics.GAL.Multithreading.Model;
|
||||||
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
using Ryujinx.Graphics.GAL.Multithreading.Resources;
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
@@ -4,23 +4,22 @@ namespace Ryujinx.Graphics.GAL
|
|||||||
{
|
{
|
||||||
public int FragmentOutputMap { get; }
|
public int FragmentOutputMap { get; }
|
||||||
public ResourceLayout ResourceLayout { get; }
|
public ResourceLayout ResourceLayout { get; }
|
||||||
|
public ComputeSize ComputeLocalSize { get; }
|
||||||
public ProgramPipelineState? State { get; }
|
public ProgramPipelineState? State { get; }
|
||||||
public bool FromCache { get; set; }
|
public bool FromCache { get; set; }
|
||||||
|
|
||||||
public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, ProgramPipelineState state, bool fromCache = false)
|
public ShaderInfo(
|
||||||
|
int fragmentOutputMap,
|
||||||
|
ResourceLayout resourceLayout,
|
||||||
|
ComputeSize computeLocalSize,
|
||||||
|
ProgramPipelineState? state,
|
||||||
|
bool fromCache = false)
|
||||||
{
|
{
|
||||||
FragmentOutputMap = fragmentOutputMap;
|
FragmentOutputMap = fragmentOutputMap;
|
||||||
ResourceLayout = resourceLayout;
|
ResourceLayout = resourceLayout;
|
||||||
|
ComputeLocalSize = computeLocalSize;
|
||||||
State = state;
|
State = state;
|
||||||
FromCache = fromCache;
|
FromCache = fromCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, bool fromCache = false)
|
|
||||||
{
|
|
||||||
FragmentOutputMap = fragmentOutputMap;
|
|
||||||
ResourceLayout = resourceLayout;
|
|
||||||
State = null;
|
|
||||||
FromCache = fromCache;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum ScalingFilter
|
|
||||||
{
|
|
||||||
Bilinear,
|
|
||||||
Nearest,
|
|
||||||
Fsr,
|
|
||||||
Area,
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
namespace Ryujinx.Graphics.GAL
|
|
||||||
{
|
|
||||||
public enum VSyncMode
|
|
||||||
{
|
|
||||||
Switch,
|
|
||||||
Unbounded,
|
|
||||||
Custom
|
|
||||||
}
|
|
||||||
}
|
|
@@ -11,8 +11,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
class VtgAsComputeContext : IDisposable
|
class VtgAsComputeContext : IDisposable
|
||||||
{
|
{
|
||||||
private const int DummyBufferSize = 16;
|
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -48,7 +46,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
1,
|
format.GetBytesPerElement(),
|
||||||
format,
|
format,
|
||||||
DepthStencilMode.Depth,
|
DepthStencilMode.Depth,
|
||||||
Target.TextureBuffer,
|
Target.TextureBuffer,
|
||||||
@@ -521,21 +519,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write);
|
return new BufferRange(_geometryIndexDataBuffer.Handle, offset, size, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets the range for a dummy 16 bytes buffer, filled with zeros.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>Dummy buffer range</returns>
|
|
||||||
public BufferRange GetDummyBufferRange()
|
|
||||||
{
|
|
||||||
if (_dummyBuffer == BufferHandle.Null)
|
|
||||||
{
|
|
||||||
_dummyBuffer = _context.Renderer.CreateBuffer(DummyBufferSize, BufferAccess.DeviceMemory);
|
|
||||||
_context.Renderer.Pipeline.ClearBuffer(_dummyBuffer, 0, DummyBufferSize, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new BufferRange(_dummyBuffer, 0, DummyBufferSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the range for a sequential index buffer, with ever incrementing index values.
|
/// Gets the range for a sequential index buffer, with ever incrementing index values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -147,7 +147,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
{
|
{
|
||||||
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
||||||
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
||||||
SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,15 +162,12 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
{
|
{
|
||||||
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
_vacContext.VertexInfoBufferUpdater.SetVertexStride(index, 0, componentsCount);
|
||||||
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
_vacContext.VertexInfoBufferUpdater.SetVertexOffset(index, 0, 0);
|
||||||
SetDummyBufferTexture(_vertexAsCompute.Reservations, index, format);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vbStride = vertexBuffer.UnpackStride();
|
int vbStride = vertexBuffer.UnpackStride();
|
||||||
ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count);
|
ulong vbSize = GetVertexBufferSize(address, endAddress.Pack(), vbStride, _indexed, instanced, _firstVertex, _count);
|
||||||
|
|
||||||
ulong oldVbSize = vbSize;
|
|
||||||
|
|
||||||
ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset();
|
ulong attributeOffset = (ulong)vertexAttrib.UnpackOffset();
|
||||||
int componentSize = format.GetScalarSize();
|
int componentSize = format.GetScalarSize();
|
||||||
|
|
||||||
@@ -345,20 +341,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
|
|||||||
return maxOutputVertices / verticesPerPrimitive;
|
return maxOutputVertices / verticesPerPrimitive;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Binds a dummy buffer as vertex buffer into a buffer texture.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="reservations">Shader resource binding reservations</param>
|
|
||||||
/// <param name="index">Buffer texture index</param>
|
|
||||||
/// <param name="format">Buffer texture format</param>
|
|
||||||
private readonly void SetDummyBufferTexture(ResourceReservations reservations, int index, Format format)
|
|
||||||
{
|
|
||||||
ITexture bufferTexture = _vacContext.EnsureBufferTexture(index + 2, format);
|
|
||||||
bufferTexture.SetStorage(_vacContext.GetDummyBufferRange());
|
|
||||||
|
|
||||||
_context.Renderer.Pipeline.SetTextureAndSampler(ShaderStage.Compute, reservations.GetVertexBufferTextureBinding(index), bufferTexture, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Binds a vertex buffer into a buffer texture.
|
/// Binds a vertex buffer into a buffer texture.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
using Ryujinx.Common;
|
using Ryujinx.Common;
|
||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Graphics.Device;
|
using Ryujinx.Graphics.Device;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
using Ryujinx.Graphics.Gpu.Engine.GPFifo;
|
||||||
@@ -90,6 +91,9 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Support buffer updater.
|
/// Support buffer updater.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
internal SupportBufferUpdater SupportBufferUpdater { get; }
|
||||||
|
|
||||||
|
internal DirtyHackCollection DirtyHacks { get; }
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Host hardware capabilities.
|
/// Host hardware capabilities.
|
||||||
@@ -113,7 +117,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Creates a new instance of the GPU emulation context.
|
/// Creates a new instance of the GPU emulation context.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="renderer">Host renderer</param>
|
/// <param name="renderer">Host renderer</param>
|
||||||
public GpuContext(IRenderer renderer)
|
public GpuContext(IRenderer renderer, DirtyHackCollection hackCollection)
|
||||||
{
|
{
|
||||||
Renderer = renderer;
|
Renderer = renderer;
|
||||||
|
|
||||||
@@ -136,6 +140,8 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
|
|
||||||
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
SupportBufferUpdater = new SupportBufferUpdater(renderer);
|
||||||
|
|
||||||
|
DirtyHacks = hackCollection;
|
||||||
|
|
||||||
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,7 +46,7 @@ namespace Ryujinx.Graphics.Gpu
|
|||||||
/// Enables or disables high-level emulation of common GPU Macro code.
|
/// Enables or disables high-level emulation of common GPU Macro code.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static bool EnableMacroHLE = true;
|
public static bool EnableMacroHLE = true;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Title id of the current running game.
|
/// Title id of the current running game.
|
||||||
/// Used by the shader cache.
|
/// Used by the shader cache.
|
||||||
|
@@ -8,6 +8,7 @@ using Ryujinx.Graphics.Texture;
|
|||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
@@ -998,7 +999,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
{
|
{
|
||||||
bool dataOverlaps = texture.DataOverlaps(overlap, compatibility);
|
bool dataOverlaps = texture.DataOverlaps(overlap, compatibility);
|
||||||
|
|
||||||
if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Exists(incompatible => incompatible.Group == overlap.Group))
|
if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Any(incompatible => incompatible.Group == overlap.Group))
|
||||||
{
|
{
|
||||||
incompatibleOverlaps.Add(new TextureIncompatibleOverlap(overlap.Group, compatibility));
|
incompatibleOverlaps.Add(new TextureIncompatibleOverlap(overlap.Group, compatibility));
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,7 @@ using Ryujinx.Memory.Range;
|
|||||||
using Ryujinx.Memory.Tracking;
|
using Ryujinx.Memory.Tracking;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Image
|
namespace Ryujinx.Graphics.Gpu.Image
|
||||||
@@ -1555,7 +1556,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="copy">True if the overlap should register copy dependencies</param>
|
/// <param name="copy">True if the overlap should register copy dependencies</param>
|
||||||
public void RegisterIncompatibleOverlap(TextureIncompatibleOverlap other, bool copy)
|
public void RegisterIncompatibleOverlap(TextureIncompatibleOverlap other, bool copy)
|
||||||
{
|
{
|
||||||
if (!_incompatibleOverlaps.Exists(overlap => overlap.Group == other.Group))
|
if (!_incompatibleOverlaps.Any(overlap => overlap.Group == other.Group))
|
||||||
{
|
{
|
||||||
if (copy && other.Compatibility == TextureViewCompatibility.LayoutIncompatible)
|
if (copy && other.Compatibility == TextureViewCompatibility.LayoutIncompatible)
|
||||||
{
|
{
|
||||||
@@ -1701,3 +1702,4 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -721,7 +721,7 @@ namespace Ryujinx.Graphics.Gpu.Image
|
|||||||
/// <param name="format">The format of the texture</param>
|
/// <param name="format">The format of the texture</param>
|
||||||
/// <param name="components">The texture swizzle components</param>
|
/// <param name="components">The texture swizzle components</param>
|
||||||
/// <returns>The depth-stencil mode</returns>
|
/// <returns>The depth-stencil mode</returns>
|
||||||
private static DepthStencilMode GetDepthStencilMode(Format format, params SwizzleComponent[] components)
|
private static DepthStencilMode GetDepthStencilMode(Format format, params ReadOnlySpan<SwizzleComponent> components)
|
||||||
{
|
{
|
||||||
// R = Depth, G = Stencil.
|
// R = Depth, G = Stencil.
|
||||||
// On 24-bits depth formats, this is inverted (Stencil is R etc).
|
// On 24-bits depth formats, this is inverted (Stencil is R etc).
|
||||||
|
@@ -2,6 +2,7 @@ using Ryujinx.Common.Pools;
|
|||||||
using Ryujinx.Memory.Range;
|
using Ryujinx.Memory.Range;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Memory
|
namespace Ryujinx.Graphics.Gpu.Memory
|
||||||
{
|
{
|
||||||
@@ -76,7 +77,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
private BufferMigration _source;
|
private BufferMigration _source;
|
||||||
private BufferModifiedRangeList _migrationTarget;
|
private BufferModifiedRangeList _migrationTarget;
|
||||||
|
|
||||||
private readonly object _lock = new();
|
private readonly Lock _lock = new();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the modified range list has any entries or not.
|
/// Whether the modified range list has any entries or not.
|
||||||
@@ -435,7 +436,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
|
|||||||
|
|
||||||
if (_source == null)
|
if (_source == null)
|
||||||
{
|
{
|
||||||
// Create a new migration.
|
// Create a new migration.
|
||||||
_source = new BufferMigration(new BufferMigrationSpan[] { span }, this, _context.SyncNumber);
|
_source = new BufferMigration(new BufferMigrationSpan[] { span }, this, _context.SyncNumber);
|
||||||
|
|
||||||
_context.RegisterBufferMigration(_source);
|
_context.RegisterBufferMigration(_source);
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
@@ -324,6 +324,11 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
|
|
||||||
bool loadHostCache = header.CodeGenVersion == CodeGenVersion;
|
bool loadHostCache = header.CodeGenVersion == CodeGenVersion;
|
||||||
|
|
||||||
|
if (context.Capabilities.Api == TargetApi.Metal)
|
||||||
|
{
|
||||||
|
loadHostCache = false;
|
||||||
|
}
|
||||||
|
|
||||||
int programIndex = 0;
|
int programIndex = 0;
|
||||||
|
|
||||||
DataEntry entry = new();
|
DataEntry entry = new();
|
||||||
@@ -392,7 +397,8 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
context,
|
context,
|
||||||
shaders,
|
shaders,
|
||||||
specState.PipelineState,
|
specState.PipelineState,
|
||||||
specState.TransformFeedbackDescriptors != null);
|
specState.TransformFeedbackDescriptors != null,
|
||||||
|
specState.ComputeState.GetLocalSize());
|
||||||
|
|
||||||
IProgram hostProgram;
|
IProgram hostProgram;
|
||||||
|
|
||||||
@@ -629,7 +635,10 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
|
if (context.Capabilities.Api != TargetApi.Metal)
|
||||||
|
{
|
||||||
|
WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
using Ryujinx.Graphics.Shader;
|
using Ryujinx.Graphics.Shader;
|
||||||
@@ -366,6 +367,9 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (_context.DirtyHacks.IsEnabled(DirtyHacks.ShaderCompilationThreadSleep))
|
||||||
|
Thread.Sleep(_context.DirtyHacks[DirtyHacks.ShaderCompilationThreadSleep]);
|
||||||
|
|
||||||
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
|
||||||
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -490,7 +494,12 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
|
|||||||
{
|
{
|
||||||
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
|
||||||
|
|
||||||
ShaderInfoBuilder shaderInfoBuilder = new(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
|
ref GpuChannelComputeState computeState = ref compilation.SpecializationState.ComputeState;
|
||||||
|
|
||||||
|
ShaderInfoBuilder shaderInfoBuilder = new(
|
||||||
|
_context,
|
||||||
|
compilation.SpecializationState.TransformFeedbackDescriptors != null,
|
||||||
|
computeLocalSize: computeState.GetLocalSize());
|
||||||
|
|
||||||
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
for (int index = 0; index < compilation.TranslatedStages.Length; index++)
|
||||||
{
|
{
|
||||||
|
@@ -16,7 +16,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private readonly GpuAccessorState _state;
|
private readonly GpuAccessorState _state;
|
||||||
private readonly int _stageIndex;
|
private readonly int _stageIndex;
|
||||||
private readonly bool _compute;
|
private readonly bool _compute;
|
||||||
private readonly bool _isVulkan;
|
private readonly bool _isOpenGL;
|
||||||
private readonly bool _hasGeometryShader;
|
private readonly bool _hasGeometryShader;
|
||||||
private readonly bool _supportsQuads;
|
private readonly bool _supportsQuads;
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
_channel = channel;
|
_channel = channel;
|
||||||
_state = state;
|
_state = state;
|
||||||
_stageIndex = stageIndex;
|
_stageIndex = stageIndex;
|
||||||
_isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
|
_isOpenGL = context.Capabilities.Api == TargetApi.OpenGL;
|
||||||
_hasGeometryShader = hasGeometryShader;
|
_hasGeometryShader = hasGeometryShader;
|
||||||
_supportsQuads = context.Capabilities.SupportsQuads;
|
_supportsQuads = context.Capabilities.SupportsQuads;
|
||||||
|
|
||||||
@@ -116,10 +116,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
public GpuGraphicsState QueryGraphicsState()
|
public GpuGraphicsState QueryGraphicsState()
|
||||||
{
|
{
|
||||||
return _state.GraphicsState.CreateShaderGraphicsState(
|
return _state.GraphicsState.CreateShaderGraphicsState(
|
||||||
!_isVulkan,
|
_isOpenGL,
|
||||||
_supportsQuads,
|
_supportsQuads,
|
||||||
_hasGeometryShader,
|
_hasGeometryShader,
|
||||||
_isVulkan || _state.GraphicsState.YNegateEnabled);
|
!_isOpenGL || _state.GraphicsState.YNegateEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
@@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
{
|
{
|
||||||
int binding;
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||||
{
|
{
|
||||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
|
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumUniformBuffersPerStage, "Uniform buffer");
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
{
|
{
|
||||||
int binding;
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||||
{
|
{
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
@@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
{
|
{
|
||||||
int binding;
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||||
{
|
{
|
||||||
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
binding = GetBindingFromIndex(index, _context.Capabilities.MaximumStorageBuffersPerStage, "Storage buffer");
|
||||||
}
|
}
|
||||||
@@ -119,7 +119,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
{
|
{
|
||||||
int binding;
|
int binding;
|
||||||
|
|
||||||
if (_context.Capabilities.Api == TargetApi.Vulkan)
|
if (_context.Capabilities.Api != TargetApi.OpenGL)
|
||||||
{
|
{
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
|
@@ -1,3 +1,5 @@
|
|||||||
|
using Ryujinx.Graphics.GAL;
|
||||||
|
|
||||||
namespace Ryujinx.Graphics.Gpu.Shader
|
namespace Ryujinx.Graphics.Gpu.Shader
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,5 +63,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
SharedMemorySize = sharedMemorySize;
|
SharedMemorySize = sharedMemorySize;
|
||||||
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
HasUnalignedStorageBuffer = hasUnalignedStorageBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the local group size of the shader in a GAL compatible struct.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Local group size</returns>
|
||||||
|
public ComputeSize GetLocalSize()
|
||||||
|
{
|
||||||
|
return new ComputeSize(LocalSizeX, LocalSizeY, LocalSizeZ);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,3 +1,4 @@
|
|||||||
|
using Ryujinx.Common;
|
||||||
using Ryujinx.Common.Configuration;
|
using Ryujinx.Common.Configuration;
|
||||||
using Ryujinx.Common.Logging;
|
using Ryujinx.Common.Logging;
|
||||||
using Ryujinx.Graphics.GAL;
|
using Ryujinx.Graphics.GAL;
|
||||||
@@ -224,7 +225,10 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false);
|
TranslatedShader translatedShader = TranslateShader(_dumper, channel, translatorContext, cachedGuestCode, asCompute: false);
|
||||||
|
|
||||||
ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) };
|
ShaderSource[] shaderSourcesArray = new ShaderSource[] { CreateShaderSource(translatedShader.Program) };
|
||||||
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(_context, translatedShader.Program.Info);
|
ShaderInfo info = ShaderInfoBuilder.BuildForCompute(
|
||||||
|
_context,
|
||||||
|
translatedShader.Program.Info,
|
||||||
|
computeState.GetLocalSize());
|
||||||
IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info);
|
IProgram hostProgram = _context.Renderer.CreateProgram(shaderSourcesArray, info);
|
||||||
|
|
||||||
cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader);
|
cpShader = new CachedShaderProgram(hostProgram, specState, translatedShader.Shader);
|
||||||
@@ -425,7 +429,8 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage;
|
TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage;
|
||||||
|
|
||||||
program = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
|
(program, ShaderProgramInfo vacInfo) = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
|
||||||
|
infoBuilder.AddStageInfoVac(vacInfo);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -530,7 +535,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
|
private ShaderAsCompute CreateHostVertexAsComputeProgram(ShaderProgram program, TranslatorContext context, bool tfEnabled)
|
||||||
{
|
{
|
||||||
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
|
ShaderSource source = new(program.Code, program.BinaryCode, ShaderStage.Compute, program.Language);
|
||||||
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, tfEnabled);
|
ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, context.GetVertexAsComputeInfo(), tfEnabled);
|
||||||
|
|
||||||
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
|
return new(_context.Renderer.CreateProgram(new[] { source }, info), program.Info, context.GetResourceReservations());
|
||||||
}
|
}
|
||||||
@@ -822,16 +827,20 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates shader translation options with the requested graphics API and flags.
|
/// Creates shader translation options with the requested graphics API and flags.
|
||||||
/// The shader language is choosen based on the current configuration and graphics API.
|
/// The shader language is chosen based on the current configuration and graphics API.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="api">Target graphics API</param>
|
/// <param name="api">Target graphics API</param>
|
||||||
/// <param name="flags">Translation flags</param>
|
/// <param name="flags">Translation flags</param>
|
||||||
/// <returns>Translation options</returns>
|
/// <returns>Translation options</returns>
|
||||||
private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags)
|
private static TranslationOptions CreateTranslationOptions(TargetApi api, TranslationFlags flags)
|
||||||
{
|
{
|
||||||
TargetLanguage lang = GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan
|
TargetLanguage lang = api switch
|
||||||
? TargetLanguage.Spirv
|
{
|
||||||
: TargetLanguage.Glsl;
|
TargetApi.OpenGL => TargetLanguage.Glsl,
|
||||||
|
TargetApi.Vulkan => GraphicsConfig.EnableSpirvCompilationOnVulkan ? TargetLanguage.Spirv : TargetLanguage.Glsl,
|
||||||
|
TargetApi.Metal => TargetLanguage.Msl,
|
||||||
|
_ => throw new NotImplementedException()
|
||||||
|
};
|
||||||
|
|
||||||
return new TranslationOptions(lang, api, flags);
|
return new TranslationOptions(lang, api, flags);
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
ResourceStages.Geometry;
|
ResourceStages.Geometry;
|
||||||
|
|
||||||
private readonly GpuContext _context;
|
private readonly GpuContext _context;
|
||||||
|
private readonly ComputeSize _computeLocalSize;
|
||||||
|
|
||||||
private int _fragmentOutputMap;
|
private int _fragmentOutputMap;
|
||||||
|
|
||||||
@@ -39,9 +40,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
/// <param name="context">GPU context that owns the shaders that will be added to the builder</param>
|
||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
/// <param name="vertexAsCompute">Indicates that the vertex shader will be emulated on a compute shader</param>
|
/// <param name="vertexAsCompute">Indicates that the vertex shader will be emulated on a compute shader</param>
|
||||||
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false)
|
/// <param name="computeLocalSize">Indicates the local thread size for a compute shader</param>
|
||||||
|
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false, ComputeSize computeLocalSize = default)
|
||||||
{
|
{
|
||||||
_context = context;
|
_context = context;
|
||||||
|
_computeLocalSize = computeLocalSize;
|
||||||
|
|
||||||
_fragmentOutputMap = -1;
|
_fragmentOutputMap = -1;
|
||||||
|
|
||||||
@@ -95,7 +98,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
|
private void PopulateDescriptorAndUsages(ResourceStages stages, ResourceType type, int setIndex, int start, int count, bool write = false)
|
||||||
{
|
{
|
||||||
AddDescriptor(stages, type, setIndex, start, count);
|
AddDescriptor(stages, type, setIndex, start, count);
|
||||||
AddUsage(stages, type, setIndex, start, count, write);
|
// AddUsage(stages, type, setIndex, start, count, write);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -159,6 +162,25 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
AddUsage(info.Images, stages, isImage: true);
|
AddUsage(info.Images, stages, isImage: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddStageInfoVac(ShaderProgramInfo info)
|
||||||
|
{
|
||||||
|
ResourceStages stages = info.Stage switch
|
||||||
|
{
|
||||||
|
ShaderStage.Compute => ResourceStages.Compute,
|
||||||
|
ShaderStage.Vertex => ResourceStages.Vertex,
|
||||||
|
ShaderStage.TessellationControl => ResourceStages.TessellationControl,
|
||||||
|
ShaderStage.TessellationEvaluation => ResourceStages.TessellationEvaluation,
|
||||||
|
ShaderStage.Geometry => ResourceStages.Geometry,
|
||||||
|
ShaderStage.Fragment => ResourceStages.Fragment,
|
||||||
|
_ => ResourceStages.None,
|
||||||
|
};
|
||||||
|
|
||||||
|
AddUsage(info.CBuffers, stages, isStorage: false);
|
||||||
|
AddUsage(info.SBuffers, stages, isStorage: true);
|
||||||
|
AddUsage(info.Textures, stages, isImage: false);
|
||||||
|
AddUsage(info.Images, stages, isImage: true);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds a resource descriptor to the list of descriptors.
|
/// Adds a resource descriptor to the list of descriptors.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -361,14 +383,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
|
|
||||||
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
|
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
|
||||||
|
|
||||||
if (pipeline.HasValue)
|
return new ShaderInfo(_fragmentOutputMap, resourceLayout, _computeLocalSize, pipeline, fromCache);
|
||||||
{
|
|
||||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, pipeline.Value, fromCache);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return new ShaderInfo(_fragmentOutputMap, resourceLayout, fromCache);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -378,14 +393,16 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="programs">Shaders from the disk cache</param>
|
/// <param name="programs">Shaders from the disk cache</param>
|
||||||
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
/// <param name="pipeline">Optional pipeline for background compilation</param>
|
||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
|
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCache(
|
public static ShaderInfo BuildForCache(
|
||||||
GpuContext context,
|
GpuContext context,
|
||||||
IEnumerable<CachedShaderStage> programs,
|
IEnumerable<CachedShaderStage> programs,
|
||||||
ProgramPipelineState? pipeline,
|
ProgramPipelineState? pipeline,
|
||||||
bool tfEnabled)
|
bool tfEnabled,
|
||||||
|
ComputeSize computeLocalSize)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled);
|
ShaderInfoBuilder builder = new(context, tfEnabled, computeLocalSize: computeLocalSize);
|
||||||
|
|
||||||
foreach (CachedShaderStage program in programs)
|
foreach (CachedShaderStage program in programs)
|
||||||
{
|
{
|
||||||
@@ -403,11 +420,12 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="context">GPU context that owns the shader</param>
|
/// <param name="context">GPU context that owns the shader</param>
|
||||||
/// <param name="info">Compute shader information</param>
|
/// <param name="info">Compute shader information</param>
|
||||||
|
/// <param name="computeLocalSize">Compute local thread size</param>
|
||||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
|
public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, ComputeSize computeLocalSize, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false);
|
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false, computeLocalSize: computeLocalSize);
|
||||||
|
|
||||||
builder.AddStageInfo(info);
|
builder.AddStageInfo(info);
|
||||||
|
|
||||||
@@ -422,10 +440,11 @@ namespace Ryujinx.Graphics.Gpu.Shader
|
|||||||
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
/// <param name="tfEnabled">Indicates if the graphics shader is used with transform feedback enabled</param>
|
||||||
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
/// <param name="fromCache">True if the compute shader comes from a disk cache, false otherwise</param>
|
||||||
/// <returns>Shader information</returns>
|
/// <returns>Shader information</returns>
|
||||||
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
|
public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false)
|
||||||
{
|
{
|
||||||
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true);
|
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute);
|
||||||
|
|
||||||
|
builder.AddStageInfoVac(info2);
|
||||||
builder.AddStageInfo(info, vertexAsCompute: true);
|
builder.AddStageInfo(info, vertexAsCompute: true);
|
||||||
|
|
||||||
return builder.Build(null, fromCache);
|
return builder.Build(null, fromCache);
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user