Compare commits

...

16 Commits

Author SHA1 Message Date
TSRBerry
141cf61ff7 CI: Run git_short_hash inside of bash (#3808) 2022-10-29 19:00:08 +00:00
Wunk
3fe3598d41 Vulkan: Replace VK_EXT_debug_report usage with VK_EXT_debug_utils (#3802)
* Vulkan: Replace `VK_EXT_debug_report` usage with `VK_EXT_debug_utils`

[VK_EXT_debug_report](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_debug_report.html)
has been depreciated for quite some time now in favor of the much more
featureful
[VK_EXT_debug_utils](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VK_EXT_debug_utils.html)
extension.

This PR converts our debug-report-callback into the newer
debug-messenger pattern.

`VK_EXT_debug_utils` adds some additional diagnostic tooling for marking
debug-label scopes for queue-operations, command-buffers, and assigning
name-labels to vulkan objects to aid in debugging(for a later PR).

* Vulkan: Fix `DebugMessenger` severity-flag classification

Extension bits between the two flags, for reference:

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDebugUtilsMessageSeverityFlagBitsEXT.html

https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDebugReportFlagBitsEXT.html
2022-10-29 14:09:25 -03:00
gdkchan
59cdf310bd SPIR-V: Fix tessellation control shader output types (#3807)
* SPIR-V: Fix tessellation control shader output types

* Shader cache version bump
2022-10-29 13:45:30 -03:00
dependabot[bot]
4e34170a84 nuget: bump System.IdentityModel.Tokens.Jwt from 6.15.0 to 6.25.0 (#3806)
Bumps [System.IdentityModel.Tokens.Jwt](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet) from 6.15.0 to 6.25.0.
- [Release notes](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/releases)
- [Changelog](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/AzureAD/azure-activedirectory-identitymodel-extensions-for-dotnet/commits)

---
updated-dependencies:
- dependency-name: System.IdentityModel.Tokens.Jwt
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-29 10:46:46 +02:00
Luke Warner
d540af5dc0 AppletAE: stub SetRecordVolumeMuted (#3804)
* Update IIrSensorServer.cs

* Update IIrSensorServer.cs

* Apply suggestions from code review

Addressed formatting feedback

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update IIrSensorServer.cs

* Update ISelfController.cs

* Update ISelfController.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2022-10-27 23:15:57 +00:00
Luke Warner
f7c7b66fc0 hid/irs: Stub StopImageProcessorAsync (#3799)
* Update IIrSensorServer.cs

* Update IIrSensorServer.cs

* Apply suggestions from code review

Addressed formatting feedback

Co-authored-by: Ac_K <Acoustik666@gmail.com>

* Update IIrSensorServer.cs

Co-authored-by: Ac_K <Acoustik666@gmail.com>
2022-10-27 21:36:37 +00:00
gdkchan
28ba55598d Vulkan: Fix indirect buffer barrier (#3798) 2022-10-26 14:53:11 -03:00
riperiperi
9719b6a112 Vulkan: Use dynamic state for blend constants (#3793) 2022-10-25 23:49:23 +00:00
VocalFan
f70236f947 Updated Compatibility info and GPU info (Vulkan, SPIRV, and Texture Recompression) (#3568)
* Updated Compatibility info and GPU info (Vulkan, SPIRV, and Texture Recompression)

* Added Mutant's changes.

Co-authored-by: MutantAura <44103205+MutantAura@users.noreply.github.com>

* Five to four.

* Fixed github's terrible conflict diffs

Co-authored-by: MutantAura <44103205+MutantAura@users.noreply.github.com>
2022-10-24 16:40:39 +00:00
merry
eafadf10c7 Ryujinx.Tests.Unicorn: Implement IDisposable (#3794)
Dispose unicorn when done
2022-10-23 23:51:54 +00:00
Mary-nyan
9b06ee7736 Attempt to fix issues since github-script v6 upgrade 2022-10-23 17:15:15 +02:00
Emmanuel Hansen
baba2c2467 Avalonia: Use overlay dialog for controller applet (#3777)
* use overlay dialog for controller applet

* Update Ryujinx.Ava/Ui/Controls/ContentDialogHelper.cs

Co-authored-by: riperiperi <rhy3756547@hotmail.com>

Co-authored-by: riperiperi <rhy3756547@hotmail.com>
2022-10-23 11:15:45 +02:00
dependabot[bot]
286e5d39b2 nuget: bump SPB from 0.0.4-build24 to 0.0.4-build27 (#3791)
Bumps [SPB](https://github.com/Thog/SPB) from 0.0.4-build24 to 0.0.4-build27.
- [Release notes](https://github.com/Thog/SPB/releases)
- [Commits](https://github.com/Thog/SPB/commits)

---
updated-dependencies:
- dependency-name: SPB
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-10-22 10:32:12 +02:00
TSRBerry
dc529c1181 ci: Add updates for nuget packages to dependabot (#3786) 2022-10-21 14:23:16 +02:00
TSRBerry
c7cf1cbc35 CI: Update workflows (#3774)
* ci: Update workflows

* gha: Add no-build switch to test action
2022-10-21 10:31:38 +02:00
TSRBerry
d8e487d018 gha: Add dependabot.yml (#3778) 2022-10-21 10:16:28 +02:00
26 changed files with 337 additions and 137 deletions

24
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,24 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: weekly
labels:
- "infra"
reviewers:
- marysaka
commit-message:
prefix: "ci"
- package-ecosystem: nuget
directory: /
open-pull-requests-limit: 5
schedule:
interval: daily
labels:
- "infra"
reviewers:
- marysaka
commit-message:
prefix: nuget

View File

@@ -48,21 +48,22 @@ jobs:
DOTNET_CLI_TELEMETRY_OPTOUT: 1 DOTNET_CLI_TELEMETRY_OPTOUT: 1
RYUJINX_BASE_VERSION: "1.1.0" RYUJINX_BASE_VERSION: "1.1.0"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v1 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: 6.0.x dotnet-version: 6.0.x
- name: Ensure NuGet Source - name: Ensure NuGet Source
uses: fabriciomurta/ensure-nuget-source@v1 uses: fabriciomurta/ensure-nuget-source@v1
- name: Get git short hash - name: Get git short hash
id: git_short_hash id: git_short_hash
run: echo "::set-output name=result::$(git rev-parse --short "${{ github.sha }}")" run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash
- name: Clear - name: Clear
run: dotnet clean && dotnet nuget locals all --clear run: dotnet clean && dotnet nuget locals all --clear
- name: Build - name: Build
run: dotnet build -c "${{ matrix.configuration }}" /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER run: dotnet build -c "${{ matrix.configuration }}" /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER
- name: Test - name: Test
run: dotnet test -c "${{ matrix.configuration }}" run: dotnet test --no-build -c "${{ matrix.configuration }}"
- name: Publish Ryujinx - name: Publish Ryujinx
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish /p:Version="${{ env.RYUJINX_BASE_VERSION }}" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx --self-contained
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
@@ -73,19 +74,19 @@ jobs:
run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava /p:Version="1.0.0" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava run: dotnet publish -c "${{ matrix.configuration }}" -r "${{ matrix.DOTNET_RUNTIME_IDENTIFIER }}" -o ./publish_ava /p:Version="1.0.0" /p:DebugType=embedded /p:SourceRevisionId="${{ steps.git_short_hash.outputs.result }}" /p:ExtraDefineConstants=DISABLE_UPDATER Ryujinx.Ava
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Upload Ryujinx artifact - name: Upload Ryujinx artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} name: ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish path: publish
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Upload Ryujinx.Headless.SDL2 artifact - name: Upload Ryujinx.Headless.SDL2 artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} name: sdl2-ryujinx-headless-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_sdl2_headless path: publish_sdl2_headless
if: github.event_name == 'pull_request' if: github.event_name == 'pull_request'
- name: Upload Ryujinx.Ava artifact - name: Upload Ryujinx.Ava artifact
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v3
with: with:
name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }} name: ava-ryujinx-${{ matrix.configuration }}-${{ env.RYUJINX_BASE_VERSION }}+${{ steps.git_short_hash.outputs.result }}-${{ matrix.RELEASE_ZIP_OS_NAME }}
path: publish_ava path: publish_ava

View File

@@ -8,7 +8,7 @@ jobs:
if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/github-script@v3 - uses: actions/github-script@v6
with: with:
script: | script: |
const {owner, repo} = context.repo; const {owner, repo} = context.repo;
@@ -16,7 +16,7 @@ jobs:
const pull_head_sha = '${{github.event.workflow_run.head_sha}}'; const pull_head_sha = '${{github.event.workflow_run.head_sha}}';
const issue_number = await (async () => { const issue_number = await (async () => {
const pulls = await github.pulls.list({owner, repo}); const pulls = await github.rest.pulls.list({owner, repo});
for await (const {data} of github.paginate.iterator(pulls)) { for await (const {data} of github.paginate.iterator(pulls)) {
for (const pull of data) { for (const pull of data) {
if (pull.head.sha === pull_head_sha) { if (pull.head.sha === pull_head_sha) {
@@ -31,7 +31,7 @@ jobs:
return core.error(`No matching pull request found`); return core.error(`No matching pull request found`);
} }
const {data: {artifacts}} = await github.actions.listWorkflowRunArtifacts({owner, repo, run_id}); const {data: {artifacts}} = await github.rest.actions.listWorkflowRunArtifacts({owner, repo, run_id});
if (!artifacts.length) { if (!artifacts.length) {
return core.error(`No artifacts found`); return core.error(`No artifacts found`);
} }
@@ -57,12 +57,12 @@ jobs:
body += hidden_headless_artifacts; body += hidden_headless_artifacts;
body += hidden_debug_artifacts; body += hidden_debug_artifacts;
const {data: comments} = await github.issues.listComments({repo, owner, issue_number}); const {data: comments} = await github.rest.issues.listComments({repo, owner, issue_number});
const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]'); const existing_comment = comments.find((c) => c.user.login === 'github-actions[bot]');
if (existing_comment) { if (existing_comment) {
core.info(`Updating comment ${existing_comment.id}`); core.info(`Updating comment ${existing_comment.id}`);
await github.issues.updateComment({repo, owner, comment_id: existing_comment.id, body}); await github.rest.issues.updateComment({repo, owner, comment_id: existing_comment.id, body});
} else { } else {
core.info(`Creating a comment`); core.info(`Creating a comment`);
await github.issues.createComment({repo, owner, issue_number, body}); await github.rest.issues.createComment({repo, owner, issue_number, body});
} }

View File

@@ -25,8 +25,8 @@ jobs:
RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master" RYUJINX_TARGET_RELEASE_CHANNEL_REPO: "release-channel-master"
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- uses: actions/setup-dotnet@v1 - uses: actions/setup-dotnet@v3
with: with:
dotnet-version: 6.0.x dotnet-version: 6.0.x
- name: Ensure NuGet Source - name: Ensure NuGet Source
@@ -36,8 +36,8 @@ jobs:
- name: Get version info - name: Get version info
id: version_info id: version_info
run: | run: |
echo "::set-output name=build_version::${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" echo "build_version=${{ env.RYUJINX_BASE_VERSION }}.${{ github.run_number }}" >> $GITHUB_OUTPUT
echo "::set-output name=git_short_hash::$(git rev-parse --short "${{ github.sha }}")" echo "git_short_hash=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT
shell: bash shell: bash
- name: Configure for release - name: Configure for release
run: | run: |

View File

@@ -36,8 +36,8 @@
## Compatibility ## Compatibility
As of October 2022, Ryujinx has been tested on approximately 3,600 titles; over 3,500 boot past menus and into gameplay, with roughly 3,000 of those being considered playable. You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). As of October 2022, Ryujinx has been tested on approximately 3,700 titles; over 3,500 boot past menus and into gameplay, with roughly 3,000 of those being considered playable.
Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already! You can check out the compatibility list [here](https://github.com/Ryujinx/Ryujinx-Games-List/issues). Anyone is free to submit a new game test or update an existing game test entry; simply follow the new issue template and testing guidelines, or post as a reply to the applicable game issue. Use the search function to see if a game has been tested already!
## Usage ## Usage
@@ -90,7 +90,7 @@ Ryujinx system files are stored in the `Ryujinx` folder. This folder is located
- **GPU** - **GPU**
The GPU emulator emulates the Switch's Maxwell GPU using the OpenGL API (version 4.5 minimum) through a custom build of OpenTK. There are currently four graphics enhancements available to the end user in Ryujinx: disk shader caching, resolution scaling, aspect ratio adjustment and anisotropic filtering. These enhancements can be adjusted or toggled as desired in the GUI. The GPU emulator emulates the Switch's Maxwell GPU using either the OpenGL (version 4.5 minimum) or Vulkan APIs through a custom build of OpenTK or Silk.NET respectively. There are currently four graphics enhancements available to the end user in Ryujinx: Disk Shader Caching, Resolution Scaling, Aspect Ratio Adjustment, and Anisotropic Filtering. These enhancements can be adjusted or toggled as desired in the GUI.
- **Input** - **Input**

View File

@@ -34,7 +34,7 @@
<PackageReference Include="Silk.NET.Vulkan" Version="2.10.1" /> <PackageReference Include="Silk.NET.Vulkan" Version="2.10.1" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.10.1" /> <PackageReference Include="Silk.NET.Vulkan.Extensions.EXT" Version="2.10.1" />
<PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.10.1" /> <PackageReference Include="Silk.NET.Vulkan.Extensions.KHR" Version="2.10.1" />
<PackageReference Include="SPB" Version="0.0.4-build24" /> <PackageReference Include="SPB" Version="0.0.4-build27" />
<PackageReference Include="SharpZipLib" Version="1.3.3" /> <PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
</ItemGroup> </ItemGroup>

View File

@@ -4,6 +4,7 @@ using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Threading; using Avalonia.Threading;
using FluentAvalonia.Core;
using FluentAvalonia.UI.Controls; using FluentAvalonia.UI.Controls;
using Ryujinx.Ava.Common.Locale; using Ryujinx.Ava.Common.Locale;
using Ryujinx.Ava.Ui.Models; using Ryujinx.Ava.Ui.Models;
@@ -27,7 +28,10 @@ namespace Ryujinx.Ava.Ui.Controls
string secondaryButton, string secondaryButton,
string closeButton, string closeButton,
int iconSymbol, int iconSymbol,
UserResult primaryButtonResult = UserResult.Ok) UserResult primaryButtonResult = UserResult.Ok,
ManualResetEvent deferResetEvent = null,
Func<Window, Task> doWhileDeferred = null,
TypedEventHandler<ContentDialog, ContentDialogButtonClickEventArgs> deferCloseAction = null)
{ {
UserResult result = UserResult.None; UserResult result = UserResult.None;
@@ -110,12 +114,19 @@ namespace Ryujinx.Ava.Ui.Controls
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() => contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
{ {
result = UserResult.No; result = UserResult.No;
contentDialog.PrimaryButtonClick -= deferCloseAction;
}); });
contentDialog.CloseButtonCommand = MiniCommand.Create(() => contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
{ {
result = UserResult.Cancel; result = UserResult.Cancel;
contentDialog.PrimaryButtonClick -= deferCloseAction;
}); });
if (deferResetEvent != null)
{
contentDialog.PrimaryButtonClick += deferCloseAction;
}
await contentDialog.ShowAsync(ContentDialogPlacement.Popup); await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
overlay?.Close(); overlay?.Close();
@@ -143,35 +154,20 @@ namespace Ryujinx.Ava.Ui.Controls
Func<Window, Task> doWhileDeferred = null) Func<Window, Task> doWhileDeferred = null)
{ {
bool startedDeferring = false; bool startedDeferring = false;
UserResult result = UserResult.None; UserResult result = UserResult.None;
ContentDialog contentDialog = new ContentDialog return await ShowContentDialog(
{ title,
Title = title, primaryText,
PrimaryButtonText = primaryButton, secondaryText,
SecondaryButtonText = secondaryButton, primaryButton,
CloseButtonText = closeButton, secondaryButton,
Content = CreateDialogTextContent(primaryText, secondaryText, iconSymbol), closeButton,
PrimaryButtonCommand = MiniCommand.Create(() => iconSymbol,
{ primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok,
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok; deferResetEvent,
}), doWhileDeferred,
}; DeferClose);
contentDialog.SecondaryButtonCommand = MiniCommand.Create(() =>
{
contentDialog.PrimaryButtonClick -= DeferClose;
result = UserResult.No;
});
contentDialog.CloseButtonCommand = MiniCommand.Create(() =>
{
contentDialog.PrimaryButtonClick -= DeferClose;
result = UserResult.Cancel;
});
contentDialog.PrimaryButtonClick += DeferClose;
await contentDialog.ShowAsync(ContentDialogPlacement.Popup);
return result;
async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args) async void DeferClose(ContentDialog sender, ContentDialogButtonClickEventArgs args)
{ {
@@ -180,7 +176,7 @@ namespace Ryujinx.Ava.Ui.Controls
return; return;
} }
contentDialog.PrimaryButtonClick -= DeferClose; sender.PrimaryButtonClick -= DeferClose;
startedDeferring = true; startedDeferring = true;
@@ -188,7 +184,7 @@ namespace Ryujinx.Ava.Ui.Controls
result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok; result = primaryButton == LocaleManager.Instance["InputDialogYes"] ? UserResult.Yes : UserResult.Ok;
contentDialog.PrimaryButtonClick -= DeferClose; sender.PrimaryButtonClick -= DeferClose;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() => Task.Run(() =>

View File

@@ -22,7 +22,7 @@ namespace Ryujinx.Graphics.Gpu.Shader.DiskCache
private const ushort FileFormatVersionMajor = 1; private const ushort FileFormatVersionMajor = 1;
private const ushort FileFormatVersionMinor = 2; private const ushort FileFormatVersionMinor = 2;
private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor; private const uint FileFormatVersionPacked = ((uint)FileFormatVersionMajor << 16) | FileFormatVersionMinor;
private const uint CodeGenVersion = 3781; private const uint CodeGenVersion = 3807;
private const string SharedTocFileName = "shared.toc"; private const string SharedTocFileName = "shared.toc";
private const string SharedDataFileName = "shared.data"; private const string SharedDataFileName = "shared.data";

View File

@@ -262,6 +262,13 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
Instruction ioVariable, elemIndex; Instruction ioVariable, elemIndex;
Instruction invocationId = null;
if (Config.Stage == ShaderStage.TessellationControl && isOutAttr)
{
invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]);
}
bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd; bool isUserAttr = attr >= AttributeConsts.UserAttributeBase && attr < AttributeConsts.UserAttributeEnd;
if (isUserAttr && if (isUserAttr &&
@@ -273,7 +280,17 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex()); elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
var vecIndex = Constant(TypeU32(), (attr - AttributeConsts.UserAttributeBase) >> 4); var vecIndex = Constant(TypeU32(), (attr - AttributeConsts.UserAttributeBase) >> 4);
if (AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr)) bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr);
if (invocationId != null && isArray)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex);
}
else if (invocationId != null)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex);
}
else if (isArray)
{ {
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex); return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
} }
@@ -307,13 +324,30 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
bool isIndexed = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr) && (!attrInfo.IsBuiltin || AttributeInfo.IsArrayBuiltIn(attr)); bool isIndexed = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr) && (!attrInfo.IsBuiltin || AttributeInfo.IsArrayBuiltIn(attr));
if ((type & (AggregateType.Array | AggregateType.Vector)) == 0) if ((type & (AggregateType.Array | AggregateType.Vector)) == 0)
{
if (invocationId != null)
{
return isIndexed
? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index)
: AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId);
}
else
{ {
return isIndexed ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index) : ioVariable; return isIndexed ? AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index) : ioVariable;
} }
}
elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex()); elemIndex = Constant(TypeU32(), attrInfo.GetInnermostIndex());
if (isIndexed) if (invocationId != null && isIndexed)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, elemIndex);
}
else if (invocationId != null)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, elemIndex);
}
else if (isIndexed)
{ {
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, elemIndex); return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, elemIndex);
} }
@@ -327,12 +361,29 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
{ {
var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input; var storageClass = isOutAttr ? StorageClass.Output : StorageClass.Input;
Instruction invocationId = null;
if (Config.Stage == ShaderStage.TessellationControl && isOutAttr)
{
invocationId = Load(TypeS32(), Inputs[AttributeConsts.InvocationId]);
}
elemType = AggregateType.FP32; elemType = AggregateType.FP32;
var ioVariable = isOutAttr ? OutputsArray : InputsArray; var ioVariable = isOutAttr ? OutputsArray : InputsArray;
var vecIndex = ShiftRightLogical(TypeS32(), attrIndex, Constant(TypeS32(), 2)); var vecIndex = ShiftRightLogical(TypeS32(), attrIndex, Constant(TypeS32(), 2));
var elemIndex = BitwiseAnd(TypeS32(), attrIndex, Constant(TypeS32(), 3)); var elemIndex = BitwiseAnd(TypeS32(), attrIndex, Constant(TypeS32(), 3));
if (AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr)) bool isArray = AttributeInfo.IsArrayAttributeSpirv(Config.Stage, isOutAttr);
if (invocationId != null && isArray)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, index, vecIndex, elemIndex);
}
else if (invocationId != null)
{
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, invocationId, vecIndex, elemIndex);
}
else if (isArray)
{ {
return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex); return AccessChain(TypePointer(storageClass, GetType(elemType)), ioVariable, index, vecIndex, elemIndex);
} }

