Compare commits

..

4 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
10 changed files with 92 additions and 28 deletions

View File

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

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

@@ -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();