Compare commits

..

61 Commits

Author SHA1 Message Date
Evan Husted
f07a9737db UI: Fix logo aliasing 2024-12-19 00:26:45 -06:00
GabCoolGuy
73638582c5 UI: Add faq, setup and multiplayer guides to the Help dropdown (#383) 2024-12-19 00:26:45 -06:00
Evan Husted
246b4bd555 Revamp README header 2024-12-19 00:26:45 -06:00
Evan Husted
c77dced809 Remove icon padding 2024-12-19 00:26:45 -06:00
Evan Husted
1e8235414f Logo from PR #381 everywhere 2024-12-19 00:26:45 -06:00
Matteo Forlani
fc41960fd3 New macOS icon (#381) 2024-12-19 00:26:45 -06:00
Evan Husted
26319ba487 fix changelogs in canary release 2024-12-19 00:26:45 -06:00
Daenorth
aeeeaca37c Norwegian Translation (#338) 2024-12-19 00:26:45 -06:00
Hack茶ん
8b3fa0011b Korean Former Maintainers & About description translations (#371) 2024-12-19 00:26:45 -06:00
rrondo
c4bfe7ec21 Some changes to Ukrainian localization (uk_UA.json) (#356)
I made some small corrections and translated the lines that didn’t have
translations.
2024-12-19 00:26:45 -06:00
GabCoolGuy
5b6449d916 infra: Add a table to the releases (#363)
This adds a table making it clearer what artifacts are needed for what
platform.

Nogui builds are not provided in the table as per Greem's request.

MAINTAINER EDIT: reasoning for above is due to the Headless in Avalonia
PR; nogui builds are going away.

Tested for both canary and release builds and everything works fine:


[Canary](https://github.com/GabCoolDude/Ryujinx-Canary/releases/tag/1.2.6)
[Release](https://github.com/GabCoolDude/Ryujinx/releases/tag/1.2.2)

For release, the damn appimage messed everything up, but thanks to
macOS, you can still test if it works.
2024-12-19 00:26:45 -06:00
Evan Husted
71646c3757 misc: chore: Simplify Updater version parsing. 2024-12-19 00:26:45 -06:00
Evan Husted
966ca60847 misc: chore: Collapse XCIFileTrimmerLog implementations into a single class. 2024-12-19 00:26:45 -06:00
Evan Husted
f1a222bb9a UI: Update About window with the current status of the project. 2024-12-19 00:26:45 -06:00
Evan Husted
8f789dd04c i18n: Clean out old translations and reset outdated ones 2024-12-19 00:26:45 -06:00
bangfire
f239ca2de0 Fix Windows Terminal hide/show functions (#342)
https://stackoverflow.com/a/78577080
2024-12-19 00:26:45 -06:00
Evan Husted
ac577e76a1 UI: Adapt accent color to the user's system.
https://amwx.github.io/FluentAvaloniaDocs/pages/FATheme/Accents#using-the-systems-accent-color
2024-12-19 00:26:45 -06:00
Evan Husted
04e6d44607 UI: Fix missing total DLC count.
Fixes #347.
2024-12-19 00:26:45 -06:00
Evan Husted
4f9cf2be6b Attempt #2 2024-12-19 00:26:45 -06:00
Evan Husted
44fcb4f5cd Try and fix nullref 2024-12-19 00:26:45 -06:00
Evan Husted
f838f00c04 HLE: extract custom NACP data functionality into a static helper for generic reuse elsewhere, and clarify magic numbers. 2024-12-19 00:26:45 -06:00
Evan Husted
0d369fc1da headless: Actually log the command line errors 2024-12-19 00:26:45 -06:00
Evan Husted
7c3e89c4f4 misc: chore: Cleanups & unused parameter removal 2024-12-19 00:26:45 -06:00
WilliamWsyHK
87394b8d4d Add Firmware keyword in log if it is indeed firmware (#343)
Co-authored-by: LotP1 <rasmus.stilling.pedersen1@gmail.com>
2024-12-19 00:26:45 -06:00
maxdlpee
b59d8f9e4e Update Spanish translation (#332)
- Added translations for XCI trimmer
- Added translations for Cabinet applet
- Added translations for Keys installer
- Other miscellaneous translations added
2024-12-19 00:26:45 -06:00
Luke Warner
468f6f782d Stub Ldn.Lp2p.ISfService: 776 (DestroyGroup) (#353)
This prevents a crash in Mario Kart Live: Home Circuit that would occur
after exiting the kart pairing screen.
2024-12-19 00:26:45 -06:00
Hack茶ん
aae92bbf15 Update Korean translation (#352) 2024-12-19 00:26:45 -06:00
Evan Husted
f23547d911 direct errored updates to ryujinx.app 2024-12-19 00:26:45 -06:00
Evan Husted
9573476db6 version 1.2 in Info.plist 2024-12-19 00:26:45 -06:00
Evan Husted
7f279cd4ed UI: Move Shader Compilation hint, graphics backend, and GPU manufacturer to the right side of the status bar, next to firmware version.
Removed the "Game:" prefix in front of FPS.
2024-12-19 00:26:45 -06:00
Evan Husted
cde38fb1c5 chore: applets: Cleanup redundant ReadStruct implementations & provide a default implementation for IApplet#GetResult. 2024-12-19 00:26:45 -06:00
Jacobwasbeast
164cf7ea7f Add the Cabinet Applet (#340)
This adds the missing Cabinet Applet, which allows for formatting
Amiibos and changing their names.
2024-12-19 00:26:45 -06:00
Luke Warner
29c4435791 ARMeilleure: Allow TPIDR2_EL0 to be set properly (#339) 2024-12-19 00:26:45 -06:00
Luke Warner
84cc3559f0 Implement and stub services required for Mario Kart Live: Home Circuit (#331)
These changes allow Mario Kart Live: Home Circuit (v2.0.0) to boot into
menus. Kart functionality has not been implemented and will not work.

Version 1.0.0 is currently unsupported due to unimplemented ARM
registers. I plan on addressing this issue at a later date.


### Here is a list of the implemented and stubbed services in this PR:
#### Implemented:
Ldn.Lp2p.IServiceCreator: 0 (CreateNetworkService)
Ldn.Lp2p.IServiceCreator: 8 (CreateNetworkServiceMonitor)
Ldn.Lp2p.ISfService: 0 (Initialize)
Ldn.Lp2p.ISfServiceMonitor: 0 (Initialize)
Ldn.Lp2p.ISfServiceMonitor: 256 (AttachNetworkInterfaceStateChangeEvent)
Ldn.Lp2p.ISfServiceMonitor: 328 (AttachJoinEvent)
#### Stubbed:
Ldn.Lp2p.ISfService: 768 (CreateGroup)
Ldn.Lp2p.ISfService: 1536 (SendToOtherGroup)
Ldn.Lp2p.ISfService: 1544 (RecvFromOtherGroup)
Ldn.Lp2p.ISfServiceMonitor: 288 (GetGroupInfo)
Ldn.Lp2p.ISfServiceMonitor: 296 (GetGroupInfo2)
Ldn.Lp2p.ISfServiceMonitor: 312 (GetIpConfig)
2024-12-19 00:26:45 -06:00
Piplup
1963cda121 Fix for missing text with specific system locale encoding (#330) 2024-12-19 00:26:45 -06:00
LotP1
b59b8ac943 JIT Sparse Function Table random crash fix (#319)
A couple of games have random crashing with the JIT Sparse Ftable changes, and it seems to have been caused by an insufficient int size returned by `AddressTableLevel#GetValue(ulong address)`.
It was 32 bits (Int32), but the GiantBlock (which is the current address table impl) uses potentially 36 bits for the first level.
2024-12-19 00:26:45 -06:00
Hack茶ん
b40cf692c8 Korean translation for key install tool (#329) 2024-12-19 00:26:45 -06:00
Nicola
fd2972ec84 Added Tool for installing keys (#233)
#232 

![image](https://github.com/user-attachments/assets/5ae6118d-3857-4005-8392-5398c8fa91d5)
2024-12-19 00:26:45 -06:00
Jonas Henriksson
9190796c62 Fix logic surrounding PushDescriptors in Vulkan (#257) 2024-12-19 00:26:45 -06:00
TheToid
08d2929ea0 ignore macos attribute files (#302) 2024-12-19 00:26:45 -06:00
Evan Husted
df6798cf7a UI: RPC: Add Diablo III 2024-12-19 00:26:45 -06:00
Luke Warner
484dc13314 Remove 'Enter' hotkey in settings menu (#95)
This allows the Enter key to be bound to a button when using the
Avalonia UI.
2024-12-19 00:26:45 -06:00
GabCoolGuy
bada08258e UI: Add Mii Edit Applet Locale (#311)
This allows the "Mii Edit Applet" dropdown to be localized ( I already
went ahead and localized French )
2024-12-19 00:26:45 -06:00
Hack茶ん
dc4ac64faf Korean "Show Changelog" translation (#313) 2024-12-19 00:26:45 -06:00
Keaton
67bb3dc2d9 Add custom refresh rate mode to VSync option (#238)
Rebased @jcm93's refreshinterval branch:
https://github.com/jcm93/Ryujinx/tree/refreshinterval

The option is placed under System/Hacks. Disabled, it's the default
Ryujinx behavior. Enabled, the behavior is shown in the attached
screenshots. If a framerate is too high or low, you can adjust the value
where you normally toggle VSync on and off. It will also cycle through
the default on/off toggles.

Also, in order to reduce clutter, I made an adjustment to remove the
target FPS and only show the percentage.

---------

Co-authored-by: jcm <6864788+jcm93@users.noreply.github.com>
2024-12-19 00:26:45 -06:00
GabCoolGuy
5e5b3aeaf1 UI: Fix icons getting cutoff in the About window (#310)
Before:


![image](https://github.com/user-attachments/assets/c8d6b7d5-487b-4ab9-83e3-9489eaa0a076)

After:


![image](https://github.com/user-attachments/assets/18ea6360-f6ee-48e6-9a0a-cd8d88a0cf51)
2024-12-19 00:26:45 -06:00
Daniel Zauner
84d340b4fb Fix window decorations being too wide (#309) 2024-12-19 00:26:45 -06:00
Evan Husted
ef7ce19867 UI: RPC: TSUKIHIME -A piece of blue glass moon- asset image 2024-12-19 00:26:45 -06:00
Evan Husted
394fabb8cc infra: Undo packing native libraries into executable. 2024-12-19 00:26:45 -06:00
LotP1
68525ab7f1 JIT Sparse Function Table (#250)
More up to date build of the JIT Sparse PR for continued development.
JIT Sparse Function Table was originally developed by riperiperi for the
original Ryujinx project, and decreased the amount of layers in the
Function Table structure, to decrease lookup times at the cost of
slightly higher RAM usage.
This PR rebalances the JIT Sparse Function Table to be a bit more RAM
intensive, but faster in workloads where the JIT Function Table is a
bottleneck. Faster RAM will see a bigger impact and slower RAM (DDR3 and
potentially slow DDR4) will see a slight performance decrease.
This PR also implements a base for a PPTC profile system that could
allow for PPTC with ExeFS mods enabled in the future.
This PR also potentially fixes a strange issue where Avalonia would time
out in some rare instances, e.g. when running ExeFS mods with TotK and a
strange controller configuration.

---------

Co-authored-by: Evan Husted <gr33m11@gmail.com>
2024-12-19 00:26:45 -06:00
Evan Husted
904d249dad UI: Always save screenshots to the Ryujinx data directory. 2024-12-19 00:26:45 -06:00
Evan Husted
413eb755cb UI: It's called "live testing." 2024-12-19 00:26:45 -06:00
Evan Husted
2ed3836093 UI: I may be stupid. Primary button result is Ok, not Yes. 2024-12-19 00:26:45 -06:00
Evan Husted
b5d5256c61 UI: Add a show changelog button in the Updater, for new updates & when you're on the latest version. 2024-12-19 00:26:45 -06:00
GabCoolGuy
32bfa06024 Add all the missing locales from XCI Trimmer and LDN merge (#281)
Hello any fellow developers that may be reading this. Whenever you add
any new locales to `en_US.json`, please make sure to add them to the
rest of the locale files. I will not always be there to add them myself.
2024-12-19 00:26:45 -06:00
GabCoolGuy
b31a8946ae Add more mentions of canary (#258)
This should hopefully make it clearer whether or not you're using
canary.

Changelog:
- Changed github workflows to have "canary" in the zip files
- Added `App.FullAppName` in the about section, so that it's clear in
there too
- Changed log name for canary builds to
`Ryujinx_Canary_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log`
(normal builds should still be
"Ryujinx_{version}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.log)
2024-12-19 00:26:45 -06:00
Evan Husted
0f85cadf28 Fix really obvious typo, lol 2024-12-19 00:26:45 -06:00
GabCoolGuy
4892e72907 Change headless to nogui in the release artifacts (#285)
This makes it so that instead of the files you download being
`sdl2-ryujinx-headless` they are now `nogui-ryujinx`in the release (and
canary) artifacts
2024-12-19 00:26:45 -06:00
GabCoolGuy
c565da03c5 Add documentation and ldn labels to labeler.yml (#282)
This should make it so that any changes made to ldn and documentation
related files should be auto-labeled
2024-12-19 00:26:45 -06:00
Luke Warner
0cf125a4d9 ARMeilleure: Implement TPIDR2_EL0 (#280)
This is an implementation of the TPIDR2_EL0 register. There may be more
potential use-cases for this register not included in this PR, but this
implements the use-case seen in SuperTuxKart.
2024-12-19 00:26:45 -06:00
Evan Husted
f8c53f03fd Try and fix weird nullref 2024-11-19 10:32:51 -06:00
498 changed files with 20505 additions and 41837 deletions

2
.github/labeler.yml vendored
View File

@@ -32,7 +32,7 @@ kernel:
infra: infra:
- changed-files: - changed-files:
- any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props', 'src/Ryujinx.BuildValidationTasks/**'] - any-glob-to-any-file: ['.github/**', 'distribution/**', 'Directory.Packages.props']
documentation: documentation:
- changed-files: - changed-files:

View File

@@ -64,9 +64,14 @@ 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
@@ -114,6 +119,13 @@ 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
@@ -159,9 +171,20 @@ 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'

View File

@@ -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: "Ryubing" RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx" RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO: "Ryujinx"
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Canary-Releases" RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "Ryujinx-Canary"
RELEASE: 1 RELEASE: 1
jobs: jobs:
@@ -43,8 +43,8 @@ jobs:
with: with:
script: | script: |
github.rest.git.createRef({ github.rest.git.createRef({
owner: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}", owner: context.repo.owner,
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}", repo: context.repo.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
}) })
@@ -61,10 +61,10 @@ jobs:
| Platform | Artifact | | 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) | | 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 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) | | 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) | | 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 }} **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
@@ -116,6 +116,7 @@ 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'
@@ -124,6 +125,11 @@ 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
@@ -134,6 +140,12 @@ 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,21 +191,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,release_output/*AppImage*" #artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }} tag: ${{ steps.version_info.outputs.build_version }}
body: | body: |
# Canary builds: # 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. These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact | | 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) | | Windows 64 bit | https://github.com/${{ github.repository }}/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 64 bit | https://github.com/${{ github.repository }}/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) | | Linux arm 64 bit | https://github.com/${{ github.repository }}/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) | | Macos | https://github.com/${{ github.repository }}/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 }} "**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
@@ -250,13 +262,29 @@ 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" artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }} tag: ${{ steps.version_info.outputs.build_version }}
body: "" body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/GreemDev/Ryujinx/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
| Macos | https://github.com/${{ github.repository }}/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/${{ github.repository }}/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

View File

@@ -37,17 +37,21 @@ jobs:
if (!artifacts.length) { if (!artifacts.length) {
return core.error(`No artifacts found`); return core.error(`No artifacts found`);
} }
let body = `*You need to be logged into GitHub to download these files.*\n\nDownload 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}](${url})`; hidden_debug_artifacts += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
} 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}](${url})`; body += `\n* [${art.name}](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`;
} }
} }
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});

View File

@@ -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: "Ryubing" RYUJINX_TARGET_RELEASE_CHANNEL_OWNER: "GreemDev"
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: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}", owner: context.repo.owner,
repo: "${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}", repo: context.repo.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
}) })
@@ -54,13 +54,13 @@ jobs:
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: | body: |
# Stable builds: # Regular builds:
| Platform | Artifact | | 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) | | Windows 64 bit | [Release 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 64 bit | [Release 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) | | Linux arm 64 bit | [Release 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) | | macOS | [Release 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 }} **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
@@ -112,6 +112,7 @@ 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'
@@ -120,6 +121,11 @@ 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)
@@ -166,6 +172,11 @@ 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
@@ -175,15 +186,15 @@ jobs:
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: | body: |
# Stable builds: # Regular builds:
| Platform | Artifact | | 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) | | Windows 64 bit | https://github.com/${{ github.repository }}/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 64 bit | https://github.com/${{ github.repository }}/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) | | Linux arm 64 bit | https://github.com/${{ github.repository }}/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) | | Macos | https://github.com/${{ github.repository }}/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 }} "**Full Changelog**: https://github.com/${{ github.repository }}/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
@@ -240,13 +251,26 @@ 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" artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }} tag: ${{ steps.version_info.outputs.build_version }}
body: "" body: |
# Regular builds:
| Platform | Artifact |
|--|--|
| Windows 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-win_x64.zip |
| Linux 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz |
| Linux arm 64 bit | https://github.com/${{ github.repository }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz |
| Macos | https://github.com/${{ github.repository }}/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/${{ github.repository }}/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

View File

@@ -5,7 +5,7 @@ If you wish to build the emulator yourself, follow these steps:
### Step 1 ### Step 1
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0). Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.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

View File

@@ -1,6 +0,0 @@
<Project>
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>

View File

@@ -10,14 +10,10 @@
<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"/>
<PackageVersion Include="CommandLineParser" Version="2.9.1" /> <PackageVersion Include="CommandLineParser" Version="2.9.1" />
<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.4.0"/>
<PackageVersion Include="Concentus" Version="2.2.0" /> <PackageVersion Include="Concentus" Version="2.2.0" />
<PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" /> <PackageVersion Include="DiscordRichPresence" Version="1.2.1.24" />
<PackageVersion Include="DynamicData" Version="9.0.4" /> <PackageVersion Include="DynamicData" Version="9.0.4" />
@@ -42,10 +38,9 @@
<PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" /> <PackageVersion Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.3-build14" />
<PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" /> <PackageVersion Include="Ryujinx.Graphics.Vulkan.Dependencies.MoltenVK" Version="1.2.0" />
<PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" /> <PackageVersion Include="Ryujinx.SDL2-CS" Version="2.30.0-build32" />
<PackageVersion Include="Gommon" Version="2.7.0.1" /> <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" />
@@ -53,8 +48,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="9.0.0" /> <PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="System.Management" Version="9.0.0" /> <PackageVersion Include="System.Management" Version="8.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>

View File

@@ -54,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).
@@ -82,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!

View File

@@ -57,10 +57,14 @@ 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}"
@@ -77,22 +81,13 @@ 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
@@ -209,6 +204,10 @@ 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
@@ -217,6 +216,10 @@ 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
@@ -249,16 +252,6 @@ 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
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C08931FA-1191-417A-864F-3882D93E683B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C08931FA-1191-417A-864F-3882D93E683B}.Release|Any CPU.Build.0 = Release|Any CPU
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4A89A234-4F19-497D-A576-DDE8CDFC5B22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81EA598C-DBA1-40B0-8DA4-4796B78F2037}.Release|Any CPU.ActiveCfg = Release|Any CPU
{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

View File

@@ -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 distribution/misc/Logo.svg AppDir/Ryujinx.svg cp src/Ryujinx.UI.Common/Resources/Logo_Ryujinx.png AppDir/Ryujinx.svg
cp -r "$BUILDDIR"/* AppDir/usr/bin/ cp -r "$BUILDDIR"/* AppDir/usr/bin/

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -1,6 +1,6 @@
{ {
"sdk": { "sdk": {
"version": "9.0.100", "version": "8.0.100",
"rollForward": "latestFeature" "rollForward": "latestFeature"
} }
} }

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -1,5 +1,4 @@
using ARMeilleure.Common; using ARMeilleure.Common;
using System;
namespace ARMeilleure.Decoders namespace ARMeilleure.Decoders
{ {
@@ -150,7 +149,7 @@ namespace ARMeilleure.Decoders
return (((long)opCode << 45) >> 48) & ~3; return (((long)opCode << 45) >> 48) & ~3;
} }
public static bool VectorArgumentsInvalid(bool q, params ReadOnlySpan<int> args) public static bool VectorArgumentsInvalid(bool q, params int[] args)
{ {
if (q) if (q)
{ {

View File

@@ -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 ReadOnlySpan<V128> tb) private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params V128[] tb)
{ {
byte[] res = new byte[16]; byte[] res = new byte[16];

View File

@@ -337,7 +337,7 @@ namespace ARMeilleure.IntermediateRepresentation
return result; return result;
} }
public static Operation Operation(Intrinsic intrin, Operand dest, params ReadOnlySpan<Operand> srcs) public static Operation Operation(Intrinsic intrin, Operand dest, params Operand[] srcs)
{ {
Operation result = Make(Instruction.Extended, 0, srcs.Length); Operation result = Make(Instruction.Extended, 0, srcs.Length);

View File

@@ -8,7 +8,6 @@ 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
{ {
@@ -27,7 +26,7 @@ namespace ARMeilleure.Translation.Cache
private static readonly List<CacheEntry> _cacheEntries = new(); private static readonly List<CacheEntry> _cacheEntries = new();
private static readonly Lock _lock = new(); private static readonly object _lock = new();
private static bool _initialized; private static bool _initialized;
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]

View File

@@ -559,27 +559,27 @@ namespace ARMeilleure.Translation
return dest; return dest;
} }
public Operand AddIntrinsic(Intrinsic intrin, params ReadOnlySpan<Operand> args) public Operand AddIntrinsic(Intrinsic intrin, params Operand[] args)
{ {
return Add(intrin, Local(OperandType.V128), args); return Add(intrin, Local(OperandType.V128), args);
} }
public Operand AddIntrinsicInt(Intrinsic intrin, params ReadOnlySpan<Operand> args) public Operand AddIntrinsicInt(Intrinsic intrin, params Operand[] args)
{ {
return Add(intrin, Local(OperandType.I32), args); return Add(intrin, Local(OperandType.I32), args);
} }
public Operand AddIntrinsicLong(Intrinsic intrin, params ReadOnlySpan<Operand> args) public Operand AddIntrinsicLong(Intrinsic intrin, params Operand[] args)
{ {
return Add(intrin, Local(OperandType.I64), args); return Add(intrin, Local(OperandType.I64), args);
} }
public void AddIntrinsicNoRet(Intrinsic intrin, params ReadOnlySpan<Operand> args) public void AddIntrinsicNoRet(Intrinsic intrin, params Operand[] args)
{ {
Add(intrin, default, args); Add(intrin, default, args);
} }
private Operand Add(Intrinsic intrin, Operand dest, params ReadOnlySpan<Operand> sources) private Operand Add(Intrinsic intrin, Operand dest, params Operand[] sources)
{ {
NewNextBlockIfNeeded(); NewNextBlockIfNeeded();

View File

@@ -59,7 +59,7 @@ namespace ARMeilleure.Translation.PTC
private readonly ManualResetEvent _waitEvent; private readonly ManualResetEvent _waitEvent;
private readonly Lock _lock = new(); private readonly object _lock;
private bool _disposed; private bool _disposed;
@@ -89,6 +89,8 @@ namespace ARMeilleure.Translation.PTC
_waitEvent = new ManualResetEvent(true); _waitEvent = new ManualResetEvent(true);
_lock = new object();
_disposed = false; _disposed = false;
TitleIdText = TitleIdTextDefault; TitleIdText = TitleIdTextDefault;

View File

@@ -1,5 +1,4 @@
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;
@@ -42,7 +41,7 @@ namespace ARMeilleure.Translation.PTC
private readonly ManualResetEvent _waitEvent; private readonly ManualResetEvent _waitEvent;
private readonly Lock _lock = new(); private readonly object _lock;
private bool _disposed; private bool _disposed;
@@ -59,13 +58,15 @@ namespace ARMeilleure.Translation.PTC
{ {
_ptc = ptc; _ptc = ptc;
_timer = new Timer(SaveInterval.Seconds()); _timer = new Timer(SaveInterval * 1000d);
_timer.Elapsed += TimerElapsed; _timer.Elapsed += PreSave;
_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>();
@@ -73,9 +74,6 @@ 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))
@@ -266,7 +264,7 @@ namespace ARMeilleure.Translation.PTC
compressedStream.SetLength(0L); compressedStream.SetLength(0L);
} }
private void PreSave() private void PreSave(object source, ElapsedEventArgs e)
{ {
_waitEvent.Reset(); _waitEvent.Reset();
@@ -432,7 +430,7 @@ namespace ARMeilleure.Translation.PTC
{ {
_disposed = true; _disposed = true;
_timer.Elapsed -= TimerElapsed; _timer.Elapsed -= PreSave;
_timer.Dispose(); _timer.Dispose();
Wait(); Wait();

View File

@@ -5,7 +5,6 @@ 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
{ {
@@ -19,7 +18,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
private ulong _playedSampleCount; private ulong _playedSampleCount;
private float _volume; private float _volume;
private readonly Lock _lock = new(); private readonly object _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)
{ {

View File

@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -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 Lock _lock = new(); private readonly object _lock = new();
/// <summary> /// <summary>
/// Events signaled when the driver played audio buffers. /// Events signaled when the driver played audio buffers.

View File

@@ -2,7 +2,6 @@ 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
{ {
@@ -13,7 +12,7 @@ namespace Ryujinx.Audio.Backends.Common
{ {
private const int RingBufferAlignment = 2048; private const int RingBufferAlignment = 2048;
private readonly Lock _lock = new(); private readonly object _lock = new();
private MemoryOwner<byte> _bufferOwner; private MemoryOwner<byte> _bufferOwner;
private Memory<byte> _buffer; private Memory<byte> _buffer;

View File

@@ -9,12 +9,20 @@ namespace Ryujinx.Audio.Backends.Dummy
{ {
public class DummyHardwareDeviceDriver : IHardwareDeviceDriver public class DummyHardwareDeviceDriver : IHardwareDeviceDriver
{ {
private readonly ManualResetEvent _updateRequiredEvent = new(false); private readonly ManualResetEvent _updateRequiredEvent;
private readonly ManualResetEvent _pauseEvent = new(true); private readonly ManualResetEvent _pauseEvent;
public static bool IsSupported => true; public static bool IsSupported => true;
public float Volume { get; set; } = 1f; public float Volume { get; set; }
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)
{ {
@@ -52,7 +60,7 @@ namespace Ryujinx.Audio.Backends.Dummy
Dispose(true); Dispose(true);
} }
private void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if (disposing) if (disposing)
{ {

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Input
/// </summary> /// </summary>
public class AudioInputManager : IDisposable public class AudioInputManager : IDisposable
{ {
private readonly Lock _lock = new(); private readonly object _lock = new();
/// <summary> /// <summary>
/// Lock used for session allocation. /// Lock used for session allocation.
/// </summary> /// </summary>
private readonly Lock _sessionLock = new(); private readonly object _sessionLock = new();
/// <summary> /// <summary>
/// The session ids allocation table. /// The session ids allocation table.

View File

@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
/// <summary> /// <summary>
/// The lock of the parent. /// The lock of the parent.
/// </summary> /// </summary>
private readonly Lock _parentLock; private readonly object _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, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent) public AudioInputSystem(AudioInputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
{ {
_manager = manager; _manager = manager;
_parentLock = parentLock; _parentLock = parentLock;

View File

@@ -14,12 +14,12 @@ namespace Ryujinx.Audio.Output
/// </summary> /// </summary>
public class AudioOutputManager : IDisposable public class AudioOutputManager : IDisposable
{ {
private readonly Lock _lock = new(); private readonly object _lock = new();
/// <summary> /// <summary>
/// Lock used for session allocation. /// Lock used for session allocation.
/// </summary> /// </summary>
private readonly Lock _sessionLock = new(); private readonly object _sessionLock = new();
/// <summary> /// <summary>
/// The session ids allocation table. /// The session ids allocation table.

View File

@@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
/// <summary> /// <summary>
/// THe lock of the parent. /// THe lock of the parent.
/// </summary> /// </summary>
private readonly Lock _parentLock; private readonly object _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, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent) public AudioOutputSystem(AudioOutputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
{ {
_manager = manager; _manager = manager;
_parentLock = parentLock; _parentLock = parentLock;

View File

@@ -26,7 +26,7 @@ namespace Ryujinx.Audio.Renderer.Server
{ {
public class AudioRenderSystem : IDisposable public class AudioRenderSystem : IDisposable
{ {
private readonly Lock _lock = new(); private readonly object _lock = new();
private AudioRendererRenderingDevice _renderingDevice; private AudioRendererRenderingDevice _renderingDevice;
private AudioRendererExecutionMode _executionMode; private AudioRendererExecutionMode _executionMode;

View File

@@ -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 Lock _sessionLock = new(); private readonly object _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 Lock _audioProcessorLock = new(); private readonly object _audioProcessorLock = new();
/// <summary> /// <summary>
/// The session ids allocation table. /// The session ids allocation table.

View File

@@ -1,6 +1,5 @@
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
{ {
@@ -17,7 +16,7 @@ namespace Ryujinx.Audio.Renderer.Server.Upsampler
/// <summary> /// <summary>
/// Global lock of the object. /// Global lock of the object.
/// </summary> /// </summary>
private readonly Lock _lock = new(); private readonly object _lock = new();
/// <summary> /// <summary>
/// The upsamplers instances. /// The upsamplers instances.

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -1,7 +0,0 @@
namespace Ryujinx.BuildValidationTasks
{
public interface IValidationTask
{
public bool Execute(string projectPath, bool isGitRunner);
}
}

View File

@@ -1,117 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text.Json;
using System.Text.Encodings.Web;
namespace Ryujinx.BuildValidationTasks
{
public class LocalesValidationTask : IValidationTask
{
public LocalesValidationTask() { }
public bool Execute(string projectPath, bool isGitRunner)
{
Console.WriteLine("Running Locale Validation Task...");
string path = projectPath + "src/Ryujinx/Assets/locales.json";
string data;
using (StreamReader sr = new(path))
{
data = sr.ReadToEnd();
}
LocalesJson json;
if (isGitRunner && data.Contains("\r\n"))
throw new FormatException("locales.json is using CRLF line endings! It should be using LF line endings, build locally to fix...");
try
{
json = JsonSerializer.Deserialize<LocalesJson>(data);
}
catch (JsonException e)
{
throw new JsonException(e.Message); //shorter and easier stacktrace
}
bool encounteredIssue = false;
for (int i = 0; i < json.Locales.Count; i++)
{
LocalesEntry locale = json.Locales[i];
foreach (string langCode in json.Languages.Where(lang => !locale.Translations.ContainsKey(lang)))
{
encounteredIssue = true;
if (!isGitRunner)
{
locale.Translations.Add(langCode, string.Empty);
Console.WriteLine($"Added '{langCode}' to Locale '{locale.ID}'");
}
else
{
Console.WriteLine($"Missing '{langCode}' in Locale '{locale.ID}'!");
}
}
foreach (string langCode in json.Languages.Where(lang => locale.Translations.ContainsKey(lang) && lang != "en_US" && locale.Translations[lang] == locale.Translations["en_US"]))
{
encounteredIssue = true;
if (!isGitRunner)
{
locale.Translations[langCode] = string.Empty;
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'! Resetting it...");
}
else
{
Console.WriteLine($"Lanugage '{langCode}' is a duplicate of en_US in Locale '{locale.ID}'!");
}
}
locale.Translations = locale.Translations.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
json.Locales[i] = locale;
}
if (isGitRunner && encounteredIssue)
throw new JsonException("1 or more locales are invalid!");
JsonSerializerOptions jsonOptions = new JsonSerializerOptions()
{
WriteIndented = true,
NewLine = "\n",
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
};
string jsonString = JsonSerializer.Serialize(json, jsonOptions);
using (StreamWriter sw = new(path))
{
sw.Write(jsonString);
}
Console.WriteLine("Finished Locale Validation Task!");
return true;
}
struct LocalesJson
{
public List<string> Languages { get; set; }
public List<LocalesEntry> Locales { get; set; }
}
struct LocalesEntry
{
public string ID { get; set; }
public Dictionary<string, string> Translations { get; set; }
}
}
}

View File

@@ -1,37 +0,0 @@
using System;
using System.IO;
using System.Linq;
namespace Ryujinx.BuildValidationTasks
{
public class Program
{
static void Main(string[] args)
{
// Display the number of command line arguments.
if (args.Length == 0)
throw new ArgumentException("Error: too few arguments!");
string path = args[0];
if (string.IsNullOrEmpty(path))
throw new ArgumentException("Error: path is null or empty!");
if (!Path.Exists(path))
throw new FileLoadException($"path {{{path}}} does not exist!");
path = Path.GetFullPath(path);
if (!Directory.GetDirectories(path).Contains($"{path}src"))
throw new FileLoadException($"path {{{path}}} is not a valid ryujinx project!");
bool isGitRunner = path.Contains("runner") || path.Contains("D:\\a\\Ryujinx\\Ryujinx");
if (isGitRunner)
Console.WriteLine("Is Git Runner!");
// Run tasks
// Pass extra info needed in the task constructors
new LocalesValidationTask().Execute(path, isGitRunner);
}
}
}

View File

@@ -1,17 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
</PropertyGroup>
<Target Name="PostBuildTarget" AfterTargets="AfterBuild">
<Message Text="Running Validation Project" Importance="high" />
<Exec WorkingDirectory="$(ProjectDir)bin\Debug\$(TargetFramework)\"
Command="dotnet Ryujinx.BuildValidationTasks.dll &quot;$(ProjectDir)..\..\\&quot;"
ConsoleToMsBuild="true"
Condition="'$(RuntimeIdentifier)' == ''"
/>
</Target>
</Project>

View File

@@ -35,8 +35,6 @@ 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)
{ {

View File

@@ -1,60 +0,0 @@
using Gommon;
using System;
using System.Collections.Generic;
using System.Linq;
namespace Ryujinx.Common.Configuration
{
[Flags]
public enum DirtyHack : byte
{
Xc2MenuSoftlockFix = 1,
ShaderTranslationDelay = 2
}
public readonly struct EnabledDirtyHack(DirtyHack hack, int value)
{
public DirtyHack Hack => hack;
public int Value => value;
public ulong Pack() => Raw.PackBitFields(PackedFormat);
public static EnabledDirtyHack Unpack(ulong packedHack)
{
var unpackedFields = packedHack.UnpackBitFields(PackedFormat);
if (unpackedFields is not [var hack, var value])
throw new ArgumentException(nameof(packedHack));
return new EnabledDirtyHack((DirtyHack)hack, (int)value);
}
private uint[] Raw => [(uint)Hack, (uint)Value.CoerceAtLeast(0)];
public static readonly byte[] PackedFormat = [8, 32];
}
public class DirtyHacks : Dictionary<DirtyHack, int>
{
public DirtyHacks(IEnumerable<EnabledDirtyHack> hacks)
=> hacks.ForEach(edh => Add(edh.Hack, edh.Value));
public DirtyHacks(ulong[] packedHacks) : this(packedHacks.Select(EnabledDirtyHack.Unpack)) {}
public ulong[] PackEntries()
=> Entries.Select(it => it.Pack()).ToArray();
public EnabledDirtyHack[] Entries
=> this
.Select(it => new EnabledDirtyHack(it.Key, it.Value))
.ToArray();
public static implicit operator DirtyHacks(EnabledDirtyHack[] hacks) => new(hacks);
public static implicit operator DirtyHacks(ulong[] packedHacks) => new(packedHacks);
public new int this[DirtyHack hack] => TryGetValue(hack, out var value) ? value : -1;
public bool IsEnabled(DirtyHack hack) => ContainsKey(hack);
}
}

View File

@@ -6,9 +6,7 @@ namespace Ryujinx.Common.Configuration
[JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))] [JsonConverter(typeof(TypedStringEnumConverter<GraphicsBackend>))]
public enum GraphicsBackend public enum GraphicsBackend
{ {
Auto,
Vulkan, Vulkan,
OpenGl, OpenGl,
Metal
} }
} }

View File

@@ -9,6 +9,5 @@ namespace Ryujinx.Common.Configuration
Bilinear, Bilinear,
Nearest, Nearest,
Fsr, Fsr,
Area,
} }
} }

View File

@@ -8,10 +8,10 @@ namespace Ryujinx.Common
public static class StreamExtensions public static class StreamExtensions
{ {
/// <summary> /// <summary>
/// Writes an int span to this stream. /// Writes a <see cref="ReadOnlySpan{int}" /> 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 <see cref="Stream.Write(ReadOnlySpan{byte})" />. /// byte array, then writes it to the Stream using <cref="System.Stream.Write(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>

View File

@@ -4,7 +4,6 @@ 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;
@@ -158,16 +157,21 @@ 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;

View File

@@ -27,7 +27,11 @@ namespace Ryujinx.Common.Logging.Targets
private readonly int _overflowTimeout; private readonly int _overflowTimeout;
string ILogTarget.Name => _target.Name; string ILogTarget.Name { get => _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)
{ {

View File

@@ -124,7 +124,7 @@ namespace Ryujinx.Common.PreciseSleep
} }
} }
private readonly Lock _lock = new(); private readonly object _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();

View File

@@ -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 Lock _lock = new(); private readonly object _lock = new();
private readonly List<WaitingObject> _waitingObjects = new(); private readonly List<WaitingObject> _waitingObjects = new();
private WindowsGranularTimer() private WindowsGranularTimer()

View File

@@ -53,9 +53,6 @@ namespace Ryujinx.Common
{ {
public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName) public static void LogValueChange<T>(LogClass logClass, ReactiveEventArgs<T> eventArgs, string valueName)
{ {
if (eventArgs.AreValuesEqual)
return;
string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}"); string message = string.Create(CultureInfo.InvariantCulture, $"{valueName} set to: {eventArgs.NewValue}");
Logger.Info?.Print(logClass, message); Logger.Info?.Print(logClass, message);
@@ -68,22 +65,5 @@ namespace Ryujinx.Common
{ {
public T OldValue { get; } = oldValue; public T OldValue { get; } = oldValue;
public T NewValue { get; } = newValue; public T NewValue { get; } = newValue;
public bool AreValuesEqual
{
get
{
if (OldValue == null && NewValue == null)
return true;
if (OldValue == null && NewValue != null)
return false;
if (OldValue != null && NewValue == null)
return false;
return OldValue!.Equals(NewValue);
}
}
} }
} }

View File

@@ -6,6 +6,7 @@ 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";
@@ -28,6 +29,8 @@ 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);

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -40,35 +40,5 @@ namespace Ryujinx.Common
return (value >> 32) | (value << 32); return (value >> 32) | (value << 32);
} }
// Never actually written bit packing logic before, so I looked it up.
// This code is from https://gist.github.com/Alan-FGR/04938e93e2bffdf5802ceb218a37c195
public static ulong PackBitFields(this uint[] values, byte[] bitFields)
{
ulong retVal = values[0]; //we set the first value right away
for (int f = 1; f < values.Length; f++)
{
retVal <<= bitFields[f]; // we shift the previous value
retVal += values[f];// and add our current value
}
return retVal;
}
public static uint[] UnpackBitFields(this ulong packed, byte[] bitFields)
{
int fields = bitFields.Length - 1; // number of fields to unpack
uint[] retArr = new uint[fields + 1]; // init return array
int curPos = 0; // current field bit position (start)
int lastEnd; // position where last field ended
for (int f = fields; f >= 0; f--) // loop from last
{
lastEnd = curPos; // we store where the last value ended
curPos += bitFields[f]; // we get where the current value starts
int leftShift = 64 - curPos; // we figure how much left shift we gotta apply for the other numbers to overflow into oblivion
retArr[f] = (uint)((packed << leftShift) >> leftShift + lastEnd); // we do magic
}
return retArr;
}
} }
} }

View File

@@ -1,4 +1,3 @@
using System;
using System.IO; using System.IO;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;
@@ -28,14 +27,9 @@ namespace Ryujinx.Common.Utilities
ReadCommentHandling = JsonCommentHandling.Skip ReadCommentHandling = JsonCommentHandling.Skip
}; };
public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) public static string Serialize<T>(T value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Serialize(value, typeInfo);
=> JsonSerializer.Serialize(value, typeInfo);
public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) public static T Deserialize<T>(string value, JsonTypeInfo<T> typeInfo) => JsonSerializer.Deserialize(value, 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)
{ {

View File

@@ -230,20 +230,25 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (size == 0) if (size == 0)
{ {
yield break; return Enumerable.Empty<HostMemoryRange>();
} }
var guestRegions = GetPhysicalRegionsImpl(va, size); var guestRegions = GetPhysicalRegionsImpl(va, size);
if (guestRegions == null) if (guestRegions == null)
{ {
yield break; return null;
} }
foreach (var guestRegion in guestRegions) var regions = new HostMemoryRange[guestRegions.Count];
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);
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size); regions[i] = new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
} }
return regions;
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -251,24 +256,23 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (size == 0) if (size == 0)
{ {
yield break; return Enumerable.Empty<MemoryRange>();
} }
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size)) return GetPhysicalRegionsImpl(va, size);
{
yield return physicalRegion;
}
} }
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size) private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
{ {
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size)) if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
{ {
yield break; return null;
} }
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;
@@ -276,14 +280,14 @@ namespace Ryujinx.Cpu.AppleHv
{ {
if (!ValidateAddress(va + PageSize)) if (!ValidateAddress(va + PageSize))
{ {
yield break; return null;
} }
ulong newPa = GetPhysicalAddressInternal(va + PageSize); ulong newPa = GetPhysicalAddressInternal(va + PageSize);
if (GetPhysicalAddressInternal(va) + PageSize != newPa) if (GetPhysicalAddressInternal(va) + PageSize != newPa)
{ {
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
regionStart = newPa; regionStart = newPa;
regionSize = 0; regionSize = 0;
} }
@@ -292,7 +296,9 @@ namespace Ryujinx.Cpu.AppleHv
regionSize += PageSize; regionSize += PageSize;
} }
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
return regions;
} }
/// <remarks> /// <remarks>

View File

@@ -1,7 +1,6 @@
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
{ {
@@ -13,7 +12,7 @@ namespace Ryujinx.Cpu.AppleHv
private static int _addressSpaces; private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator; private static HvIpaAllocator _ipaAllocator;
private static readonly Lock _lock = new(); private static readonly object _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block) public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{ {

View File

@@ -115,9 +115,6 @@ 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)
@@ -177,9 +174,6 @@ 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(

View File

@@ -250,20 +250,25 @@ namespace Ryujinx.Cpu.Jit
{ {
if (size == 0) if (size == 0)
{ {
yield break; return Enumerable.Empty<HostMemoryRange>();
} }
var guestRegions = GetPhysicalRegionsImpl(va, size); var guestRegions = GetPhysicalRegionsImpl(va, size);
if (guestRegions == null) if (guestRegions == null)
{ {
yield break; return null;
} }
foreach (var guestRegion in guestRegions) var regions = new HostMemoryRange[guestRegions.Count];
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);
yield return new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size); regions[i] = new HostMemoryRange((nuint)(ulong)pointer, guestRegion.Size);
} }
return regions;
} }
/// <inheritdoc/> /// <inheritdoc/>
@@ -271,24 +276,23 @@ namespace Ryujinx.Cpu.Jit
{ {
if (size == 0) if (size == 0)
{ {
yield break; return Enumerable.Empty<MemoryRange>();
} }
foreach (var physicalRegion in GetPhysicalRegionsImpl(va, size)) return GetPhysicalRegionsImpl(va, size);
{
yield return physicalRegion;
}
} }
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size) private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
{ {
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size)) if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
{ {
yield break; return null;
} }
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;
@@ -296,14 +300,14 @@ namespace Ryujinx.Cpu.Jit
{ {
if (!ValidateAddress(va + PageSize)) if (!ValidateAddress(va + PageSize))
{ {
yield break; return null;
} }
ulong newPa = GetPhysicalAddressInternal(va + PageSize); ulong newPa = GetPhysicalAddressInternal(va + PageSize);
if (GetPhysicalAddressInternal(va) + PageSize != newPa) if (GetPhysicalAddressInternal(va) + PageSize != newPa)
{ {
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
regionStart = newPa; regionStart = newPa;
regionSize = 0; regionSize = 0;
} }
@@ -312,7 +316,9 @@ namespace Ryujinx.Cpu.Jit
regionSize += PageSize; regionSize += PageSize;
} }
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
return regions;
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -475,15 +475,17 @@ namespace Ryujinx.Cpu.Jit
return GetPhysicalRegionsImpl(va, size); return GetPhysicalRegionsImpl(va, size);
} }
private IEnumerable<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size) private List<MemoryRange> GetPhysicalRegionsImpl(ulong va, ulong size)
{ {
if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size)) if (!ValidateAddress(va) || !ValidateAddressAndSize(va, size))
{ {
yield break; return null;
} }
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;
@@ -491,14 +493,14 @@ namespace Ryujinx.Cpu.Jit
{ {
if (!ValidateAddress(va + PageSize)) if (!ValidateAddress(va + PageSize))
{ {
yield break; return null;
} }
ulong newPa = GetPhysicalAddressInternal(va + PageSize); ulong newPa = GetPhysicalAddressInternal(va + PageSize);
if (GetPhysicalAddressInternal(va) + PageSize != newPa) if (GetPhysicalAddressInternal(va) + PageSize != newPa)
{ {
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
regionStart = newPa; regionStart = newPa;
regionSize = 0; regionSize = 0;
} }
@@ -507,7 +509,9 @@ namespace Ryujinx.Cpu.Jit
regionSize += PageSize; regionSize += PageSize;
} }
yield return new MemoryRange(regionStart, regionSize); regions.Add(new MemoryRange(regionStart, regionSize));
return regions;
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -478,7 +478,7 @@ namespace Ryujinx.Cpu.LightningJit.Arm32.Target.Arm64
bool skipContext, bool skipContext,
int spillBaseOffset, int spillBaseOffset,
int? resultRegister, int? resultRegister,
params ReadOnlySpan<ulong> callArgs) params ulong[] callArgs)
{ {
uint resultMask = 0u; uint resultMask = 0u;

View File

@@ -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 ReadOnlySpan<ulong> callArgs) params ulong[] callArgs)
{ {
uint resultMask = 0u; uint resultMask = 0u;

View File

@@ -5,7 +5,6 @@ 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
{ {
@@ -24,7 +23,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
private static readonly List<CacheEntry> _cacheEntries = new(); private static readonly List<CacheEntry> _cacheEntries = new();
private static readonly Lock _lock = new(); private static readonly object _lock = new();
private static bool _initialized; private static bool _initialized;
[SupportedOSPlatform("windows")] [SupportedOSPlatform("windows")]

View File

@@ -4,7 +4,6 @@ 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
{ {
@@ -105,7 +104,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 Lock _lock = new(); private readonly object _lock;
class ThreadLocalCacheEntry class ThreadLocalCacheEntry
{ {
@@ -138,6 +137,7 @@ 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)

View File

@@ -8,6 +8,8 @@ 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);
@@ -18,9 +20,11 @@ namespace Ryujinx.Cpu.LightningJit.CodeGen.Arm64
break; break;
} }
yield return (ulong)functionPointer - 4; functionPointers.Add((ulong)functionPointer - 4);
framePointer = Marshal.ReadIntPtr(framePointer); framePointer = Marshal.ReadIntPtr(framePointer);
} }
return functionPointers;
} }
} }
} }

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -5,7 +5,6 @@ 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
{ {
@@ -60,7 +59,7 @@ namespace Ryujinx.Cpu.Signal
private static MemoryBlock _codeBlock; private static MemoryBlock _codeBlock;
private static readonly Lock _lock = new(); private static readonly object _lock = new();
private static bool _initialized; private static bool _initialized;
static NativeSignalHandler() static NativeSignalHandler()

View File

@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup> </PropertyGroup>

View File

@@ -0,0 +1,12 @@
namespace Ryujinx.Graphics.GAL
{
public enum AntiAliasing
{
None,
Fxaa,
SmaaLow,
SmaaMedium,
SmaaHigh,
SmaaUltra,
}
}

View File

@@ -1,18 +0,0 @@
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;
}
}
}

View File

@@ -339,84 +339,6 @@ 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>

View File

@@ -1,4 +1,3 @@
using Ryujinx.Common.Configuration;
using System; using System;
namespace Ryujinx.Graphics.GAL namespace Ryujinx.Graphics.GAL

View File

@@ -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 Lock _interruptLock = new(); private readonly object _interruptLock = new();
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured; public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;

View File

@@ -1,4 +1,3 @@
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;

View File

@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup> </PropertyGroup>

View File

@@ -4,22 +4,23 @@ 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( public ShaderInfo(int fragmentOutputMap, ResourceLayout resourceLayout, ProgramPipelineState state, bool fromCache = false)
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;
}
} }
} }

View File

@@ -0,0 +1,10 @@
namespace Ryujinx.Graphics.GAL
{
public enum ScalingFilter
{
Bilinear,
Nearest,
Fsr,
Area,
}
}

View File

@@ -0,0 +1,9 @@
namespace Ryujinx.Graphics.GAL
{
public enum VSyncMode
{
Switch,
Unbounded,
Custom
}
}

View File

@@ -11,6 +11,8 @@ 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>
@@ -46,7 +48,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed.ComputeDraw
1, 1,
1, 1,
1, 1,
format.GetBytesPerElement(), 1,
format, format,
DepthStencilMode.Depth, DepthStencilMode.Depth,
Target.TextureBuffer, Target.TextureBuffer,
@@ -519,6 +521,21 @@ 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>

View File

@@ -147,6 +147,7 @@ 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;
} }
@@ -162,12 +163,15 @@ 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();
@@ -341,6 +345,20 @@ 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>

View File

@@ -1,5 +1,4 @@
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;
@@ -91,13 +90,6 @@ namespace Ryujinx.Graphics.Gpu
/// Support buffer updater. /// Support buffer updater.
/// </summary> /// </summary>
internal SupportBufferUpdater SupportBufferUpdater { get; } internal SupportBufferUpdater SupportBufferUpdater { get; }
/// <summary>
/// Enabled dirty hacks.
/// Used for workarounds to emulator bugs we can't fix/don't know how to fix yet.
/// </summary>
internal DirtyHacks DirtyHacks { get; }
/// <summary> /// <summary>
/// Host hardware capabilities. /// Host hardware capabilities.
@@ -121,7 +113,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, DirtyHacks hacks) public GpuContext(IRenderer renderer)
{ {
Renderer = renderer; Renderer = renderer;
@@ -144,8 +136,6 @@ namespace Ryujinx.Graphics.Gpu
SupportBufferUpdater = new SupportBufferUpdater(renderer); SupportBufferUpdater = new SupportBufferUpdater(renderer);
DirtyHacks = hacks;
_firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds); _firstTimestamp = ConvertNanosecondsToTicks((ulong)PerformanceCounter.ElapsedNanoseconds);
} }

View File

@@ -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.

View File

@@ -8,7 +8,6 @@ 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
@@ -999,7 +998,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{ {
bool dataOverlaps = texture.DataOverlaps(overlap, compatibility); bool dataOverlaps = texture.DataOverlaps(overlap, compatibility);
if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Any(incompatible => incompatible.Group == overlap.Group)) if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Exists(incompatible => incompatible.Group == overlap.Group))
{ {
incompatibleOverlaps.Add(new TextureIncompatibleOverlap(overlap.Group, compatibility)); incompatibleOverlaps.Add(new TextureIncompatibleOverlap(overlap.Group, compatibility));
} }

View File

@@ -7,7 +7,6 @@ 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
@@ -1556,7 +1555,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.Any(overlap => overlap.Group == other.Group)) if (!_incompatibleOverlaps.Exists(overlap => overlap.Group == other.Group))
{ {
if (copy && other.Compatibility == TextureViewCompatibility.LayoutIncompatible) if (copy && other.Compatibility == TextureViewCompatibility.LayoutIncompatible)
{ {
@@ -1702,4 +1701,3 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
} }
} }

View File

@@ -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 ReadOnlySpan<SwizzleComponent> components) private static DepthStencilMode GetDepthStencilMode(Format format, params 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).

View File

@@ -2,7 +2,6 @@ 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
{ {
@@ -77,7 +76,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
private BufferMigration _source; private BufferMigration _source;
private BufferModifiedRangeList _migrationTarget; private BufferModifiedRangeList _migrationTarget;
private readonly Lock _lock = new(); private readonly object _lock = new();
/// <summary> /// <summary>
/// Whether the modified range list has any entries or not. /// Whether the modified range list has any entries or not.
@@ -436,7 +435,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);

View File

@@ -1,6 +1,7 @@
<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>

View File

@@ -324,11 +324,6 @@ 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();
@@ -397,8 +392,7 @@ 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;
@@ -635,10 +629,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
return; return;
} }
if (context.Capabilities.Api != TargetApi.Metal) WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
{
WriteHostCode(context, hostCode, program.Shaders, streams, timestamp);
}
} }
/// <summary> /// <summary>

View File

@@ -1,4 +1,3 @@
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;
@@ -367,9 +366,6 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
{ {
try try
{ {
if (_context.Capabilities.Api == TargetApi.Metal && _context.DirtyHacks.IsEnabled(DirtyHack.ShaderTranslationDelay))
Thread.Sleep(_context.DirtyHacks[DirtyHack.ShaderTranslationDelay]);
AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute); AsyncProgramTranslation asyncTranslation = new(guestShaders, specState, programIndex, isCompute);
_asyncTranslationQueue.Add(asyncTranslation, _cancellationToken); _asyncTranslationQueue.Add(asyncTranslation, _cancellationToken);
} }
@@ -494,12 +490,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
{ {
ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length]; ShaderSource[] shaderSources = new ShaderSource[compilation.TranslatedStages.Length];
ref GpuChannelComputeState computeState = ref compilation.SpecializationState.ComputeState; ShaderInfoBuilder shaderInfoBuilder = new(_context, compilation.SpecializationState.TransformFeedbackDescriptors != null);
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++)
{ {

View File

@@ -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 _isOpenGL; private readonly bool _isVulkan;
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;
_isOpenGL = context.Capabilities.Api == TargetApi.OpenGL; _isVulkan = context.Capabilities.Api == TargetApi.Vulkan;
_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(
_isOpenGL, !_isVulkan,
_supportsQuads, _supportsQuads,
_hasGeometryShader, _hasGeometryShader,
!_isOpenGL || _state.GraphicsState.YNegateEnabled); _isVulkan || _state.GraphicsState.YNegateEnabled);
} }
/// <inheritdoc/> /// <inheritdoc/>

View File

@@ -55,7 +55,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
int binding; int binding;
if (_context.Capabilities.Api != TargetApi.OpenGL) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
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.OpenGL) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
if (count == 1) if (count == 1)
{ {
@@ -103,7 +103,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
{ {
int binding; int binding;
if (_context.Capabilities.Api != TargetApi.OpenGL) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
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.OpenGL) if (_context.Capabilities.Api == TargetApi.Vulkan)
{ {
if (count == 1) if (count == 1)
{ {

View File

@@ -1,5 +1,3 @@
using Ryujinx.Graphics.GAL;
namespace Ryujinx.Graphics.Gpu.Shader namespace Ryujinx.Graphics.Gpu.Shader
{ {
/// <summary> /// <summary>
@@ -63,14 +61,5 @@ 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);
}
} }
} }

View File

@@ -1,4 +1,3 @@
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;
@@ -225,10 +224,7 @@ 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( ShaderInfo info = ShaderInfoBuilder.BuildForCompute(_context, translatedShader.Program.Info);
_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);
@@ -429,8 +425,7 @@ namespace Ryujinx.Graphics.Gpu.Shader
TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage; TranslatorContext lastInVertexPipeline = geometryToCompute ? translatorContexts[4] ?? currentStage : currentStage;
(program, ShaderProgramInfo vacInfo) = lastInVertexPipeline.GenerateVertexPassthroughForCompute(); program = lastInVertexPipeline.GenerateVertexPassthroughForCompute();
infoBuilder.AddStageInfoVac(vacInfo);
} }
else else
{ {
@@ -535,7 +530,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, context.GetVertexAsComputeInfo(), tfEnabled); ShaderInfo info = ShaderInfoBuilder.BuildForVertexAsCompute(_context, program.Info, 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());
} }
@@ -827,20 +822,16 @@ 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 chosen based on the current configuration and graphics API. /// The shader language is choosen 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 = api switch TargetLanguage lang = GraphicsConfig.EnableSpirvCompilationOnVulkan && api == TargetApi.Vulkan
{ ? TargetLanguage.Spirv
TargetApi.OpenGL => TargetLanguage.Glsl, : 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);
} }

View File

@@ -22,7 +22,6 @@ 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;
@@ -40,11 +39,9 @@ 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>
/// <param name="computeLocalSize">Indicates the local thread size for a compute shader</param> public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false)
public ShaderInfoBuilder(GpuContext context, bool tfEnabled, bool vertexAsCompute = false, ComputeSize computeLocalSize = default)
{ {
_context = context; _context = context;
_computeLocalSize = computeLocalSize;
_fragmentOutputMap = -1; _fragmentOutputMap = -1;
@@ -98,7 +95,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>
@@ -162,25 +159,6 @@ 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>
@@ -383,7 +361,14 @@ namespace Ryujinx.Graphics.Gpu.Shader
ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly()); ResourceLayout resourceLayout = new(descriptors.AsReadOnly(), usages.AsReadOnly());
return new ShaderInfo(_fragmentOutputMap, resourceLayout, _computeLocalSize, pipeline, fromCache); if (pipeline.HasValue)
{
return new ShaderInfo(_fragmentOutputMap, resourceLayout, pipeline.Value, fromCache);
}
else
{
return new ShaderInfo(_fragmentOutputMap, resourceLayout, fromCache);
}
} }
/// <summary> /// <summary>
@@ -393,16 +378,14 @@ 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, computeLocalSize: computeLocalSize); ShaderInfoBuilder builder = new(context, tfEnabled);
foreach (CachedShaderStage program in programs) foreach (CachedShaderStage program in programs)
{ {
@@ -420,12 +403,11 @@ 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, ComputeSize computeLocalSize, bool fromCache = false) public static ShaderInfo BuildForCompute(GpuContext context, ShaderProgramInfo info, bool fromCache = false)
{ {
ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false, computeLocalSize: computeLocalSize); ShaderInfoBuilder builder = new(context, tfEnabled: false, vertexAsCompute: false);
builder.AddStageInfo(info); builder.AddStageInfo(info);
@@ -440,11 +422,10 @@ 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, ShaderProgramInfo info2, bool tfEnabled, bool fromCache = false) public static ShaderInfo BuildForVertexAsCompute(GpuContext context, ShaderProgramInfo info, bool tfEnabled, bool fromCache = false)
{ {
ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true, computeLocalSize: ComputeSize.VtgAsCompute); ShaderInfoBuilder builder = new(context, tfEnabled, vertexAsCompute: true);
builder.AddStageInfoVac(info2);
builder.AddStageInfo(info, vertexAsCompute: true); builder.AddStageInfo(info, vertexAsCompute: true);
return builder.Build(null, fromCache); return builder.Build(null, fromCache);

View File

@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes> <DefaultItemExcludes>$(DefaultItemExcludes);._*</DefaultItemExcludes>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,22 +0,0 @@
using SharpMetal;
using SharpMetal.Foundation;
using SharpMetal.ObjectiveCCore;
using SharpMetal.QuartzCore;
using System.Runtime.Versioning;
// ReSharper disable InconsistentNaming
namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
{
[SupportedOSPlatform("macOS")]
public static class CAMetalLayerExtensions
{
private static readonly Selector sel_developerHUDProperties = "developerHUDProperties";
private static readonly Selector sel_setDeveloperHUDProperties = "setDeveloperHUDProperties:";
public static NSDictionary GetDeveloperHudProperties(this CAMetalLayer metalLayer)
=> new(ObjectiveCRuntime.IntPtr_objc_msgSend(metalLayer.NativePtr, sel_developerHUDProperties));
public static void SetDeveloperHudProperties(this CAMetalLayer metalLayer, NSDictionary dictionary)
=> ObjectiveCRuntime.objc_msgSend(metalLayer.NativePtr, sel_setDeveloperHUDProperties, dictionary);
}
}

View File

@@ -1,32 +0,0 @@
using SharpMetal.Foundation;
using SharpMetal.ObjectiveCCore;
using System.Runtime.Versioning;
// ReSharper disable InconsistentNaming
namespace Ryujinx.Graphics.Metal.SharpMetalExtensions
{
[SupportedOSPlatform("macOS")]
public static class NSHelper
{
private static readonly Selector sel_getCStringMaxLengthEncoding = "getCString:maxLength:encoding:";
private static readonly Selector sel_stringWithUTF8String = "stringWithUTF8String:";
public static unsafe string ToDotNetString(this NSString source)
{
char[] sourceBuffer = new char[source.Length];
fixed (char* pSourceBuffer = sourceBuffer)
{
ObjectiveC.bool_objc_msgSend(source,
sel_getCStringMaxLengthEncoding,
pSourceBuffer,
source.MaximumLengthOfBytes(NSStringEncoding.UTF16) + 1,
(ulong)NSStringEncoding.UTF16);
}
return new string(sourceBuffer);
}
public static NSString ToNSString(this string source)
=> new(ObjectiveC.IntPtr_objc_msgSend(new ObjectiveCClass(nameof(NSString)), sel_stringWithUTF8String, source));
}
}

View File

@@ -1,11 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SharpMetal" />
</ItemGroup>
</Project>

View File

@@ -1,146 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Threading;
namespace Ryujinx.Graphics.Metal
{
interface IAuto
{
bool HasCommandBufferDependency(CommandBufferScoped cbs);
void IncrementReferenceCount();
void DecrementReferenceCount(int cbIndex);
void DecrementReferenceCount();
}
interface IAutoPrivate : IAuto
{
void AddCommandBufferDependencies(CommandBufferScoped cbs);
}
[SupportedOSPlatform("macos")]
class Auto<T> : IAutoPrivate, IDisposable where T : IDisposable
{
private int _referenceCount;
private T _value;
private readonly BitMap _cbOwnership;
private readonly MultiFenceHolder _waitable;
private bool _disposed;
private bool _destroyed;
public Auto(T value)
{
_referenceCount = 1;
_value = value;
_cbOwnership = new BitMap(CommandBufferPool.MaxCommandBuffers);
}
public Auto(T value, MultiFenceHolder waitable) : this(value)
{
_waitable = waitable;
}
public T Get(CommandBufferScoped cbs, int offset, int size, bool write = false)
{
_waitable?.AddBufferUse(cbs.CommandBufferIndex, offset, size, write);
return Get(cbs);
}
public T GetUnsafe()
{
return _value;
}
public T Get(CommandBufferScoped cbs)
{
if (!_destroyed)
{
AddCommandBufferDependencies(cbs);
}
return _value;
}
public bool HasCommandBufferDependency(CommandBufferScoped cbs)
{
return _cbOwnership.IsSet(cbs.CommandBufferIndex);
}
public bool HasRentedCommandBufferDependency(CommandBufferPool cbp)
{
return _cbOwnership.AnySet();
}
public void AddCommandBufferDependencies(CommandBufferScoped cbs)
{
// We don't want to add a reference to this object to the command buffer
// more than once, so if we detect that the command buffer already has ownership
// of this object, then we can just return without doing anything else.
if (_cbOwnership.Set(cbs.CommandBufferIndex))
{
if (_waitable != null)
{
cbs.AddWaitable(_waitable);
}
cbs.AddDependant(this);
}
}
public bool TryIncrementReferenceCount()
{
int lastValue;
do
{
lastValue = _referenceCount;
if (lastValue == 0)
{
return false;
}
}
while (Interlocked.CompareExchange(ref _referenceCount, lastValue + 1, lastValue) != lastValue);
return true;
}
public void IncrementReferenceCount()
{
if (Interlocked.Increment(ref _referenceCount) == 1)
{
Interlocked.Decrement(ref _referenceCount);
throw new InvalidOperationException("Attempted to increment the reference count of an object that was already destroyed.");
}
}
public void DecrementReferenceCount(int cbIndex)
{
_cbOwnership.Clear(cbIndex);
DecrementReferenceCount();
}
public void DecrementReferenceCount()
{
if (Interlocked.Decrement(ref _referenceCount) == 0)
{
_value.Dispose();
_value = default;
_destroyed = true;
}
Debug.Assert(_referenceCount >= 0);
}
public void Dispose()
{
if (!_disposed)
{
DecrementReferenceCount();
_disposed = true;
}
}
}
}

View File

@@ -1,107 +0,0 @@
using SharpMetal.Metal;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
using System.Threading;
namespace Ryujinx.Graphics.Metal
{
[SupportedOSPlatform("macos")]
class BackgroundResource : IDisposable
{
private readonly MetalRenderer _renderer;
private CommandBufferPool _pool;
private PersistentFlushBuffer _flushBuffer;
public BackgroundResource(MetalRenderer renderer)
{
_renderer = renderer;
}
public CommandBufferPool GetPool()
{
if (_pool == null)
{
MTLCommandQueue queue = _renderer.BackgroundQueue;
_pool = new CommandBufferPool(queue, true);
_pool.Initialize(null); // TODO: Proper encoder factory for background render/compute
}
return _pool;
}
public PersistentFlushBuffer GetFlushBuffer()
{
_flushBuffer ??= new PersistentFlushBuffer(_renderer);
return _flushBuffer;
}
public void Dispose()
{
_pool?.Dispose();
_flushBuffer?.Dispose();
}
}
[SupportedOSPlatform("macos")]
class BackgroundResources : IDisposable
{
private readonly MetalRenderer _renderer;
private readonly Dictionary<Thread, BackgroundResource> _resources;
public BackgroundResources(MetalRenderer renderer)
{
_renderer = renderer;
_resources = new Dictionary<Thread, BackgroundResource>();
}
private void Cleanup()
{
lock (_resources)
{
foreach (KeyValuePair<Thread, BackgroundResource> tuple in _resources)
{
if (!tuple.Key.IsAlive)
{
tuple.Value.Dispose();
_resources.Remove(tuple.Key);
}
}
}
}
public BackgroundResource Get()
{
Thread thread = Thread.CurrentThread;
lock (_resources)
{
if (!_resources.TryGetValue(thread, out BackgroundResource resource))
{
Cleanup();
resource = new BackgroundResource(_renderer);
_resources[thread] = resource;
}
return resource;
}
}
public void Dispose()
{
lock (_resources)
{
foreach (var resource in _resources.Values)
{
resource.Dispose();
}
}
}
}
}

View File

@@ -1,157 +0,0 @@
namespace Ryujinx.Graphics.Metal
{
readonly struct BitMap
{
public const int IntSize = 64;
private const int IntShift = 6;
private const int IntMask = IntSize - 1;
private readonly long[] _masks;
public BitMap(int count)
{
_masks = new long[(count + IntMask) / IntSize];
}
public bool AnySet()
{
for (int i = 0; i < _masks.Length; i++)
{
if (_masks[i] != 0)
{
return true;
}
}
return false;
}
public bool IsSet(int bit)
{
int wordIndex = bit >> IntShift;
int wordBit = bit & IntMask;
long wordMask = 1L << wordBit;
return (_masks[wordIndex] & wordMask) != 0;
}
public bool IsSet(int start, int end)
{
if (start == end)
{
return IsSet(start);
}
int startIndex = start >> IntShift;
int startBit = start & IntMask;
long startMask = -1L << startBit;
int endIndex = end >> IntShift;
int endBit = end & IntMask;
long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
if (startIndex == endIndex)
{
return (_masks[startIndex] & startMask & endMask) != 0;
}
if ((_masks[startIndex] & startMask) != 0)
{
return true;
}
for (int i = startIndex + 1; i < endIndex; i++)
{
if (_masks[i] != 0)
{
return true;
}
}
if ((_masks[endIndex] & endMask) != 0)
{
return true;
}
return false;
}
public bool Set(int bit)
{
int wordIndex = bit >> IntShift;
int wordBit = bit & IntMask;
long wordMask = 1L << wordBit;
if ((_masks[wordIndex] & wordMask) != 0)
{
return false;
}
_masks[wordIndex] |= wordMask;
return true;
}
public void SetRange(int start, int end)
{
if (start == end)
{
Set(start);
return;
}
int startIndex = start >> IntShift;
int startBit = start & IntMask;
long startMask = -1L << startBit;
int endIndex = end >> IntShift;
int endBit = end & IntMask;
long endMask = (long)(ulong.MaxValue >> (IntMask - endBit));
if (startIndex == endIndex)
{
_masks[startIndex] |= startMask & endMask;
}
else
{
_masks[startIndex] |= startMask;
for (int i = startIndex + 1; i < endIndex; i++)
{
_masks[i] |= -1;
}
_masks[endIndex] |= endMask;
}
}
public void Clear(int bit)
{
int wordIndex = bit >> IntShift;
int wordBit = bit & IntMask;
long wordMask = 1L << wordBit;
_masks[wordIndex] &= ~wordMask;
}
public void Clear()
{
for (int i = 0; i < _masks.Length; i++)
{
_masks[i] = 0;
}
}
public void ClearInt(int start, int end)
{
for (int i = start; i <= end; i++)
{
_masks[i] = 0;
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More