View File

@@ -473,6 +473,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4); var attrType = context.TypeVector(context.TypeFP32(), (LiteralInteger)4);
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes)); attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)MaxAttributes));
if (context.Config.Stage == ShaderStage.TessellationControl)
{
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
}
var spvType = context.TypePointer(StorageClass.Output, attrType); var spvType = context.TypePointer(StorageClass.Output, attrType);
var spvVar = context.Variable(spvType, StorageClass.Output); var spvVar = context.Variable(spvType, StorageClass.Output);
@@ -543,6 +548,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
} }
} }
if (context.Config.Stage == ShaderStage.TessellationControl && isOutAttr && !perPatch)
{
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
}
var spvType = context.TypePointer(storageClass, attrType); var spvType = context.TypePointer(storageClass, attrType);
var spvVar = context.Variable(spvType, storageClass); var spvVar = context.Variable(spvType, storageClass);
@@ -634,6 +644,11 @@ namespace Ryujinx.Graphics.Shader.CodeGen.Spirv
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize)); attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), (LiteralInteger)arraySize));
} }
if (context.Config.Stage == ShaderStage.TessellationControl && isOutAttr)
{
attrType = context.TypeArray(attrType, context.Constant(context.TypeU32(), context.Config.ThreadsPerInputPrimitive));
}
var spvType = context.TypePointer(storageClass, attrType); var spvType = context.TypePointer(storageClass, attrType);
var spvVar = context.Variable(spvType, storageClass); var spvVar = context.Variable(spvType, storageClass);

