Compare commits

...

13 commits

Author SHA1 Message Date
KeatonTheBot
565174c2cd Revert "Vulkan: Feedback loop detection and barriers (#7226)"
This reverts commit ca59c3f499.
2024-12-19 19:50:35 -06:00
Marco Carvalho
ff6628149d
Migrate to .NET 9 (#198)
Some checks are pending
Canary release job / Create tag (push) Waiting to run
Canary release job / Release for linux-arm64 (push) Waiting to run
Canary release job / Release for linux-x64 (push) Waiting to run
Canary release job / Release for win-x64 (push) Waiting to run
Canary release job / Release MacOS universal (push) Waiting to run
2024-12-19 18:52:25 -06:00
Evan Husted
8db5a7e98b UI: Fix logo aliasing
Some checks failed
Canary release job / Create tag (push) Has been cancelled
Canary release job / Release for linux-arm64 (push) Has been cancelled
Canary release job / Release for linux-x64 (push) Has been cancelled
Canary release job / Release for win-x64 (push) Has been cancelled
Canary release job / Release MacOS universal (push) Has been cancelled
2024-12-17 21:20:49 -06:00
GabCoolGuy
8e00cb5232
UI: Add faq, setup and multiplayer guides to the Help dropdown (#383)
Some checks failed
Canary release job / Create tag (push) Has been cancelled
Canary release job / Release for linux-arm64 (push) Has been cancelled
Canary release job / Release for linux-x64 (push) Has been cancelled
Canary release job / Release for win-x64 (push) Has been cancelled
Canary release job / Release MacOS universal (push) Has been cancelled
2024-12-15 10:45:37 -06:00
Evan Husted
362f62cd39
Revamp README header
Some checks failed
Canary release job / Create tag (push) Has been cancelled
Canary release job / Release for linux-arm64 (push) Has been cancelled
Canary release job / Release for linux-x64 (push) Has been cancelled
Canary release job / Release for win-x64 (push) Has been cancelled
Canary release job / Release MacOS universal (push) Has been cancelled
2024-12-14 08:41:44 -06:00
Evan Husted
2cd54d0da0 Remove icon padding 2024-12-14 08:03:17 -06:00
Evan Husted
b97b8ca8f5 Logo from PR #381 everywhere 2024-12-14 07:27:07 -06:00
Matteo Forlani
d7d4225e0d
New macOS icon (#381) 2024-12-14 07:23:47 -06:00
Evan Husted
a9e0fac9dc
fix changelogs in canary release 2024-12-13 19:28:34 -06:00
Daenorth
1b9656e960
Norwegian Translation (#338)
Some checks failed
Canary release job / Create tag (push) Has been cancelled
Canary release job / Release for linux-arm64 (push) Has been cancelled
Canary release job / Release for linux-x64 (push) Has been cancelled
Canary release job / Release for win-x64 (push) Has been cancelled
Canary release job / Release MacOS universal (push) Has been cancelled
2024-12-13 03:56:20 -06:00
Hack茶ん
8994e7476c
Korean Former Maintainers & About description translations (#371) 2024-12-13 03:54:07 -06:00
rrondo
b3944a18b7
Some changes to Ukrainian localization (uk_UA.json) (#356)
Some checks failed
Canary release job / Create tag (push) Has been cancelled
Canary release job / Release for linux-arm64 (push) Has been cancelled
Canary release job / Release for linux-x64 (push) Has been cancelled
Canary release job / Release for win-x64 (push) Has been cancelled
Canary release job / Release MacOS universal (push) Has been cancelled
I made some small corrections and translated the lines that didn’t have
translations.
2024-12-10 11:58:53 -06:00
GabCoolGuy
18c957f90b
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-10 11:02:18 -06:00
183 changed files with 2311 additions and 1720 deletions

View file

@ -54,7 +54,19 @@ jobs:
with:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/${{ github.repository }}/releases/latest) instead if that sounds like something you don't want to deal with.
| Platform | Artifact |
|--|--|
| Windows 64 bit | [Canary Windows Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-win_x64.zip) |
| Linux 64 bit | [Canary Linux Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_x64.tar.gz) |
| Linux arm 64 bit | [Canary Linux arm Artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-linux_arm64.tar.gz) |
| macOS | [Canary macOS artifact](https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}/releases/download/${{ steps.version_info.outputs.build_version }}/ryujinx-canary-${{ steps.version_info.outputs.build_version }}-macos_universal.app.tar.gz) |
**Full Changelog**: https://github.com/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}/${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_SOURCE_REPO }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
@ -181,7 +193,19 @@ jobs:
artifacts: "release_output/*.tar.gz,release_output/*.zip"
#artifacts: "release_output/*.tar.gz,release_output/*.zip/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/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/${{ 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
allowUpdates: true
replacesArtifacts: true
@ -248,7 +272,19 @@ jobs:
name: "Canary ${{ steps.version_info.outputs.build_version }}"
artifacts: "publish_ava/*.tar.gz, publish_headless/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/Canary-${{ steps.version_info.outputs.prev_build_version }}...Canary-${{ steps.version_info.outputs.build_version }}"
body: |
# Canary builds:
These builds are experimental and may sometimes not work, use [regular builds](https://github.com/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
allowUpdates: true
replacesArtifacts: true

View file

@ -53,7 +53,16 @@ jobs:
with:
name: ${{ steps.version_info.outputs.build_version }}
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
body: |
# Regular builds:
| Platform | Artifact |
|--|--|
| 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 | [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 | [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 | [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 }}
omitBodyDuringUpdate: true
owner: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_OWNER }}
repo: ${{ env.RYUJINX_TARGET_RELEASE_CHANNEL_REPO }}
@ -176,7 +185,16 @@ jobs:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "release_output/*.tar.gz,release_output/*.zip,release_output/*AppImage*"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
body: |
# 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
allowUpdates: true
replacesArtifacts: true
@ -243,7 +261,16 @@ jobs:
name: ${{ steps.version_info.outputs.build_version }}
artifacts: "publish/*.tar.gz, publish_headless/*.tar.gz"
tag: ${{ steps.version_info.outputs.build_version }}
body: "**Full Changelog**: https://github.com/${{ github.repository }}/compare/${{ steps.version_info.outputs.prev_build_version }}...${{ steps.version_info.outputs.build_version }}"
body: |
# 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
allowUpdates: true
replacesArtifacts: true

View file

@ -5,7 +5,7 @@ If you wish to build the emulator yourself, follow these steps:
### Step 1
Install the [.NET 8.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/8.0).
Install the [.NET 9.0 (or higher) SDK](https://dotnet.microsoft.com/download/dotnet/9.0).
Make sure your SDK version is higher or equal to the required version specified in [global.json](global.json).
### Step 2

6
Directory.Build.props Normal file
View file

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

View file

@ -48,8 +48,8 @@
<PackageVersion Include="SkiaSharp" Version="2.88.7" />
<PackageVersion Include="SkiaSharp.NativeAssets.Linux" Version="2.88.7" />
<PackageVersion Include="SPB" Version="0.0.4-build32" />
<PackageVersion Include="System.IO.Hashing" Version="8.0.0" />
<PackageVersion Include="System.Management" Version="8.0.0" />
<PackageVersion Include="System.IO.Hashing" Version="9.0.0" />
<PackageVersion Include="System.Management" Version="9.0.0" />
<PackageVersion Include="UnicornEngine.Unicorn" Version="2.0.2-rc1-fb78016" />
</ItemGroup>
</Project>

View file

@ -1,35 +1,26 @@
<h1 align="center">
<table align="center">
<tr>
<td align="center" width="25%">
<img src="https://raw.githubusercontent.com/GreemDev/ryuassets/refs/heads/main/RyujinxApp_1024.png" alt="Ryujinx" >
</td>
<td align="center" width="75%">
# Ryujinx
[![Release workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml/badge.svg)](https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml)
[![Latest release](https://img.shields.io/github/v/release/GreemDev/Ryujinx)](https://github.com/GreemDev/Ryujinx/releases/latest)
<br>
<img src="https://raw.githubusercontent.com/GreemDev/Ryujinx/master/distribution/misc/Logo.svg" alt="Ryujinx" width="150"></a>
<br>
<b>Ryujinx</b>
<br>
<sub><sup><b>(REE-YOU-JINX)</b></sup></sub>
<br>
<a href="https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml">
<img src="https://github.com/GreemDev/Ryujinx/actions/workflows/release.yml/badge.svg"
alt="">
</a>
<a href="https://github.com/GreemDev/Ryujinx/releases/latest">
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx"
alt="Latest Release">
</a>
<br>
<a href="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml">
<img src="https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg"
alt="">
</a>
<a href="https://github.com/GreemDev/Ryujinx-Canary/releases/latest">
<img src="https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary"
alt="Latest Canary Release">
</a>
</h1>
[![Canary workflow](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml/badge.svg)](https://github.com/GreemDev/Ryujinx/actions/workflows/canary.yml)
[![Latest canary release](https://img.shields.io/github/v/release/GreemDev/Ryujinx-Canary?label=canary)](https://github.com/GreemDev/Ryujinx-Canary/releases/latest)
</td>
</tr>
</table>
<p align="center">
Ryujinx is an open-source Nintendo Switch emulator, originally created by gdkchan, written in C#.
This emulator aims at providing excellent accuracy and performance, a user-friendly interface and consistent builds.
It was written from scratch and development on the project began in September 2017.
Ryujinx is available on Github under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
Ryujinx is available on GitHub under the <a href="https://github.com/GreemDev/Ryujinx/blob/master/LICENSE.txt" target="_blank">MIT license</a>.
<br />
</p>
<p align="center">

Binary file not shown.

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.2 MiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 48 KiB

View file

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

View file

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

View file

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

View file

@ -264,7 +264,7 @@ namespace ARMeilleure.Instructions
return TblOrTbx(dest, vector, bytes, tb0, tb1, tb2, tb3);
}
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params V128[] tb)
private static V128 TblOrTbx(V128 dest, V128 vector, int bytes, params ReadOnlySpan<V128> tb)
{
byte[] res = new byte[16];

View file

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

View file

@ -8,6 +8,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
namespace ARMeilleure.Translation.Cache
{
@ -26,7 +27,7 @@ namespace ARMeilleure.Translation.Cache
private static readonly List<CacheEntry> _cacheEntries = new();
private static readonly object _lock = new();
private static readonly Lock _lock = new();
private static bool _initialized;
[SupportedOSPlatform("windows")]

View file

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

View file

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

View file

@ -41,7 +41,7 @@ namespace ARMeilleure.Translation.PTC
private readonly ManualResetEvent _waitEvent;
private readonly object _lock;
private readonly Lock _lock = new();
private bool _disposed;
@ -65,8 +65,6 @@ namespace ARMeilleure.Translation.PTC
_waitEvent = new ManualResetEvent(true);
_lock = new object();
_disposed = false;
ProfiledFuncs = new Dictionary<ulong, FuncProfile>();

View file

@ -5,6 +5,7 @@ using Ryujinx.Memory;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace Ryujinx.Audio.Backends.OpenAL
{
@ -18,7 +19,7 @@ namespace Ryujinx.Audio.Backends.OpenAL
private ulong _playedSampleCount;
private float _volume;
private readonly object _lock = new();
private readonly Lock _lock = new();
public OpenALHardwareDeviceSession(OpenALHardwareDeviceDriver driver, IVirtualMemoryManager memoryManager, SampleFormat requestedSampleFormat, uint requestedSampleRate, uint requestedChannelCount) : base(memoryManager, requestedSampleFormat, requestedSampleRate, requestedChannelCount)
{

View file

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

View file

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

View file

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

View file

@ -11,7 +11,7 @@ namespace Ryujinx.Audio
/// <summary>
/// Lock used to control the waiters registration.
/// </summary>
private readonly object _lock = new();
private readonly Lock _lock = new();
/// <summary>
/// Events signaled when the driver played audio buffers.

View file

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

View file

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

View file

@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Input
/// <summary>
/// The lock of the parent.
/// </summary>
private readonly object _parentLock;
private readonly Lock _parentLock;
/// <summary>
/// The dispose state.
@ -62,7 +62,7 @@ namespace Ryujinx.Audio.Input
/// <param name="parentLock">The lock of the manager</param>
/// <param name="deviceSession">The hardware device session</param>
/// <param name="bufferEvent">The buffer release event of the audio input</param>
public AudioInputSystem(AudioInputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
public AudioInputSystem(AudioInputManager manager, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
{
_manager = manager;
_parentLock = parentLock;

View file

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

View file

@ -48,7 +48,7 @@ namespace Ryujinx.Audio.Output
/// <summary>
/// THe lock of the parent.
/// </summary>
private readonly object _parentLock;
private readonly Lock _parentLock;
/// <summary>
/// The dispose state.
@ -62,7 +62,7 @@ namespace Ryujinx.Audio.Output
/// <param name="parentLock">The lock of the manager</param>
/// <param name="deviceSession">The hardware device session</param>
/// <param name="bufferEvent">The buffer release event of the audio output</param>
public AudioOutputSystem(AudioOutputManager manager, object parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
public AudioOutputSystem(AudioOutputManager manager, Lock parentLock, IHardwareDeviceSession deviceSession, IWritableEvent bufferEvent)
{
_manager = manager;
_parentLock = parentLock;

View file

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

View file

@ -19,12 +19,12 @@ namespace Ryujinx.Audio.Renderer.Server
/// <summary>
/// Lock used for session allocation.
/// </summary>
private readonly object _sessionLock = new();
private readonly Lock _sessionLock = new();
/// <summary>
/// Lock used to control the <see cref="AudioProcessor"/> running state.
/// </summary>
private readonly object _audioProcessorLock = new();
private readonly Lock _audioProcessorLock = new();
/// <summary>
/// The session ids allocation table.

View file

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

View file

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

View file

@ -1,33 +1,13 @@
using Ryujinx.Common.Utilities;
using System;
namespace Ryujinx.Common.GraphicsDriver
{
public static class DriverUtilities
{
private static void AddMesaFlags(string envVar, string newFlags)
{
string existingFlags = Environment.GetEnvironmentVariable(envVar);
string flags = existingFlags == null ? newFlags : $"{existingFlags},{newFlags}";
OsUtils.SetEnvironmentVariableNoCaching(envVar, flags);
}
public static void InitDriverConfig(bool oglThreading)
{
if (OperatingSystem.IsLinux())
{
AddMesaFlags("RADV_DEBUG", "nodcc");
}
ToggleOGLThreading(oglThreading);
}
public static void ToggleOGLThreading(bool enabled)
{
OsUtils.SetEnvironmentVariableNoCaching("mesa_glthread", enabled.ToString().ToLower());
OsUtils.SetEnvironmentVariableNoCaching("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
Environment.SetEnvironmentVariable("mesa_glthread", enabled.ToString().ToLower());
Environment.SetEnvironmentVariable("__GL_THREADED_OPTIMIZATIONS", enabled ? "1" : "0");
try
{

View file

@ -124,7 +124,7 @@ namespace Ryujinx.Common.PreciseSleep
}
}
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly List<NanosleepThread> _threads = new();
private readonly List<NanosleepThread> _active = new();
private readonly Stack<NanosleepThread> _free = new();

View file

@ -50,7 +50,7 @@ namespace Ryujinx.Common.SystemInterop
private long _lastTicks = PerformanceCounter.ElapsedTicks;
private long _lastId;
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly List<WaitingObject> _waitingObjects = new();
private WindowsGranularTimer()

View file

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

View file

@ -1,24 +0,0 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
namespace Ryujinx.Common.Utilities
{
public partial class OsUtils
{
[LibraryImport("libc", SetLastError = true)]
private static partial int setenv([MarshalAs(UnmanagedType.LPStr)] string name, [MarshalAs(UnmanagedType.LPStr)] string value, int overwrite);
public static void SetEnvironmentVariableNoCaching(string key, string value)
{
// Set the value in the cached environment variables, too.
Environment.SetEnvironmentVariable(key, value);
if (!OperatingSystem.IsWindows())
{
int res = setenv(key, value, 1);
Debug.Assert(res != -1);
}
}
}
}

View file

@ -1,6 +1,7 @@
using Ryujinx.Memory;
using System;
using System.Runtime.Versioning;
using System.Threading;
namespace Ryujinx.Cpu.AppleHv
{
@ -12,7 +13,7 @@ namespace Ryujinx.Cpu.AppleHv
private static int _addressSpaces;
private static HvIpaAllocator _ipaAllocator;
private static readonly object _lock = new();
private static readonly Lock _lock = new();
public static (ulong, HvIpaAllocator) CreateAddressSpace(MemoryBlock block)
{

View file

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

View file

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

View file

@ -5,6 +5,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Threading;
namespace Ryujinx.Cpu.LightningJit.Cache
{
@ -23,7 +24,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
private static readonly List<CacheEntry> _cacheEntries = new();
private static readonly object _lock = new();
private static readonly Lock _lock = new();
private static bool _initialized;
[SupportedOSPlatform("windows")]

View file

@ -4,6 +4,7 @@ using Ryujinx.Memory;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace Ryujinx.Cpu.LightningJit.Cache
{
@ -104,7 +105,7 @@ namespace Ryujinx.Cpu.LightningJit.Cache
private readonly MemoryCache _sharedCache;
private readonly MemoryCache _localCache;
private readonly PageAlignedRangeList _pendingMap;
private readonly object _lock;
private readonly Lock _lock = new();
class ThreadLocalCacheEntry
{
@ -137,7 +138,6 @@ namespace Ryujinx.Cpu.LightningJit.Cache
_sharedCache = new(allocator, SharedCacheSize);
_localCache = new(allocator, LocalCacheSize);
_pendingMap = new(_sharedCache.ReprotectAsRx, RegisterFunction);
_lock = new();
}
public unsafe nint Map(nint framePointer, ReadOnlySpan<byte> code, ulong guestAddress, ulong guestSize)

View file

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

View file

@ -5,6 +5,7 @@ using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
namespace Ryujinx.Cpu.Signal
{
@ -59,7 +60,7 @@ namespace Ryujinx.Cpu.Signal
private static MemoryBlock _codeBlock;
private static readonly object _lock = new();
private static readonly Lock _lock = new();
private static bool _initialized;
static NativeSignalHandler()

View file

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

View file

@ -58,7 +58,7 @@ namespace Ryujinx.Graphics.GAL.Multithreading
public uint ProgramCount { get; set; } = 0;
private Action _interruptAction;
private readonly object _interruptLock = new();
private readonly Lock _interruptLock = new();
public event EventHandler<ScreenCaptureImageInfo> ScreenCaptured;

View file

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

View file

@ -8,6 +8,7 @@ using Ryujinx.Graphics.Texture;
using Ryujinx.Memory.Range;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
namespace Ryujinx.Graphics.Gpu.Image
@ -998,7 +999,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
bool dataOverlaps = texture.DataOverlaps(overlap, compatibility);
if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Exists(incompatible => incompatible.Group == overlap.Group))
if (!overlap.IsView && dataOverlaps && !incompatibleOverlaps.Any(incompatible => incompatible.Group == overlap.Group))
{
incompatibleOverlaps.Add(new TextureIncompatibleOverlap(overlap.Group, compatibility));
}

View file

@ -7,6 +7,7 @@ using Ryujinx.Memory.Range;
using Ryujinx.Memory.Tracking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
namespace Ryujinx.Graphics.Gpu.Image
@ -1555,7 +1556,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="copy">True if the overlap should register copy dependencies</param>
public void RegisterIncompatibleOverlap(TextureIncompatibleOverlap other, bool copy)
{
if (!_incompatibleOverlaps.Exists(overlap => overlap.Group == other.Group))
if (!_incompatibleOverlaps.Any(overlap => overlap.Group == other.Group))
{
if (copy && other.Compatibility == TextureViewCompatibility.LayoutIncompatible)
{
@ -1701,3 +1702,4 @@ 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="components">The texture swizzle components</param>
/// <returns>The depth-stencil mode</returns>
private static DepthStencilMode GetDepthStencilMode(Format format, params SwizzleComponent[] components)
private static DepthStencilMode GetDepthStencilMode(Format format, params ReadOnlySpan<SwizzleComponent> components)
{
// R = Depth, G = Stencil.
// On 24-bits depth formats, this is inverted (Stencil is R etc).

View file

@ -2,6 +2,7 @@ using Ryujinx.Common.Pools;
using Ryujinx.Memory.Range;
using System;
using System.Linq;
using System.Threading;
namespace Ryujinx.Graphics.Gpu.Memory
{
@ -76,7 +77,7 @@ namespace Ryujinx.Graphics.Gpu.Memory
private BufferMigration _source;
private BufferModifiedRangeList _migrationTarget;
private readonly object _lock = new();
private readonly Lock _lock = new();
/// <summary>
/// Whether the modified range list has any entries or not.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -19,7 +19,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private ulong _accumulatedCounter;
private int _waiterCount;
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly Queue<BufferedQuery> _queryPool;
private readonly AutoResetEvent _queuedEvent = new(false);

View file

@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.OpenGL.Queries
private bool _hostAccessReserved = false;
private int _refCount = 1; // Starts with a reference from the counter queue.
private readonly object _lock = new();
private readonly Lock _lock = new();
private ulong _result = ulong.MaxValue;
private double _divisor = 1f;

View file

@ -2,6 +2,7 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.OpenGL.Image;
using System;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.Graphics.OpenGL
{
@ -19,7 +20,7 @@ namespace Ryujinx.Graphics.OpenGL
{
private const int DisposedLiveFrames = 2;
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly Dictionary<TextureCreateInfo, List<DisposedTexture>> _textures = new();
/// <summary>

View file

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

View file

@ -4,6 +4,7 @@ using Ryujinx.Graphics.Shader.StructuredIr;
using Ryujinx.Graphics.Shader.Translation;
using System;
using System.Collections.Generic;
using System.Threading;
using static Spv.Specification;
namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
@ -19,13 +20,12 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
private const int GeneratorPoolCount = 1;
private static readonly ObjectPool<SpvInstructionPool> _instructionPool;
private static readonly ObjectPool<SpvLiteralIntegerPool> _integerPool;
private static readonly object _poolLock;
private static readonly Lock _poolLock = new();
static SpirvGenerator()
{
_instructionPool = new(() => new SpvInstructionPool(), GeneratorPoolCount);
_integerPool = new(() => new SpvLiteralIntegerPool(), GeneratorPoolCount);
_poolLock = new object();
}
private const HelperFunctionsMask NeedsInvocationIdMask = HelperFunctionsMask.SwizzleAdd;

View file

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

View file

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

View file

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

View file

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

View file

@ -25,7 +25,7 @@ namespace Ryujinx.Graphics.Vulkan
{
bool useBackground = _gd.BackgroundQueue.Handle != 0 && _gd.Vendor != Vendor.Amd;
Queue queue = useBackground ? _gd.BackgroundQueue : _gd.Queue;
object queueLock = useBackground ? _gd.BackgroundQueueLock : _gd.QueueLock;
Lock queueLock = useBackground ? _gd.BackgroundQueueLock : _gd.QueueLock;
lock (queueLock)
{

View file

@ -32,12 +32,10 @@ namespace Ryujinx.Graphics.Vulkan
CommandBuffer
}
private bool _feedbackLoopActive;
private PipelineStageFlags _incoherentBufferWriteStages;
private PipelineStageFlags _incoherentTextureWriteStages;
private PipelineStageFlags _extraStages;
private IncoherentBarrierType _queuedIncoherentBarrier;
private bool _queuedFeedbackLoopBarrier;
public BarrierBatch(VulkanRenderer gd)
{
@ -55,6 +53,17 @@ namespace Ryujinx.Graphics.Vulkan
stages |= PipelineStageFlags.TransformFeedbackBitExt;
}
if (!gd.IsTBDR)
{
// Desktop GPUs can transform image barriers into memory barriers.
access |= AccessFlags.DepthStencilAttachmentWriteBit | AccessFlags.ColorAttachmentWriteBit;
access |= AccessFlags.DepthStencilAttachmentReadBit | AccessFlags.ColorAttachmentReadBit;
stages |= PipelineStageFlags.EarlyFragmentTestsBit | PipelineStageFlags.LateFragmentTestsBit;
stages |= PipelineStageFlags.ColorAttachmentOutputBit;
}
return (access, stages);
}
@ -169,34 +178,16 @@ namespace Ryujinx.Graphics.Vulkan
}
_queuedIncoherentBarrier = IncoherentBarrierType.None;
_queuedFeedbackLoopBarrier = false;
}
else if (_feedbackLoopActive && _queuedFeedbackLoopBarrier)
{
// Feedback loop barrier.
MemoryBarrier barrier = new MemoryBarrier()
{
SType = StructureType.MemoryBarrier,
SrcAccessMask = AccessFlags.ShaderWriteBit,
DstAccessMask = AccessFlags.ShaderReadBit
};
QueueBarrier(barrier, PipelineStageFlags.FragmentShaderBit, PipelineStageFlags.AllGraphicsBit);
_queuedFeedbackLoopBarrier = false;
}
_feedbackLoopActive = false;
}
}
public unsafe void Flush(CommandBufferScoped cbs, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
{
Flush(cbs, null, false, inRenderPass, rpHolder, endRenderPass);
Flush(cbs, null, inRenderPass, rpHolder, endRenderPass);
}
public unsafe void Flush(CommandBufferScoped cbs, ShaderCollection program, bool feedbackLoopActive, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
public unsafe void Flush(CommandBufferScoped cbs, ShaderCollection program, bool inRenderPass, RenderPassHolder rpHolder, Action endRenderPass)
{
if (program != null)
{
@ -204,8 +195,6 @@ namespace Ryujinx.Graphics.Vulkan
_incoherentTextureWriteStages |= program.IncoherentTextureWriteStages;
}
_feedbackLoopActive |= feedbackLoopActive;
FlushMemoryBarrier(program, inRenderPass);
if (!inRenderPass && rpHolder != null)
@ -417,8 +406,6 @@ namespace Ryujinx.Graphics.Vulkan
{
_queuedIncoherentBarrier = type;
}
_queuedFeedbackLoopBarrier = true;
}
public void QueueTextureBarrier()

View file

@ -17,7 +17,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Vk _api;
private readonly Device _device;
private readonly Queue _queue;
private readonly object _queueLock;
private readonly Lock _queueLock;
private readonly bool _concurrentFenceWaitUnsupported;
private readonly CommandPool _pool;
private readonly Thread _owner;
@ -63,7 +63,7 @@ namespace Ryujinx.Graphics.Vulkan
Vk api,
Device device,
Queue queue,
object queueLock,
Lock queueLock,
uint queueFamilyIndex,
bool concurrentFenceWaitUnsupported,
bool isLight = false)

View file

@ -4,7 +4,6 @@ using Ryujinx.Graphics.Shader;
using Silk.NET.Vulkan;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using CompareOp = Ryujinx.Graphics.GAL.CompareOp;
@ -43,15 +42,15 @@ namespace Ryujinx.Graphics.Vulkan
private record struct TextureRef
{
public ShaderStage Stage;
public TextureView View;
public Auto<DisposableImageView> ImageView;
public TextureStorage Storage;
public Auto<DisposableImageView> View;
public Auto<DisposableSampler> Sampler;
public TextureRef(ShaderStage stage, TextureView view, Auto<DisposableImageView> imageView, Auto<DisposableSampler> sampler)
public TextureRef(ShaderStage stage, TextureStorage storage, Auto<DisposableImageView> view, Auto<DisposableSampler> sampler)
{
Stage = stage;
Storage = storage;
View = view;
ImageView = imageView;
Sampler = sampler;
}
}
@ -59,14 +58,14 @@ namespace Ryujinx.Graphics.Vulkan
private record struct ImageRef
{
public ShaderStage Stage;
public TextureView View;
public Auto<DisposableImageView> ImageView;
public TextureStorage Storage;
public Auto<DisposableImageView> View;
public ImageRef(ShaderStage stage, TextureView view, Auto<DisposableImageView> imageView)
public ImageRef(ShaderStage stage, TextureStorage storage, Auto<DisposableImageView> view)
{
Stage = stage;
Storage = storage;
View = view;
ImageView = imageView;
}
}
@ -124,8 +123,6 @@ namespace Ryujinx.Graphics.Vulkan
private readonly TextureView _dummyTexture;
private readonly SamplerHolder _dummySampler;
public List<TextureView> FeedbackLoopHazards { get; private set; }
public DescriptorSetUpdater(VulkanRenderer gd, Device device)
{
_gd = gd;
@ -210,15 +207,10 @@ namespace Ryujinx.Graphics.Vulkan
_templateUpdater = new();
}
public void Initialize(bool isMainPipeline)
public void Initialize()
{
MemoryOwner<byte> dummyTextureData = MemoryOwner<byte>.RentCleared(4);
_dummyTexture.SetData(dummyTextureData);
if (isMainPipeline)
{
FeedbackLoopHazards = new();
}
}
private static bool BindingOverlaps(ref DescriptorBufferInfo info, int bindingOffset, int offset, int size)
@ -281,18 +273,6 @@ namespace Ryujinx.Graphics.Vulkan
public void InsertBindingBarriers(CommandBufferScoped cbs)
{
if ((FeedbackLoopHazards?.Count ?? 0) > 0)
{
// Clear existing hazards - they will be rebuilt.
foreach (TextureView hazard in FeedbackLoopHazards)
{
hazard.DecrementHazardUses();
}
FeedbackLoopHazards.Clear();
}
foreach (ResourceBindingSegment segment in _program.BindingSegments[PipelineBase.TextureSetIndex])
{
if (segment.Type == ResourceType.TextureAndSampler)
@ -302,7 +282,7 @@ namespace Ryujinx.Graphics.Vulkan
for (int i = 0; i < segment.Count; i++)
{
ref var texture = ref _textureRefs[segment.Binding + i];
texture.View?.PrepareForUsage(cbs, texture.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
texture.Storage?.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, texture.Stage.ConvertToPipelineStageFlags());
}
}
else
@ -323,7 +303,7 @@ namespace Ryujinx.Graphics.Vulkan
for (int i = 0; i < segment.Count; i++)
{
ref var image = ref _imageRefs[segment.Binding + i];
image.View?.PrepareForUsage(cbs, image.Stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
image.Storage?.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, image.Stage.ConvertToPipelineStageFlags());
}
}
else
@ -397,12 +377,8 @@ namespace Ryujinx.Graphics.Vulkan
}
else if (image is TextureView view)
{
ref ImageRef iRef = ref _imageRefs[binding];
iRef.View?.ClearUsage(FeedbackLoopHazards);
view?.PrepareForUsage(cbs, stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
iRef = new(stage, view, view.GetIdentityImageView());
view.Storage.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags());
_imageRefs[binding] = new(stage, view.Storage, view.GetIdentityImageView());
}
else
{
@ -500,12 +476,9 @@ namespace Ryujinx.Graphics.Vulkan
}
else if (texture is TextureView view)
{
ref TextureRef iRef = ref _textureRefs[binding];
view.Storage.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags());
iRef.View?.ClearUsage(FeedbackLoopHazards);
view?.PrepareForUsage(cbs, stage.ConvertToPipelineStageFlags(), FeedbackLoopHazards);
iRef = new(stage, view, view.GetImageView(), ((SamplerHolder)sampler)?.GetSampler());
_textureRefs[binding] = new(stage, view.Storage, view.GetImageView(), ((SamplerHolder)sampler)?.GetSampler());
}
else
{
@ -527,7 +500,7 @@ namespace Ryujinx.Graphics.Vulkan
{
view.Storage.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, stage.ConvertToPipelineStageFlags());
_textureRefs[binding] = new(stage, view, view.GetIdentityImageView(), ((SamplerHolder)sampler)?.GetSampler());
_textureRefs[binding] = new(stage, view.Storage, view.GetIdentityImageView(), ((SamplerHolder)sampler)?.GetSampler());
SignalDirty(DirtyFlags.Texture);
}
@ -853,7 +826,7 @@ namespace Ryujinx.Graphics.Vulkan
ref var texture = ref textures[i];
ref var refs = ref _textureRefs[binding + i];
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
texture.ImageView = refs.View?.Get(cbs).Value ?? default;
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
if (texture.ImageView.Handle == 0)
@ -903,7 +876,7 @@ namespace Ryujinx.Graphics.Vulkan
for (int i = 0; i < count; i++)
{
images[i].ImageView = _imageRefs[binding + i].ImageView?.Get(cbs).Value ?? default;
images[i].ImageView = _imageRefs[binding + i].View?.Get(cbs).Value ?? default;
}
tu.Push<DescriptorImageInfo>(images[..count]);
@ -974,7 +947,7 @@ namespace Ryujinx.Graphics.Vulkan
ref var texture = ref textures[i];
ref var refs = ref _textureRefs[binding + i];
texture.ImageView = refs.ImageView?.Get(cbs).Value ?? default;
texture.ImageView = refs.View?.Get(cbs).Value ?? default;
texture.Sampler = refs.Sampler?.Get(cbs).Value ?? default;
if (texture.ImageView.Handle == 0)

View file

@ -1,12 +0,0 @@
using System;
namespace Ryujinx.Graphics.Vulkan
{
[Flags]
internal enum FeedbackLoopAspects
{
None = 0,
Color = 1 << 0,
Depth = 1 << 1,
}
}

View file

@ -68,7 +68,7 @@ namespace Ryujinx.Graphics.Vulkan
_optimalTable = new FormatFeatureFlags[totalFormats];
}
public bool BufferFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
public bool BufferFormatsSupport(FormatFeatureFlags flags, params ReadOnlySpan<Format> formats)
{
foreach (Format format in formats)
{
@ -81,7 +81,7 @@ namespace Ryujinx.Graphics.Vulkan
return true;
}
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params Format[] formats)
public bool OptimalFormatsSupport(FormatFeatureFlags flags, params ReadOnlySpan<Format> formats)
{
foreach (Format format in formats)
{

View file

@ -302,27 +302,6 @@ namespace Ryujinx.Graphics.Vulkan
_depthStencil?.Storage?.AddStoreOpUsage(true);
}
public void ClearBindings()
{
_depthStencil?.Storage.ClearBindings();
for (int i = 0; i < _colorsCanonical.Length; i++)
{
_colorsCanonical[i]?.Storage.ClearBindings();
}
}
public void AddBindings()
{
_depthStencil?.Storage.AddBinding(_depthStencil);
for (int i = 0; i < _colorsCanonical.Length; i++)
{
TextureView color = _colorsCanonical[i];
color?.Storage.AddBinding(color);
}
}
public (RenderPassHolder rpHolder, Auto<DisposableFramebuffer> framebuffer) GetPassAndFramebuffer(
VulkanRenderer gd,
Device device,

View file

@ -46,8 +46,6 @@ namespace Ryujinx.Graphics.Vulkan
public readonly bool SupportsViewportArray2;
public readonly bool SupportsHostImportedMemory;
public readonly bool SupportsDepthClipControl;
public readonly bool SupportsAttachmentFeedbackLoop;
public readonly bool SupportsDynamicAttachmentFeedbackLoop;
public readonly uint SubgroupSize;
public readonly SampleCountFlags SupportedSampleCounts;
public readonly PortabilitySubsetFlags PortabilitySubset;
@ -86,8 +84,6 @@ namespace Ryujinx.Graphics.Vulkan
bool supportsViewportArray2,
bool supportsHostImportedMemory,
bool supportsDepthClipControl,
bool supportsAttachmentFeedbackLoop,
bool supportsDynamicAttachmentFeedbackLoop,
uint subgroupSize,
SampleCountFlags supportedSampleCounts,
PortabilitySubsetFlags portabilitySubset,
@ -125,8 +121,6 @@ namespace Ryujinx.Graphics.Vulkan
SupportsViewportArray2 = supportsViewportArray2;
SupportsHostImportedMemory = supportsHostImportedMemory;
SupportsDepthClipControl = supportsDepthClipControl;
SupportsAttachmentFeedbackLoop = supportsAttachmentFeedbackLoop;
SupportsDynamicAttachmentFeedbackLoop = supportsDynamicAttachmentFeedbackLoop;
SubgroupSize = subgroupSize;
SupportedSampleCounts = supportedSampleCounts;
PortabilitySubset = portabilitySubset;

View file

@ -5,6 +5,7 @@ using Silk.NET.Vulkan;
using Silk.NET.Vulkan.Extensions.EXT;
using System;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.Graphics.Vulkan
{
@ -31,7 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Vk _api;
private readonly ExtExternalMemoryHost _hostMemoryApi;
private readonly Device _device;
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly List<HostMemoryAllocation> _allocations;
private readonly IntervalTree<ulong, HostMemoryAllocation> _allocationTree;

View file

@ -2,7 +2,6 @@ using Ryujinx.Graphics.GAL;
using Ryujinx.Graphics.Shader;
using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
@ -34,7 +33,6 @@ namespace Ryujinx.Graphics.Vulkan
public readonly Action EndRenderPassDelegate;
protected PipelineDynamicState DynamicState;
protected bool IsMainPipeline;
private PipelineState _newState;
private bool _graphicsStateDirty;
private bool _computeStateDirty;
@ -87,9 +85,6 @@ namespace Ryujinx.Graphics.Vulkan
private bool _tfEnabled;
private bool _tfActive;
private FeedbackLoopAspects _feedbackLoop;
private bool _passWritesDepthStencil;
private readonly PipelineColorBlendAttachmentState[] _storedBlend;
public ulong DrawCount { get; private set; }
public bool RenderPassActive { get; private set; }
@ -131,7 +126,7 @@ namespace Ryujinx.Graphics.Vulkan
public void Initialize()
{
_descriptorSetUpdater.Initialize(IsMainPipeline);
_descriptorSetUpdater.Initialize();
QuadsToTrisPattern = new IndexBufferPattern(Gd, 4, 6, 0, new[] { 0, 1, 2, 0, 2, 3 }, 4, false);
TriFanToTrisPattern = new IndexBufferPattern(Gd, 3, 3, 2, new[] { int.MinValue, -1, 0 }, 1, true);
@ -819,8 +814,6 @@ namespace Ryujinx.Graphics.Vulkan
_newState.DepthTestEnable = depthTest.TestEnable;
_newState.DepthWriteEnable = depthTest.WriteEnable;
_newState.DepthCompareOp = depthTest.Func.Convert();
UpdatePassDepthStencil();
SignalStateChange();
}
@ -1086,8 +1079,6 @@ namespace Ryujinx.Graphics.Vulkan
_newState.StencilFrontPassOp = stencilTest.FrontDpPass.Convert();
_newState.StencilFrontDepthFailOp = stencilTest.FrontDpFail.Convert();
_newState.StencilFrontCompareOp = stencilTest.FrontFunc.Convert();
UpdatePassDepthStencil();
SignalStateChange();
}
@ -1435,23 +1426,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
if (IsMainPipeline)
{
FramebufferParams?.ClearBindings();
}
FramebufferParams = new FramebufferParams(Device, colors, depthStencil);
if (IsMainPipeline)
{
FramebufferParams.AddBindings();
_newState.FeedbackLoopAspects = FeedbackLoopAspects.None;
_bindingBarriersDirty = true;
}
_passWritesDepthStencil = false;
UpdatePassDepthStencil();
UpdatePipelineAttachmentFormats();
}
@ -1518,82 +1493,11 @@ namespace Ryujinx.Graphics.Vulkan
}
}
Gd.Barriers.Flush(Cbs, _program, _feedbackLoop != 0, RenderPassActive, _rpHolder, EndRenderPassDelegate);
Gd.Barriers.Flush(Cbs, _program, RenderPassActive, _rpHolder, EndRenderPassDelegate);
_descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Compute);
}
private bool ChangeFeedbackLoop(FeedbackLoopAspects aspects)
{
if (_feedbackLoop != aspects)
{
if (Gd.Capabilities.SupportsDynamicAttachmentFeedbackLoop)
{
DynamicState.SetFeedbackLoop(aspects);
}
else
{
_newState.FeedbackLoopAspects = aspects;
}
_feedbackLoop = aspects;
return true;
}
return false;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private bool UpdateFeedbackLoop()
{
List<TextureView> hazards = _descriptorSetUpdater.FeedbackLoopHazards;
if ((hazards?.Count ?? 0) > 0)
{
FeedbackLoopAspects aspects = 0;
foreach (TextureView view in hazards)
{
// May need to enforce feedback loop layout here in the future.
// Though technically, it should always work with the general layout.
if (view.Info.Format.IsDepthOrStencil())
{
if (_passWritesDepthStencil)
{
// If depth/stencil isn't written in the pass, it doesn't count as a feedback loop.
aspects |= FeedbackLoopAspects.Depth;
}
}
else
{
aspects |= FeedbackLoopAspects.Color;
}
}
return ChangeFeedbackLoop(aspects);
}
else if (_feedbackLoop != 0)
{
return ChangeFeedbackLoop(FeedbackLoopAspects.None);
}
return false;
}
private void UpdatePassDepthStencil()
{
if (!RenderPassActive)
{
_passWritesDepthStencil = false;
}
// Stencil test being enabled doesn't necessarily mean a write, but it's not critical to check.
_passWritesDepthStencil |= (_newState.DepthTestEnable && _newState.DepthWriteEnable) || _newState.StencilTestEnable;
}
private bool RecreateGraphicsPipelineIfNeeded()
{
if (AutoFlush.ShouldFlushDraw(DrawCount))
@ -1601,7 +1505,7 @@ namespace Ryujinx.Graphics.Vulkan
Gd.FlushAllCommands();
}
DynamicState.ReplayIfDirty(Gd, CommandBuffer);
DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
if (_needsIndexBufferRebind && _indexBufferPattern == null)
{
@ -1635,15 +1539,7 @@ namespace Ryujinx.Graphics.Vulkan
_vertexBufferUpdater.Commit(Cbs);
}
if (_bindingBarriersDirty)
{
// Stale barriers may have been activated by switching program. Emit any that are relevant.
_descriptorSetUpdater.InsertBindingBarriers(Cbs);
_bindingBarriersDirty = false;
}
if (UpdateFeedbackLoop() || _graphicsStateDirty || Pbp != PipelineBindPoint.Graphics)
if (_graphicsStateDirty || Pbp != PipelineBindPoint.Graphics)
{
if (!CreatePipeline(PipelineBindPoint.Graphics))
{
@ -1652,9 +1548,17 @@ namespace Ryujinx.Graphics.Vulkan
_graphicsStateDirty = false;
Pbp = PipelineBindPoint.Graphics;
if (_bindingBarriersDirty)
{
// Stale barriers may have been activated by switching program. Emit any that are relevant.
_descriptorSetUpdater.InsertBindingBarriers(Cbs);
_bindingBarriersDirty = false;
}
}
Gd.Barriers.Flush(Cbs, _program, _feedbackLoop != 0, RenderPassActive, _rpHolder, EndRenderPassDelegate);
Gd.Barriers.Flush(Cbs, _program, RenderPassActive, _rpHolder, EndRenderPassDelegate);
_descriptorSetUpdater.UpdateAndBindDescriptorSets(Cbs, PipelineBindPoint.Graphics);

View file

@ -1,6 +1,5 @@
using Ryujinx.Common.Memory;
using Silk.NET.Vulkan;
using Silk.NET.Vulkan.Extensions.EXT;
namespace Ryujinx.Graphics.Vulkan
{
@ -22,8 +21,6 @@ namespace Ryujinx.Graphics.Vulkan
private Array4<float> _blendConstants;
private FeedbackLoopAspects _feedbackLoopAspects;
public uint ViewportsCount;
public Array16<Viewport> Viewports;
@ -35,8 +32,7 @@ namespace Ryujinx.Graphics.Vulkan
Scissor = 1 << 2,
Stencil = 1 << 3,
Viewport = 1 << 4,
FeedbackLoop = 1 << 5,
All = Blend | DepthBias | Scissor | Stencil | Viewport | FeedbackLoop,
All = Blend | DepthBias | Scissor | Stencil | Viewport,
}
private DirtyFlags _dirty;
@ -103,22 +99,13 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public void SetFeedbackLoop(FeedbackLoopAspects aspects)
{
_feedbackLoopAspects = aspects;
_dirty |= DirtyFlags.FeedbackLoop;
}
public void ForceAllDirty()
{
_dirty = DirtyFlags.All;
}
public void ReplayIfDirty(VulkanRenderer gd, CommandBuffer commandBuffer)
public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer)
{
Vk api = gd.Api;
if (_dirty.HasFlag(DirtyFlags.Blend))
{
RecordBlend(api, commandBuffer);
@ -144,11 +131,6 @@ namespace Ryujinx.Graphics.Vulkan
RecordViewport(api, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.FeedbackLoop) && gd.Capabilities.SupportsDynamicAttachmentFeedbackLoop)
{
RecordFeedbackLoop(gd.DynamicFeedbackLoopApi, commandBuffer);
}
_dirty = DirtyFlags.None;
}
@ -187,17 +169,5 @@ namespace Ryujinx.Graphics.Vulkan
api.CmdSetViewport(commandBuffer, 0, ViewportsCount, Viewports.AsSpan());
}
}
private readonly void RecordFeedbackLoop(ExtAttachmentFeedbackLoopDynamicState api, CommandBuffer commandBuffer)
{
ImageAspectFlags aspects = (_feedbackLoopAspects & FeedbackLoopAspects.Color) != 0 ? ImageAspectFlags.ColorBit : 0;
if ((_feedbackLoopAspects & FeedbackLoopAspects.Depth) != 0)
{
aspects |= ImageAspectFlags.DepthBit | ImageAspectFlags.StencilBit;
}
api.CmdSetAttachmentFeedbackLoopEnable(commandBuffer, aspects);
}
}
}

View file

@ -28,8 +28,6 @@ namespace Ryujinx.Graphics.Vulkan
_activeBufferMirrors = new();
CommandBuffer = (Cbs = gd.CommandBufferPool.Rent()).CommandBuffer;
IsMainPipeline = true;
}
private void CopyPendingQuery()
@ -237,7 +235,7 @@ namespace Ryujinx.Graphics.Vulkan
if (Pipeline != null && Pbp == PipelineBindPoint.Graphics)
{
DynamicState.ReplayIfDirty(Gd, CommandBuffer);
DynamicState.ReplayIfDirty(Gd.Api, CommandBuffer);
}
}

View file

@ -8,7 +8,6 @@ namespace Ryujinx.Graphics.Vulkan
struct PipelineState : IDisposable
{
private const int RequiredSubgroupSize = 32;
private const int MaxDynamicStatesCount = 9;
public PipelineUid Internal;
@ -300,12 +299,6 @@ namespace Ryujinx.Graphics.Vulkan
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFFFFFFFFBF) | ((value ? 1UL : 0UL) << 6);
}
public FeedbackLoopAspects FeedbackLoopAspects
{
readonly get => (FeedbackLoopAspects)((Internal.Id8 >> 7) & 0x3);
set => Internal.Id8 = (Internal.Id8 & 0xFFFFFFFFFFFFFE7F) | (((ulong)value) << 7);
}
public bool HasTessellationControlShader;
public NativeArray<PipelineShaderStageCreateInfo> Stages;
public PipelineLayout PipelineLayout;
@ -571,11 +564,9 @@ namespace Ryujinx.Graphics.Vulkan
}
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
bool supportsFeedbackLoopDynamicState = gd.Capabilities.SupportsDynamicAttachmentFeedbackLoop;
int dynamicStatesCount = supportsExtDynamicState ? 8 : 7;
DynamicState* dynamicStates = stackalloc DynamicState[MaxDynamicStatesCount];
int dynamicStatesCount = 7;
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
dynamicStates[0] = DynamicState.Viewport;
dynamicStates[1] = DynamicState.Scissor;
@ -587,12 +578,7 @@ namespace Ryujinx.Graphics.Vulkan
if (supportsExtDynamicState)
{
dynamicStates[dynamicStatesCount++] = DynamicState.VertexInputBindingStrideExt;
}
if (supportsFeedbackLoopDynamicState)
{
dynamicStates[dynamicStatesCount++] = DynamicState.AttachmentFeedbackLoopEnableExt;
dynamicStates[7] = DynamicState.VertexInputBindingStrideExt;
}
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo
@ -602,27 +588,9 @@ namespace Ryujinx.Graphics.Vulkan
PDynamicStates = dynamicStates,
};
PipelineCreateFlags flags = 0;
if (gd.Capabilities.SupportsAttachmentFeedbackLoop)
{
FeedbackLoopAspects aspects = FeedbackLoopAspects;
if ((aspects & FeedbackLoopAspects.Color) != 0)
{
flags |= PipelineCreateFlags.CreateColorAttachmentFeedbackLoopBitExt;
}
if ((aspects & FeedbackLoopAspects.Depth) != 0)
{
flags |= PipelineCreateFlags.CreateDepthStencilAttachmentFeedbackLoopBitExt;
}
}
var pipelineCreateInfo = new GraphicsPipelineCreateInfo
{
SType = StructureType.GraphicsPipelineCreateInfo,
Flags = flags,
StageCount = StagesCount,
PStages = Stages.Pointer,
PVertexInputState = &vertexInputState,

View file

@ -24,7 +24,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private ulong _accumulatedCounter;
private int _waiterCount;
private readonly object _lock = new();
private readonly Lock _lock = new();
private readonly Queue<BufferedQuery> _queryPool;
private readonly AutoResetEvent _queuedEvent = new(false);

View file

@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Vulkan.Queries
private bool _hostAccessReserved;
private int _refCount = 1; // Starts with a reference from the counter queue.
private readonly object _lock = new();
private readonly Lock _lock = new();
private ulong _result = ulong.MaxValue;
private double _divisor = 1f;

View file

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

View file

@ -5,6 +5,7 @@ using shaderc;
using Silk.NET.Vulkan;
using System;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
namespace Ryujinx.Graphics.Vulkan
@ -13,7 +14,7 @@ namespace Ryujinx.Graphics.Vulkan
{
// The shaderc.net dependency's Options constructor and dispose are not thread safe.
// Take this lock when using them.
private static readonly object _shaderOptionsLock = new();
private static readonly Lock _shaderOptionsLock = new();
private static readonly nint _ptrMainEntryPointName = Marshal.StringToHGlobalAnsi("main");

View file

@ -4,7 +4,6 @@ using Silk.NET.Vulkan;
using System;
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Format = Ryujinx.Graphics.GAL.Format;
using VkBuffer = Silk.NET.Vulkan.Buffer;
using VkFormat = Silk.NET.Vulkan.Format;
@ -13,11 +12,6 @@ namespace Ryujinx.Graphics.Vulkan
{
class TextureStorage : IDisposable
{
private struct TextureSliceInfo
{
public int BindCount;
}
private const MemoryPropertyFlags DefaultImageMemoryFlags =
MemoryPropertyFlags.DeviceLocalBit;
@ -49,7 +43,6 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Image _image;
private readonly Auto<DisposableImage> _imageAuto;
private readonly Auto<MemoryAllocation> _allocationAuto;
private readonly int _depthOrLayers;
private Auto<MemoryAllocation> _foreignAllocationAuto;
private Dictionary<Format, TextureStorage> _aliasedStorages;
@ -62,9 +55,6 @@ namespace Ryujinx.Graphics.Vulkan
private int _viewsCount;
private readonly ulong _size;
private int _bindCount;
private readonly TextureSliceInfo[] _slices;
public VkFormat VkFormat { get; }
public unsafe TextureStorage(
@ -83,7 +73,6 @@ namespace Ryujinx.Graphics.Vulkan
var depth = (uint)(info.Target == Target.Texture3D ? info.Depth : 1);
VkFormat = format;
_depthOrLayers = info.GetDepthOrLayers();
var type = info.Target.Convert();
@ -91,7 +80,7 @@ namespace Ryujinx.Graphics.Vulkan
var sampleCountFlags = ConvertToSampleCountFlags(gd.Capabilities.SupportedSampleCounts, (uint)info.Samples);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities);
var usage = GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample);
var flags = ImageCreateFlags.CreateMutableFormatBit | ImageCreateFlags.CreateExtendedUsageBit;
@ -159,8 +148,6 @@ namespace Ryujinx.Graphics.Vulkan
InitialTransition(ImageLayout.Preinitialized, ImageLayout.General);
}
_slices = new TextureSliceInfo[levels * _depthOrLayers];
}
public TextureStorage CreateAliasedColorForDepthStorageUnsafe(Format format)
@ -305,7 +292,7 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public static ImageUsageFlags GetImageUsage(Format format, Target target, in HardwareCapabilities capabilities)
public static ImageUsageFlags GetImageUsage(Format format, Target target, bool supportsMsStorage)
{
var usage = DefaultUsageFlags;
@ -318,19 +305,11 @@ namespace Ryujinx.Graphics.Vulkan
usage |= ImageUsageFlags.ColorAttachmentBit;
}
bool supportsMsStorage = capabilities.SupportsShaderStorageImageMultisample;
if (format.IsImageCompatible() && (supportsMsStorage || !target.IsMultisample()))
{
usage |= ImageUsageFlags.StorageBit;
}
if (capabilities.SupportsAttachmentFeedbackLoop &&
(usage & (ImageUsageFlags.DepthStencilAttachmentBit | ImageUsageFlags.ColorAttachmentBit)) != 0)
{
usage |= ImageUsageFlags.AttachmentFeedbackLoopBitExt;
}
return usage;
}
@ -531,55 +510,6 @@ namespace Ryujinx.Graphics.Vulkan
}
}
public void AddBinding(TextureView view)
{
// Assumes a view only has a first level.
int index = view.FirstLevel * _depthOrLayers + view.FirstLayer;
int layers = view.Layers;
for (int i = 0; i < layers; i++)
{
ref TextureSliceInfo info = ref _slices[index++];
info.BindCount++;
}
_bindCount++;
}
public void ClearBindings()
{
if (_bindCount != 0)
{
Array.Clear(_slices, 0, _slices.Length);
_bindCount = 0;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsBound(TextureView view)
{
if (_bindCount != 0)
{
int index = view.FirstLevel * _depthOrLayers + view.FirstLayer;
int layers = view.Layers;
for (int i = 0; i < layers; i++)
{
ref TextureSliceInfo info = ref _slices[index++];
if (info.BindCount != 0)
{
return true;
}
}
}
return false;
}
public void IncrementViewsCount()
{
_viewsCount++;

View file

@ -23,8 +23,6 @@ namespace Ryujinx.Graphics.Vulkan
private readonly Auto<DisposableImageView> _imageView2dArray;
private Dictionary<Format, TextureView> _selfManagedViews;
private int _hazardUses;
private readonly TextureCreateInfo _info;
private HashTableSlim<RenderPassCacheKey, RenderPassHolder> _renderPasses;
@ -62,7 +60,7 @@ namespace Ryujinx.Graphics.Vulkan
gd.Textures.Add(this);
var format = _gd.FormatCapabilities.ConvertToVkFormat(info.Format);
var usage = TextureStorage.GetImageUsage(info.Format, info.Target, gd.Capabilities);
var usage = TextureStorage.GetImageUsage(info.Format, info.Target, gd.Capabilities.SupportsShaderStorageImageMultisample);
var levels = (uint)info.Levels;
var layers = (uint)info.GetLayers();
@ -1036,34 +1034,6 @@ namespace Ryujinx.Graphics.Vulkan
throw new NotImplementedException();
}
public void PrepareForUsage(CommandBufferScoped cbs, PipelineStageFlags flags, List<TextureView> feedbackLoopHazards)
{
Storage.QueueWriteToReadBarrier(cbs, AccessFlags.ShaderReadBit, flags);
if (feedbackLoopHazards != null && Storage.IsBound(this))
{
feedbackLoopHazards.Add(this);
_hazardUses++;
}
}
public void ClearUsage(List<TextureView> feedbackLoopHazards)
{
if (_hazardUses != 0 && feedbackLoopHazards != null)
{
feedbackLoopHazards.Remove(this);
_hazardUses--;
}
}
public void DecrementHazardUses()
{
if (_hazardUses != 0)
{
_hazardUses--;
}
}
public (RenderPassHolder rpHolder, Auto<DisposableFramebuffer> framebuffer) GetPassAndFramebuffer(
VulkanRenderer gd,
Device device,

View file

@ -44,8 +44,6 @@ namespace Ryujinx.Graphics.Vulkan
"VK_EXT_4444_formats",
"VK_KHR_8bit_storage",
"VK_KHR_maintenance2",
"VK_EXT_attachment_feedback_loop_layout",
"VK_EXT_attachment_feedback_loop_dynamic_state",
};
private static readonly string[] _requiredExtensions = {
@ -359,28 +357,6 @@ namespace Ryujinx.Graphics.Vulkan
features2.PNext = &supportedFeaturesDepthClipControl;
}
PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT supportedFeaturesAttachmentFeedbackLoopLayout = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesExt,
PNext = features2.PNext,
};
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_layout"))
{
features2.PNext = &supportedFeaturesAttachmentFeedbackLoopLayout;
}
PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT supportedFeaturesDynamicAttachmentFeedbackLoopLayout = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesExt,
PNext = features2.PNext,
};
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_dynamic_state"))
{
features2.PNext = &supportedFeaturesDynamicAttachmentFeedbackLoopLayout;
}
PhysicalDeviceVulkan12Features supportedPhysicalDeviceVulkan12Features = new()
{
SType = StructureType.PhysicalDeviceVulkan12Features,
@ -555,36 +531,6 @@ namespace Ryujinx.Graphics.Vulkan
pExtendedFeatures = &featuresDepthClipControl;
}
PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT featuresAttachmentFeedbackLoopLayout;
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_layout") &&
supportedFeaturesAttachmentFeedbackLoopLayout.AttachmentFeedbackLoopLayout)
{
featuresAttachmentFeedbackLoopLayout = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesExt,
PNext = pExtendedFeatures,
AttachmentFeedbackLoopLayout = true,
};
pExtendedFeatures = &featuresAttachmentFeedbackLoopLayout;
}
PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT featuresDynamicAttachmentFeedbackLoopLayout;
if (physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_dynamic_state") &&
supportedFeaturesDynamicAttachmentFeedbackLoopLayout.AttachmentFeedbackLoopDynamicState)
{
featuresDynamicAttachmentFeedbackLoopLayout = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesExt,
PNext = pExtendedFeatures,
AttachmentFeedbackLoopDynamicState = true,
};
pExtendedFeatures = &featuresDynamicAttachmentFeedbackLoopLayout;
}
var enabledExtensions = _requiredExtensions.Union(_desirableExtensions.Intersect(physicalDevice.DeviceExtensions)).ToArray();
nint* ppEnabledExtensions = stackalloc nint[enabledExtensions.Length];

View file

@ -11,6 +11,7 @@ using Silk.NET.Vulkan.Extensions.KHR;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Format = Ryujinx.Graphics.GAL.Format;
using PrimitiveTopology = Ryujinx.Graphics.GAL.PrimitiveTopology;
using SamplerCreateInfo = Ryujinx.Graphics.GAL.SamplerCreateInfo;
@ -40,13 +41,12 @@ namespace Ryujinx.Graphics.Vulkan
internal KhrPushDescriptor PushDescriptorApi { get; private set; }
internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; }
internal ExtAttachmentFeedbackLoopDynamicState DynamicFeedbackLoopApi { get; private set; }
internal uint QueueFamilyIndex { get; private set; }
internal Queue Queue { get; private set; }
internal Queue BackgroundQueue { get; private set; }
internal object BackgroundQueueLock { get; private set; }
internal object QueueLock { get; private set; }
internal Lock BackgroundQueueLock { get; private set; }
internal Lock QueueLock { get; private set; }
internal MemoryAllocator MemoryAllocator { get; private set; }
internal HostMemoryAllocator HostMemoryAllocator { get; private set; }
@ -154,16 +154,11 @@ namespace Ryujinx.Graphics.Vulkan
DrawIndirectCountApi = drawIndirectCountApi;
}
if (Api.TryGetDeviceExtension(_instance.Instance, _device, out ExtAttachmentFeedbackLoopDynamicState dynamicFeedbackLoopApi))
{
DynamicFeedbackLoopApi = dynamicFeedbackLoopApi;
}
if (maxQueueCount >= 2)
{
Api.GetDeviceQueue(_device, queueFamilyIndex, 1, out var backgroundQueue);
BackgroundQueue = backgroundQueue;
BackgroundQueueLock = new object();
BackgroundQueueLock = new();
}
PhysicalDeviceProperties2 properties2 = new()
@ -253,16 +248,6 @@ namespace Ryujinx.Graphics.Vulkan
SType = StructureType.PhysicalDeviceDepthClipControlFeaturesExt,
};
PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesEXT featuresAttachmentFeedbackLoop = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopLayoutFeaturesExt,
};
PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesEXT featuresDynamicAttachmentFeedbackLoop = new()
{
SType = StructureType.PhysicalDeviceAttachmentFeedbackLoopDynamicStateFeaturesExt,
};
PhysicalDevicePortabilitySubsetFeaturesKHR featuresPortabilitySubset = new()
{
SType = StructureType.PhysicalDevicePortabilitySubsetFeaturesKhr,
@ -299,22 +284,6 @@ namespace Ryujinx.Graphics.Vulkan
features2.PNext = &featuresDepthClipControl;
}
bool supportsAttachmentFeedbackLoop = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_layout");
if (supportsAttachmentFeedbackLoop)
{
featuresAttachmentFeedbackLoop.PNext = features2.PNext;
features2.PNext = &featuresAttachmentFeedbackLoop;
}
bool supportsDynamicAttachmentFeedbackLoop = _physicalDevice.IsDeviceExtensionPresent("VK_EXT_attachment_feedback_loop_dynamic_state");
if (supportsDynamicAttachmentFeedbackLoop)
{
featuresDynamicAttachmentFeedbackLoop.PNext = features2.PNext;
features2.PNext = &featuresDynamicAttachmentFeedbackLoop;
}
bool usePortability = _physicalDevice.IsDeviceExtensionPresent("VK_KHR_portability_subset");
if (usePortability)
@ -437,8 +406,6 @@ namespace Ryujinx.Graphics.Vulkan
_physicalDevice.IsDeviceExtensionPresent("VK_NV_viewport_array2"),
_physicalDevice.IsDeviceExtensionPresent(ExtExternalMemoryHost.ExtensionName),
supportsDepthClipControl && featuresDepthClipControl.DepthClipControl,
supportsAttachmentFeedbackLoop && featuresAttachmentFeedbackLoop.AttachmentFeedbackLoopLayout,
supportsDynamicAttachmentFeedbackLoop && featuresDynamicAttachmentFeedbackLoop.AttachmentFeedbackLoopDynamicState,
propertiesSubgroup.SubgroupSize,
supportedSampleCounts,
portabilityFlags,
@ -496,7 +463,7 @@ namespace Ryujinx.Graphics.Vulkan
Api.GetDeviceQueue(_device, queueFamilyIndex, 0, out var queue);
Queue = queue;
QueueLock = new object();
QueueLock = new();
LoadFeatures(maxQueueCount, queueFamilyIndex);

View file

@ -22,6 +22,7 @@ using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using Path = System.IO.Path;
namespace Ryujinx.HLE.FileSystem
@ -55,7 +56,7 @@ namespace Ryujinx.HLE.FileSystem
private readonly VirtualFileSystem _virtualFileSystem;
private readonly object _lock = new();
private readonly Lock _lock = new();
public ContentManager(VirtualFileSystem virtualFileSystem)
{
@ -396,7 +397,7 @@ namespace Ryujinx.HLE.FileSystem
if (locationList != null)
{
LocationEntry entry =
locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
locationList.ToList().FirstOrDefault(x => x.TitleId == titleId && x.ContentType == contentType);
if (entry.ContentPath != null)
{
@ -424,7 +425,7 @@ namespace Ryujinx.HLE.FileSystem
{
LinkedList<LocationEntry> locationList = _locationEntries[storageId];
return locationList.ToList().Find(x => x.TitleId == titleId && x.ContentType == contentType);
return locationList.ToList().FirstOrDefault(x => x.TitleId == titleId && x.ContentType == contentType);
}
public void InstallFirmware(string firmwareSource)
@ -719,7 +720,7 @@ namespace Ryujinx.HLE.FileSystem
if (updateNcas.TryGetValue(SystemUpdateTitleId, out var ncaEntry))
{
string metaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
string metaPath = ncaEntry.FirstOrDefault(x => x.type == NcaContentType.Meta).path;
CnmtContentMetaEntry[] metaEntries = null;
@ -755,7 +756,7 @@ namespace Ryujinx.HLE.FileSystem
if (updateNcas.TryGetValue(SystemVersionTitleId, out var updateNcasItem))
{
string versionEntry = updateNcasItem.Find(x => x.type != NcaContentType.Meta).path;
string versionEntry = updateNcasItem.FirstOrDefault(x => x.type != NcaContentType.Meta).path;
using Stream ncaStream = GetZipStream(archive.GetEntry(versionEntry));
Nca nca = new(_virtualFileSystem.KeySet, ncaStream.AsStorage());
@ -774,9 +775,9 @@ namespace Ryujinx.HLE.FileSystem
{
if (updateNcas.TryGetValue(metaEntry.TitleId, out ncaEntry))
{
metaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
metaPath = ncaEntry.FirstOrDefault(x => x.type == NcaContentType.Meta).path;
string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path;
string contentPath = ncaEntry.FirstOrDefault(x => x.type != NcaContentType.Meta).path;
// Nintendo in 9.0.0, removed PPC and only kept the meta nca of it.
// This is a perfect valid case, so we should just ignore the missing content nca and continue.
@ -915,8 +916,8 @@ namespace Ryujinx.HLE.FileSystem
{
if (updateNcas.TryGetValue(metaEntry.TitleId, out var ncaEntry))
{
string metaNcaPath = ncaEntry.Find(x => x.type == NcaContentType.Meta).path;
string contentPath = ncaEntry.Find(x => x.type != NcaContentType.Meta).path;
string metaNcaPath = ncaEntry.FirstOrDefault(x => x.type == NcaContentType.Meta).path;
string contentPath = ncaEntry.FirstOrDefault(x => x.type != NcaContentType.Meta).path;
// Nintendo in 9.0.0, removed PPC and only kept the meta nca of it.
// This is a perfect valid case, so we should just ignore the missing content nca and continue.

View file

@ -46,7 +46,7 @@ namespace Ryujinx.HLE.FileSystem
continue;
}
string ncaId = BitConverter.ToString(entry.NcaId).Replace("-", null).ToLower();
string ncaId = Convert.ToHexStringLower(entry.NcaId).Replace("-", null);
Nca nca = _pfs.GetNca(keySet, $"/{ncaId}.nca");
if (nca.GetProgramIndex() == programIndex)

View file

@ -14,6 +14,7 @@ using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
namespace Ryujinx.HLE.HOS.Applets
{
@ -62,7 +63,7 @@ namespace Ryujinx.HLE.HOS.Applets
private bool _canAcceptController = false;
private KeyboardInputMode _inputMode = KeyboardInputMode.ControllerAndKeyboard;
private readonly object _lock = new();
private readonly Lock _lock = new();
public event EventHandler AppletStateChanged;

View file

@ -6,6 +6,7 @@ using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
{
@ -21,7 +22,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
const string CancelText = "Cancel";
const string ControllerToggleText = "Toggle input";
private readonly object _bufferLock = new();
private readonly Lock _bufferLock = new();
private RenderingSurfaceInfo _surfaceInfo = null;
private SKImageInfo _imageInfo;

View file

@ -27,7 +27,7 @@ namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
private TRef<bool> _cancelled = null;
private Thread _thread = null;
private readonly object _lock = new();
private readonly Lock _lock = new();
public bool IsRunning
{

View file

@ -2,6 +2,7 @@ using Ryujinx.Common;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.Horizon.Common;
using System.Collections.Generic;
using System.Threading;
namespace Ryujinx.HLE.HOS.Kernel.Common
{
@ -14,7 +15,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
private readonly long[] _current2;
private readonly long[] _peak;
private readonly object _lock;
private readonly object _lock = new();
private readonly LinkedList<KThread> _waitingThreads;
@ -27,8 +28,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Common
_current2 = new long[(int)LimitableResource.Count];
_peak = new long[(int)LimitableResource.Count];
_lock = new object();
_waitingThreads = new LinkedList<KThread>();
}

View file

@ -4,6 +4,7 @@ using Ryujinx.HLE.HOS.Kernel.Process;
using Ryujinx.Horizon.Common;
using System;
using System.Diagnostics;
using System.Threading;
namespace Ryujinx.HLE.HOS.Kernel.Memory
{
@ -11,7 +12,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
{
public KProcess Owner { get; private set; }
private readonly KPageList _pageList;
private readonly object _lock;
private readonly Lock _lock = new();
private ulong _address;
private bool _isOwnerMapped;
private bool _isMapped;
@ -19,7 +20,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Memory
public KCodeMemory(KernelContext context) : base(context)
{
_pageList = new KPageList();
_lock = new object();
}
public Result Initialize(ulong address, ulong size)

View file

@ -40,8 +40,8 @@ namespace Ryujinx.HLE.HOS.Kernel.Process
public ProcessState State { get; private set; }
private readonly object _processLock = new();
private readonly object _threadingLock = new();
private readonly Lock _processLock = new();
private readonly Lock _threadingLock = new();
public KAddressArbiter AddressArbiter { get; private set; }

View file

@ -200,7 +200,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
WakeThreads(_condVarThreads, count, TryAcquireMutex, x => x.CondVarAddress == address);
if (!_condVarThreads.Exists(x => x.CondVarAddress == address))
if (!_condVarThreads.Any(x => x.CondVarAddress == address))
{
KernelTransfer.KernelToUser(address, 0);
}

View file

@ -5,7 +5,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
class KCriticalSection
{
private readonly KernelContext _context;
private readonly object _lock;
private readonly object _lock = new();
private int _recursionCount;
public object Lock => _lock;
@ -13,7 +13,6 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public KCriticalSection(KernelContext context)
{
_context = context;
_lock = new object();
}
public void Enter()

View file

@ -112,7 +112,7 @@ namespace Ryujinx.HLE.HOS.Kernel.Threading
public bool WaitingInArbitration { get; set; }
private readonly object _activityOperationLock = new();
private readonly Lock _activityOperationLock = new();
public KThread(KernelContext context) : base(context)
{

View file

@ -168,7 +168,7 @@ namespace Ryujinx.HLE.HOS
if (StrEquals(RomfsDir, modDir.Name))
{
var modData = modMetadata.Mods.Find(x => modDir.FullName.Contains(x.Path));
var modData = modMetadata.Mods.FirstOrDefault(x => modDir.FullName.Contains(x.Path));
var enabled = modData?.Enabled ?? true;
mods.RomfsDirs.Add(mod = new Mod<DirectoryInfo>(dir.Name, modDir, enabled));
@ -176,7 +176,7 @@ namespace Ryujinx.HLE.HOS
}
else if (StrEquals(ExefsDir, modDir.Name))
{
var modData = modMetadata.Mods.Find(x => modDir.FullName.Contains(x.Path));
var modData = modMetadata.Mods.FirstOrDefault(x => modDir.FullName.Contains(x.Path));
var enabled = modData?.Enabled ?? true;
mods.ExefsDirs.Add(mod = new Mod<DirectoryInfo>(dir.Name, modDir, enabled));
@ -275,7 +275,7 @@ namespace Ryujinx.HLE.HOS
var fsFile = new FileInfo(Path.Combine(applicationDir.FullName, RomfsContainer));
if (fsFile.Exists)
{
var modData = modMetadata.Mods.Find(x => fsFile.FullName.Contains(x.Path));
var modData = modMetadata.Mods.FirstOrDefault(x => fsFile.FullName.Contains(x.Path));
var enabled = modData == null || modData.Enabled;
mods.RomfsContainers.Add(new Mod<FileInfo>($"<{applicationDir.Name} RomFs>", fsFile, enabled));
@ -284,7 +284,7 @@ namespace Ryujinx.HLE.HOS
fsFile = new FileInfo(Path.Combine(applicationDir.FullName, ExefsContainer));
if (fsFile.Exists)
{
var modData = modMetadata.Mods.Find(x => fsFile.FullName.Contains(x.Path));
var modData = modMetadata.Mods.FirstOrDefault(x => fsFile.FullName.Contains(x.Path));
var enabled = modData == null || modData.Enabled;
mods.ExefsContainers.Add(new Mod<FileInfo>($"<{applicationDir.Name} ExeFs>", fsFile, enabled));
@ -403,7 +403,7 @@ namespace Ryujinx.HLE.HOS
}
// Assumes searchDirPaths don't overlap
private static void CollectMods(Dictionary<ulong, ModCache> modCaches, PatchCache patches, params string[] searchDirPaths)
private static void CollectMods(Dictionary<ulong, ModCache> modCaches, PatchCache patches, params ReadOnlySpan<string> searchDirPaths)
{
static bool IsPatchesDir(string name) => StrEquals(AmsNsoPatchDir, name) ||
StrEquals(AmsNroPatchDir, name) ||
@ -453,7 +453,7 @@ namespace Ryujinx.HLE.HOS
patches.Initialized = true;
}
public void CollectMods(IEnumerable<ulong> applications, params string[] searchDirPaths)
public void CollectMods(IEnumerable<ulong> applications, params ReadOnlySpan<string> searchDirPaths)
{
Clear();
@ -680,7 +680,7 @@ namespace Ryujinx.HLE.HOS
ApplyProgramPatches(nroPatches, 0, nro);
}
internal bool ApplyNsoPatches(ulong applicationId, params IExecutable[] programs)
internal bool ApplyNsoPatches(ulong applicationId, params ReadOnlySpan<IExecutable> programs)
{
IEnumerable<Mod<DirectoryInfo>> nsoMods = _patches.NsoPatches;
@ -744,7 +744,7 @@ namespace Ryujinx.HLE.HOS
}
}
private static bool ApplyProgramPatches(IEnumerable<Mod<DirectoryInfo>> mods, int protectedOffset, params IExecutable[] programs)
private static bool ApplyProgramPatches(IEnumerable<Mod<DirectoryInfo>> mods, int protectedOffset, params ReadOnlySpan<IExecutable> programs)
{
int count = 0;
@ -755,12 +755,18 @@ namespace Ryujinx.HLE.HOS
patches[i] = new MemPatch();
}
var buildIds = programs.Select(p => p switch
var buildIds = new List<string>(programs.Length);
foreach (IExecutable p in programs)
{
NsoExecutable nso => Convert.ToHexString(nso.BuildId.ItemsRo.ToArray()).TrimEnd('0'),
NroExecutable nro => Convert.ToHexString(nro.Header.BuildId).TrimEnd('0'),
_ => string.Empty,
}).ToList();
var buildId = p switch
{
NsoExecutable nso => Convert.ToHexString(nso.BuildId.ItemsRo.ToArray()).TrimEnd('0'),
NroExecutable nro => Convert.ToHexString(nro.Header.BuildId).TrimEnd('0'),
_ => string.Empty,
};
buildIds.Add(buildId);
}
int GetIndex(string buildId) => buildIds.FindIndex(id => id == buildId); // O(n) but list is small

View file

@ -4,6 +4,7 @@ using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy.Types;
using Ryujinx.Horizon.Common;
using System;
using System.Threading;
namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
{
@ -17,7 +18,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
private KEvent _accumulatedSuspendedTickChangedEvent;
private int _accumulatedSuspendedTickChangedEventHandle;
private readonly object _fatalSectionLock = new();
private readonly Lock _fatalSectionLock = new();
private int _fatalSectionCount;
// TODO: Set this when the game goes in suspension (go back to home menu ect), we currently don't support that so we can keep it set to 0.

View file

@ -123,7 +123,7 @@ namespace Ryujinx.HLE.HOS.Services.Hid
return true;
}
public void Configure(params ControllerConfig[] configs)
public void Configure(params ReadOnlySpan<ControllerConfig> configs)
{
_configuredTypes = new ControllerType[MaxControllers];

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