Compare commits

..

9 Commits

Author SHA1 Message Date
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
16 changed files with 156 additions and 72 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,21 @@ 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
- 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 +73,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

@@ -535,10 +535,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

@@ -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
{ {
@@ -107,7 +108,22 @@ namespace Ryujinx.Tests.Unicorn
~UnicornAArch32() ~UnicornAArch32()
{ {
Interface.Checked(Native.Interface.uc_close(uc)); 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));
_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
{ {
@@ -96,7 +97,22 @@ namespace Ryujinx.Tests.Unicorn
~UnicornAArch64() ~UnicornAArch64()
{ {
Interface.Checked(Native.Interface.uc_close(uc)); 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));
_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>