View File

@@ -37,7 +37,12 @@ namespace Ryujinx.Graphics.Shader.StructuredIr
Config = config; Config = config;
if (config.GpPassthrough) if (config.Stage == ShaderStage.TessellationControl)
{
// Required to index outputs.
Info.Inputs.Add(AttributeConsts.InvocationId);
}
else if (config.GpPassthrough)
{ {
int passthroughAttributes = config.PassthroughAttributes; int passthroughAttributes = config.PassthroughAttributes;
while (passthroughAttributes != 0) while (passthroughAttributes != 0)

View File

@@ -12,13 +12,12 @@ namespace Ryujinx.Graphics.Vulkan
private const int MaxUpdateBufferSize = 0x10000; private const int MaxUpdateBufferSize = 0x10000;
public const AccessFlags DefaultAccessFlags = public const AccessFlags DefaultAccessFlags =
AccessFlags.AccessIndirectCommandReadBit |
AccessFlags.AccessShaderReadBit | AccessFlags.AccessShaderReadBit |
AccessFlags.AccessShaderWriteBit | AccessFlags.AccessShaderWriteBit |
AccessFlags.AccessTransferReadBit | AccessFlags.AccessTransferReadBit |
AccessFlags.AccessTransferWriteBit | AccessFlags.AccessTransferWriteBit |
AccessFlags.AccessUniformReadBit | AccessFlags.AccessUniformReadBit;
AccessFlags.AccessShaderReadBit |
AccessFlags.AccessShaderWriteBit;
private readonly VulkanRenderer _gd; private readonly VulkanRenderer _gd;
private readonly Device _device; private readonly Device _device;

View File

@@ -228,10 +228,26 @@ namespace Ryujinx.Graphics.Vulkan
Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect); Gd.Api.CmdClearAttachments(CommandBuffer, 1, &attachment, 1, &clearRect);
} }
public void CommandBufferBarrier() public unsafe void CommandBufferBarrier()
{ {
// TODO: More specific barrier? MemoryBarrier memoryBarrier = new MemoryBarrier()
Barrier(); {
SType = StructureType.MemoryBarrier,
SrcAccessMask = BufferHolder.DefaultAccessFlags,
DstAccessMask = AccessFlags.AccessIndirectCommandReadBit
};
Gd.Api.CmdPipelineBarrier(
CommandBuffer,
PipelineStageFlags.PipelineStageAllCommandsBit,
PipelineStageFlags.PipelineStageDrawIndirectBit,
0,
1,
memoryBarrier,
0,
null,
0,
null);
} }
public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size) public void CopyBuffer(BufferHandle source, BufferHandle destination, int srcOffset, int dstOffset, int size)
@@ -535,10 +551,11 @@ namespace Ryujinx.Graphics.Vulkan
vkBlend = new PipelineColorBlendAttachmentState(); vkBlend = new PipelineColorBlendAttachmentState();
} }
_newState.BlendConstantR = blend.BlendConstant.Red; DynamicState.SetBlendConstants(
_newState.BlendConstantG = blend.BlendConstant.Green; blend.BlendConstant.Red,
_newState.BlendConstantB = blend.BlendConstant.Blue; blend.BlendConstant.Green,
_newState.BlendConstantA = blend.BlendConstant.Alpha; blend.BlendConstant.Blue,
blend.BlendConstant.Alpha);
SignalStateChange(); SignalStateChange();
} }

View File

@@ -135,11 +135,6 @@ namespace Ryujinx.Graphics.Vulkan
// It is assumed that Dynamic State is enabled when this conversion is used. // It is assumed that Dynamic State is enabled when this conversion is used.
pipeline.BlendConstantA = state.BlendDescriptors[0].BlendConstant.Alpha;
pipeline.BlendConstantB = state.BlendDescriptors[0].BlendConstant.Blue;
pipeline.BlendConstantG = state.BlendDescriptors[0].BlendConstant.Green;
pipeline.BlendConstantR = state.BlendDescriptors[0].BlendConstant.Red;
pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone; pipeline.CullMode = state.CullEnable ? state.CullMode.Convert() : CullModeFlags.CullModeNone;
pipeline.DepthBoundsTestEnable = false; // Not implemented. pipeline.DepthBoundsTestEnable = false; // Not implemented.

View File

@@ -19,21 +19,34 @@ namespace Ryujinx.Graphics.Vulkan
private uint _frontWriteMask; private uint _frontWriteMask;
private uint _frontReference; private uint _frontReference;
private Array4<float> _blendConstants;
public int ViewportsCount; public int ViewportsCount;
public Array16<Viewport> Viewports; public Array16<Viewport> Viewports;
private enum DirtyFlags private enum DirtyFlags
{ {
None = 0, None = 0,
DepthBias = 1 << 0, Blend = 1 << 0,
Scissor = 1 << 1, DepthBias = 1 << 1,
Stencil = 1 << 2, Scissor = 1 << 2,
Viewport = 1 << 3, Stencil = 1 << 3,
All = DepthBias | Scissor | Stencil | Viewport Viewport = 1 << 4,
All = Blend | DepthBias | Scissor | Stencil | Viewport
} }
private DirtyFlags _dirty; private DirtyFlags _dirty;
public void SetBlendConstants(float r, float g, float b, float a)
{
_blendConstants[0] = r;
_blendConstants[1] = g;
_blendConstants[2] = b;
_blendConstants[3] = a;
_dirty |= DirtyFlags.Blend;
}
public void SetDepthBias(float slopeFactor, float constantFactor, float clamp) public void SetDepthBias(float slopeFactor, float constantFactor, float clamp)
{ {
_depthBiasSlopeFactor = slopeFactor; _depthBiasSlopeFactor = slopeFactor;
@@ -87,6 +100,11 @@ namespace Ryujinx.Graphics.Vulkan
public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer) public void ReplayIfDirty(Vk api, CommandBuffer commandBuffer)
{ {
if (_dirty.HasFlag(DirtyFlags.Blend))
{
RecordBlend(api, commandBuffer);
}
if (_dirty.HasFlag(DirtyFlags.DepthBias)) if (_dirty.HasFlag(DirtyFlags.DepthBias))
{ {
RecordDepthBias(api, commandBuffer); RecordDepthBias(api, commandBuffer);
@@ -110,6 +128,11 @@ namespace Ryujinx.Graphics.Vulkan
_dirty = DirtyFlags.None; _dirty = DirtyFlags.None;
} }
private void RecordBlend(Vk api, CommandBuffer commandBuffer)
{
api.CmdSetBlendConstants(commandBuffer, _blendConstants.AsSpan());
}
private void RecordDepthBias(Vk api, CommandBuffer commandBuffer) private void RecordDepthBias(Vk api, CommandBuffer commandBuffer)
{ {
api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor); api.CmdSetDepthBias(commandBuffer, _depthBiasConstantFactor, _depthBiasClamp, _depthBiasSlopeFactor);

View File

@@ -499,7 +499,7 @@ namespace Ryujinx.Graphics.Vulkan
colorBlendState.BlendConstants[3] = BlendConstantA; colorBlendState.BlendConstants[3] = BlendConstantA;
bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState; bool supportsExtDynamicState = gd.Capabilities.SupportsExtendedDynamicState;
int dynamicStatesCount = supportsExtDynamicState ? 8 : 7; int dynamicStatesCount = supportsExtDynamicState ? 9 : 8;
DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount]; DynamicState* dynamicStates = stackalloc DynamicState[dynamicStatesCount];
@@ -510,10 +510,11 @@ namespace Ryujinx.Graphics.Vulkan
dynamicStates[4] = DynamicState.StencilCompareMask; dynamicStates[4] = DynamicState.StencilCompareMask;
dynamicStates[5] = DynamicState.StencilWriteMask; dynamicStates[5] = DynamicState.StencilWriteMask;
dynamicStates[6] = DynamicState.StencilReference; dynamicStates[6] = DynamicState.StencilReference;
dynamicStates[7] = DynamicState.BlendConstants;
if (supportsExtDynamicState) if (supportsExtDynamicState)
{ {
dynamicStates[7] = DynamicState.VertexInputBindingStrideExt; dynamicStates[8] = DynamicState.VertexInputBindingStrideExt;
} }
var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo() var pipelineDynamicStateCreateInfo = new PipelineDynamicStateCreateInfo()

View File

@@ -53,7 +53,7 @@ namespace Ryujinx.Graphics.Vulkan
"VUID-VkSubpassDependency-srcSubpass-00867" "VUID-VkSubpassDependency-srcSubpass-00867"
}; };
internal static Instance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions, out ExtDebugReport debugReport, out DebugReportCallbackEXT debugReportCallback) internal static Instance CreateInstance(Vk api, GraphicsDebugLevel logLevel, string[] requiredExtensions, out ExtDebugUtils debugUtils, out DebugUtilsMessengerEXT debugUtilsMessenger)
{ {
var enabledLayers = new List<string>(); var enabledLayers = new List<string>();
@@ -89,7 +89,7 @@ namespace Ryujinx.Graphics.Vulkan
AddAvailableLayer("VK_LAYER_KHRONOS_validation"); AddAvailableLayer("VK_LAYER_KHRONOS_validation");
} }
var enabledExtensions = requiredExtensions.Append(ExtDebugReport.ExtensionName).ToArray(); var enabledExtensions = requiredExtensions.Append(ExtDebugUtils.ExtensionName).ToArray();
var appName = Marshal.StringToHGlobalAnsi(AppName); var appName = Marshal.StringToHGlobalAnsi(AppName);
@@ -139,22 +139,18 @@ namespace Ryujinx.Graphics.Vulkan
Marshal.FreeHGlobal(ppEnabledLayers[i]); Marshal.FreeHGlobal(ppEnabledLayers[i]);
} }
CreateDebugCallbacks(api, logLevel, instance, out debugReport, out debugReportCallback); CreateDebugMessenger(api, logLevel, instance, out debugUtils, out debugUtilsMessenger);
return instance; return instance;
} }
private unsafe static uint DebugReport( private unsafe static uint DebugMessenger(
uint flags, DebugUtilsMessageSeverityFlagsEXT messageSeverity,
DebugReportObjectTypeEXT objectType, DebugUtilsMessageTypeFlagsEXT messageTypes,
ulong @object, DebugUtilsMessengerCallbackDataEXT* pCallbackData,
nuint location, void* pUserData)
int messageCode,
byte* layerPrefix,
byte* message,
void* userData)
{ {
var msg = Marshal.PtrToStringAnsi((IntPtr)message); var msg = Marshal.PtrToStringAnsi((IntPtr)pCallbackData->PMessage);
foreach (string excludedMessagePart in _excludedMessages) foreach (string excludedMessagePart in _excludedMessages)
{ {
@@ -164,26 +160,20 @@ namespace Ryujinx.Graphics.Vulkan
} }
} }
DebugReportFlagsEXT debugFlags = (DebugReportFlagsEXT)flags; if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt))
if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportErrorBitExt))
{ {
Logger.Error?.Print(LogClass.Gpu, msg); Logger.Error?.Print(LogClass.Gpu, msg);
//throw new Exception(msg); //throw new Exception(msg);
} }
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportWarningBitExt)) else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt))
{ {
Logger.Warning?.Print(LogClass.Gpu, msg); Logger.Warning?.Print(LogClass.Gpu, msg);
} }
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportInformationBitExt)) else if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt))
{ {
Logger.Info?.Print(LogClass.Gpu, msg); Logger.Info?.Print(LogClass.Gpu, msg);
} }
else if (debugFlags.HasFlag(DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt)) else // if (messageSeverity.HasFlag(DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt))
{
Logger.Warning?.Print(LogClass.Gpu, msg);
}
else
{ {
Logger.Debug?.Print(LogClass.Gpu, msg); Logger.Debug?.Print(LogClass.Gpu, msg);
} }
@@ -551,46 +541,59 @@ namespace Ryujinx.Graphics.Vulkan
return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex); return new CommandBufferPool(api, device, queue, queueLock, queueFamilyIndex);
} }
internal unsafe static void CreateDebugCallbacks( internal unsafe static void CreateDebugMessenger(
Vk api, Vk api,
GraphicsDebugLevel logLevel, GraphicsDebugLevel logLevel,
Instance instance, Instance instance,
out ExtDebugReport debugReport, out ExtDebugUtils debugUtils,
out DebugReportCallbackEXT debugReportCallback) out DebugUtilsMessengerEXT debugUtilsMessenger)
{ {
debugReport = default; debugUtils = default;
if (logLevel != GraphicsDebugLevel.None) if (logLevel != GraphicsDebugLevel.None)
{ {
if (!api.TryGetInstanceExtension(instance, out debugReport)) if (!api.TryGetInstanceExtension(instance, out debugUtils))
{ {
debugReportCallback = default; debugUtilsMessenger = default;
return; return;
} }
var flags = logLevel switch var filterLogType = logLevel switch
{ {
GraphicsDebugLevel.Error => DebugReportFlagsEXT.DebugReportErrorBitExt, GraphicsDebugLevel.Error => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt,
GraphicsDebugLevel.Slowdowns => DebugReportFlagsEXT.DebugReportErrorBitExt | DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt, GraphicsDebugLevel.Slowdowns => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt |
GraphicsDebugLevel.All => DebugReportFlagsEXT.DebugReportInformationBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt,
DebugReportFlagsEXT.DebugReportWarningBitExt | GraphicsDebugLevel.All => DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeGeneralBitExt |
DebugReportFlagsEXT.DebugReportPerformanceWarningBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypeValidationBitExt |
DebugReportFlagsEXT.DebugReportErrorBitExt | DebugUtilsMessageTypeFlagsEXT.DebugUtilsMessageTypePerformanceBitExt,
DebugReportFlagsEXT.DebugReportDebugBitExt,
_ => throw new ArgumentException($"Invalid log level \"{logLevel}\".") _ => throw new ArgumentException($"Invalid log level \"{logLevel}\".")
}; };
var debugReportCallbackCreateInfo = new DebugReportCallbackCreateInfoEXT()
var filterLogSeverity = logLevel switch
{ {
SType = StructureType.DebugReportCallbackCreateInfoExt, GraphicsDebugLevel.Error => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt,
Flags = flags, GraphicsDebugLevel.Slowdowns => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt |
PfnCallback = new PfnDebugReportCallbackEXT(DebugReport) DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt,
GraphicsDebugLevel.All => DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityInfoBitExt |
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityWarningBitExt |
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityVerboseBitExt |
DebugUtilsMessageSeverityFlagsEXT.DebugUtilsMessageSeverityErrorBitExt,
_ => throw new ArgumentException($"Invalid log level \"{logLevel}\".")
}; };
debugReport.CreateDebugReportCallback(instance, in debugReportCallbackCreateInfo, null, out debugReportCallback).ThrowOnError(); var debugUtilsMessengerCreateInfo = new DebugUtilsMessengerCreateInfoEXT()
{
SType = StructureType.DebugUtilsMessengerCreateInfoExt,
MessageType = filterLogType,
MessageSeverity = filterLogSeverity,
PfnUserCallback = new PfnDebugUtilsMessengerCallbackEXT(DebugMessenger)
};
debugUtils.CreateDebugUtilsMessenger(instance, in debugUtilsMessengerCreateInfo, null, out debugUtilsMessenger).ThrowOnError();
} }
else else
{ {
debugReportCallback = default; debugUtilsMessenger = default;
} }
} }
} }

View File

@@ -33,7 +33,7 @@ namespace Ryujinx.Graphics.Vulkan
internal KhrPushDescriptor PushDescriptorApi { get; private set; } internal KhrPushDescriptor PushDescriptorApi { get; private set; }
internal ExtTransformFeedback TransformFeedbackApi { get; private set; } internal ExtTransformFeedback TransformFeedbackApi { get; private set; }
internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; } internal KhrDrawIndirectCount DrawIndirectCountApi { get; private set; }
internal ExtDebugReport DebugReportApi { get; private set; } internal ExtDebugUtils DebugUtilsApi { get; private set; }
internal uint QueueFamilyIndex { get; private set; } internal uint QueueFamilyIndex { get; private set; }
internal Queue Queue { get; private set; } internal Queue Queue { get; private set; }
@@ -57,7 +57,7 @@ namespace Ryujinx.Graphics.Vulkan
private SyncManager _syncManager; private SyncManager _syncManager;
private PipelineFull _pipeline; private PipelineFull _pipeline;
private DebugReportCallbackEXT _debugReportCallback; private DebugUtilsMessengerEXT _debugUtilsMessenger;
internal HelperShader HelperShader { get; private set; } internal HelperShader HelperShader { get; private set; }
internal PipelineFull PipelineInternal => _pipeline; internal PipelineFull PipelineInternal => _pipeline;
@@ -237,9 +237,9 @@ namespace Ryujinx.Graphics.Vulkan
Api = api; Api = api;
_instance = VulkanInitialization.CreateInstance(api, logLevel, _getRequiredExtensions(), out ExtDebugReport debugReport, out _debugReportCallback); _instance = VulkanInitialization.CreateInstance(api, logLevel, _getRequiredExtensions(), out ExtDebugUtils debugUtils, out _debugUtilsMessenger);
DebugReportApi = debugReport; DebugUtilsApi = debugUtils;
if (api.TryGetInstanceExtension(_instance, out KhrSurface surfaceApi)) if (api.TryGetInstanceExtension(_instance, out KhrSurface surfaceApi))
{ {
@@ -584,9 +584,9 @@ namespace Ryujinx.Graphics.Vulkan
MemoryAllocator.Dispose(); MemoryAllocator.Dispose();
if (_debugReportCallback.Handle != 0) if (_debugUtilsMessenger.Handle != 0)
{ {
DebugReportApi.DestroyDebugReportCallback(_instance, _debugReportCallback, null); DebugUtilsApi.DestroyDebugUtilsMessenger(_instance, _debugUtilsMessenger, null);
} }
foreach (var shader in Shaders) foreach (var shader in Shaders)

View File

@@ -32,6 +32,7 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
private bool _handlesRequestToDisplay = false; private bool _handlesRequestToDisplay = false;
private bool _autoSleepDisabled = false; private bool _autoSleepDisabled = false;
private bool _albumImageTakenNotificationEnabled = false; private bool _albumImageTakenNotificationEnabled = false;
private bool _recordVolumeMuted = false;
private uint _screenShotImageOrientation = 0; private uint _screenShotImageOrientation = 0;
private uint _idleTimeDetectionExtension = 0; private uint _idleTimeDetectionExtension = 0;
@@ -389,5 +390,18 @@ namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.Sys
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(130)] // 13.0.0+
// SetRecordVolumeMuted(b8)
public ResultCode SetRecordVolumeMuted(ServiceCtx context)
{
bool recordVolumeMuted = context.RequestData.ReadBoolean();
Logger.Stub?.PrintStub(LogClass.ServiceAm, new { recordVolumeMuted });
_recordVolumeMuted = recordVolumeMuted;
return ResultCode.Success;
}
} }
} }

View File

@@ -203,6 +203,18 @@ namespace Ryujinx.HLE.HOS.Services.Hid.Irs
return ResultCode.Success; return ResultCode.Success;
} }
[CommandHipc(318)] // 4.0.0+
// StopImageProcessorAsync(nn::irsensor::IrCameraHandle, nn::applet::AppletResourceUserId, pid)
public ResultCode StopImageProcessorAsync(ServiceCtx context)
{
int irCameraHandle = context.RequestData.ReadInt32();
long appletResourceUserId = context.RequestData.ReadInt64();
Logger.Stub?.PrintStub(LogClass.ServiceIrs, new { appletResourceUserId, irCameraHandle });
return ResultCode.Success;
}
[CommandHipc(319)] // 4.0.0+ [CommandHipc(319)] // 4.0.0+
// ActivateIrsensorWithFunctionLevel(nn::applet::AppletResourceUserId, nn::irsensor::PackedFunctionLevel, pid) // ActivateIrsensorWithFunctionLevel(nn::applet::AppletResourceUserId, nn::irsensor::PackedFunctionLevel, pid)
public ResultCode ActivateIrsensorWithFunctionLevel(ServiceCtx context) public ResultCode ActivateIrsensorWithFunctionLevel(ServiceCtx context)

View File

@@ -26,7 +26,7 @@
<PackageReference Include="MsgPack.Cli" Version="1.0.1" /> <PackageReference Include="MsgPack.Cli" Version="1.0.1" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" /> <PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta11" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.15.0" /> <PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="6.25.0" />
</ItemGroup> </ItemGroup>
<!-- Due to Concentus. --> <!-- Due to Concentus. -->

View File

@@ -3,9 +3,10 @@ using System;
namespace Ryujinx.Tests.Unicorn namespace Ryujinx.Tests.Unicorn
{ {
public class UnicornAArch32 public class UnicornAArch32 : IDisposable
{ {
internal readonly IntPtr uc; internal readonly IntPtr uc;
private bool _isDisposed = false;
public IndexedProperty<int, uint> R public IndexedProperty<int, uint> R
{ {
@@ -106,8 +107,23 @@ namespace Ryujinx.Tests.Unicorn
} }
~UnicornAArch32() ~UnicornAArch32()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{ {
Interface.Checked(Native.Interface.uc_close(uc)); Interface.Checked(Native.Interface.uc_close(uc));
_isDisposed = true;
}
} }
public void RunForCount(ulong count) public void RunForCount(ulong count)

View File

@@ -3,9 +3,10 @@ using System;
namespace Ryujinx.Tests.Unicorn namespace Ryujinx.Tests.Unicorn
{ {
public class UnicornAArch64 public class UnicornAArch64 : IDisposable
{ {
internal readonly IntPtr uc; internal readonly IntPtr uc;
private bool _isDisposed = false;
public IndexedProperty<int, ulong> X public IndexedProperty<int, ulong> X
{ {
@@ -95,8 +96,23 @@ namespace Ryujinx.Tests.Unicorn
} }
~UnicornAArch64() ~UnicornAArch64()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_isDisposed)
{ {
Interface.Checked(Native.Interface.uc_close(uc)); Interface.Checked(Native.Interface.uc_close(uc));
_isDisposed = true;
}
} }
public void RunForCount(ulong count) public void RunForCount(ulong count)

View File

@@ -80,6 +80,12 @@ namespace Ryujinx.Tests.Cpu
[TearDown] [TearDown]
public void Teardown() public void Teardown()
{ {
if (_unicornAvailable)
{
_unicornEmu.Dispose();
_unicornEmu = null;
}
_memory.DecrementReferenceCount(); _memory.DecrementReferenceCount();
_context.Dispose(); _context.Dispose();
_ram.Dispose(); _ram.Dispose();

View File

@@ -76,6 +76,12 @@ namespace Ryujinx.Tests.Cpu
[TearDown] [TearDown]
public void Teardown() public void Teardown()
{ {
if (_unicornAvailable)
{
_unicornEmu.Dispose();
_unicornEmu = null;
}
_memory.DecrementReferenceCount(); _memory.DecrementReferenceCount();
_context.Dispose(); _context.Dispose();
_ram.Dispose(); _ram.Dispose();

View File

@@ -23,7 +23,7 @@
<PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build10" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" /> <PackageReference Include="Ryujinx.Graphics.Nvdec.Dependencies" Version="5.0.1-build10" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
<PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" /> <PackageReference Include="Ryujinx.Audio.OpenAL.Dependencies" Version="1.21.0.1" Condition="'$(RuntimeIdentifier)' != 'linux-x64' AND '$(RuntimeIdentifier)' != 'osx-x64'" />
<PackageReference Include="OpenTK.Graphics" Version="4.7.2" /> <PackageReference Include="OpenTK.Graphics" Version="4.7.2" />
<PackageReference Include="SPB" Version="0.0.4-build24" /> <PackageReference Include="SPB" Version="0.0.4-build27" />
<PackageReference Include="SharpZipLib" Version="1.3.3" /> <PackageReference Include="SharpZipLib" Version="1.3.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" /> <PackageReference Include="SixLabors.ImageSharp" Version="1.0.4" />
</ItemGroup> </ItemGroup>