Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
f4b74e9ce1 | ||
|
4e19b36ad7 | ||
|
b16923a902 |
18
.github/dependabot.yml
vendored
18
.github/dependabot.yml
vendored
@@ -13,7 +13,7 @@ updates:
|
||||
|
||||
- package-ecosystem: nuget
|
||||
directory: /
|
||||
open-pull-requests-limit: 5
|
||||
open-pull-requests-limit: 10
|
||||
schedule:
|
||||
interval: daily
|
||||
labels:
|
||||
@@ -22,3 +22,19 @@ updates:
|
||||
- marysaka
|
||||
commit-message:
|
||||
prefix: nuget
|
||||
groups:
|
||||
Avalonia:
|
||||
patterns:
|
||||
- "*Avalonia*"
|
||||
Silk.NET:
|
||||
patterns:
|
||||
- "Silk.NET*"
|
||||
OpenTK:
|
||||
patterns:
|
||||
- "OpenTK*"
|
||||
SixLabors:
|
||||
patterns:
|
||||
- "SixLabors*"
|
||||
NUnit:
|
||||
patterns:
|
||||
- "NUnit*"
|
||||
|
@@ -1,62 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.Intrinsics;
|
||||
|
||||
namespace Ryujinx.Cpu.AppleHv
|
||||
{
|
||||
static class HvCodePatcher
|
||||
{
|
||||
private const uint XMask = 0x3f808000u;
|
||||
private const uint XValue = 0x8000000u;
|
||||
|
||||
private const uint ZrIndex = 31u;
|
||||
|
||||
public static void RewriteUnorderedExclusiveInstructions(Span<byte> code)
|
||||
{
|
||||
Span<uint> codeUint = MemoryMarshal.Cast<byte, uint>(code);
|
||||
Span<Vector128<uint>> codeVector = MemoryMarshal.Cast<byte, Vector128<uint>>(code);
|
||||
|
||||
Vector128<uint> mask = Vector128.Create(XMask);
|
||||
Vector128<uint> value = Vector128.Create(XValue);
|
||||
|
||||
for (int index = 0; index < codeVector.Length; index++)
|
||||
{
|
||||
Vector128<uint> v = codeVector[index];
|
||||
|
||||
if (Vector128.EqualsAny(Vector128.BitwiseAnd(v, mask), value))
|
||||
{
|
||||
int baseIndex = index * 4;
|
||||
|
||||
for (int instIndex = baseIndex; instIndex < baseIndex + 4; instIndex++)
|
||||
{
|
||||
ref uint inst = ref codeUint[instIndex];
|
||||
|
||||
if ((inst & XMask) != XValue)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isPair = (inst & (1u << 21)) != 0;
|
||||
bool isLoad = (inst & (1u << 22)) != 0;
|
||||
|
||||
uint rt2 = (inst >> 10) & 0x1fu;
|
||||
uint rs = (inst >> 16) & 0x1fu;
|
||||
|
||||
if (isLoad && rs != ZrIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!isPair && rt2 != ZrIndex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Set the ordered flag.
|
||||
inst |= 1u << 15;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -724,18 +724,6 @@ namespace Ryujinx.Cpu.AppleHv
|
||||
/// <inheritdoc/>
|
||||
public void Reprotect(ulong va, ulong size, MemoryPermission protection)
|
||||
{
|
||||
if (protection.HasFlag(MemoryPermission.Execute))
|
||||
{
|
||||
// Some applications use unordered exclusive memory access instructions
|
||||
// where it is not valid to do so, leading to memory re-ordering that
|
||||
// makes the code behave incorrectly on some CPUs.
|
||||
// To work around this, we force all such accesses to be ordered.
|
||||
|
||||
using WritableRegion writableRegion = GetWritableRegion(va, (int)size);
|
||||
|
||||
HvCodePatcher.RewriteUnorderedExclusiveInstructions(writableRegion.Memory.Span);
|
||||
}
|
||||
|
||||
// TODO
|
||||
}
|
||||
|
||||
|
@@ -103,6 +103,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// <param name="argument">Method call argument</param>
|
||||
public void DrawEnd(ThreedClass engine, int argument)
|
||||
{
|
||||
_drawState.DrawUsesEngineState = true;
|
||||
|
||||
DrawEnd(
|
||||
engine,
|
||||
_state.State.IndexBufferState.First,
|
||||
@@ -205,10 +207,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
}
|
||||
else
|
||||
{
|
||||
#pragma warning disable IDE0059 // Remove unnecessary value assignment
|
||||
var drawState = _state.State.VertexBufferDrawState;
|
||||
#pragma warning restore IDE0059
|
||||
|
||||
DrawImpl(engine, drawVertexCount, 1, 0, drawFirstVertex, firstInstance, indexed: false);
|
||||
}
|
||||
|
||||
@@ -379,6 +377,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
bool oldDrawIndexed = _drawState.DrawIndexed;
|
||||
|
||||
_drawState.DrawIndexed = true;
|
||||
_drawState.DrawUsesEngineState = false;
|
||||
engine.ForceStateDirty(IndexBufferCountMethodOffset * 4);
|
||||
|
||||
DrawEnd(engine, firstIndex, indexCount, 0, 0);
|
||||
@@ -424,6 +423,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
bool oldDrawIndexed = _drawState.DrawIndexed;
|
||||
|
||||
_drawState.DrawIndexed = false;
|
||||
_drawState.DrawUsesEngineState = false;
|
||||
engine.ForceStateDirty(VertexBufferFirstMethodOffset * 4);
|
||||
|
||||
DrawEnd(engine, 0, 0, firstVertex, vertexCount);
|
||||
@@ -544,6 +544,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
_state.State.FirstInstance = (uint)firstInstance;
|
||||
|
||||
_drawState.DrawIndexed = indexed;
|
||||
_drawState.DrawUsesEngineState = true;
|
||||
_currentSpecState.SetHasConstantBufferDrawParameters(true);
|
||||
|
||||
engine.UpdateState();
|
||||
@@ -676,6 +677,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
|
||||
_drawState.DrawIndexed = indexed;
|
||||
_drawState.DrawIndirect = true;
|
||||
_drawState.DrawUsesEngineState = true;
|
||||
_currentSpecState.SetHasConstantBufferDrawParameters(true);
|
||||
|
||||
engine.UpdateState();
|
||||
|
@@ -38,6 +38,11 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
public bool DrawIndirect;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the draw is using the draw parameters on the 3D engine state, rather than inline parameters submitted with the draw command.
|
||||
/// </summary>
|
||||
public bool DrawUsesEngineState;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates if any of the currently used vertex shaders reads the instance ID.
|
||||
/// </summary>
|
||||
@@ -48,11 +53,6 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
/// </summary>
|
||||
public bool IsAnyVbInstanced;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the draw is writing the base vertex, base instance and draw index to Constant Buffer 0.
|
||||
/// </summary>
|
||||
public bool HasConstantBufferDrawParameters;
|
||||
|
||||
/// <summary>
|
||||
/// Primitive topology for the next draw.
|
||||
/// </summary>
|
||||
|
@@ -47,7 +47,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
private uint _vbEnableMask;
|
||||
|
||||
private bool _prevDrawIndexed;
|
||||
private readonly bool _prevDrawIndirect;
|
||||
private bool _prevDrawIndirect;
|
||||
private bool _prevDrawUsesEngineState;
|
||||
private IndexType _prevIndexType;
|
||||
private uint _prevFirstVertex;
|
||||
private bool _prevTfEnable;
|
||||
@@ -236,7 +237,9 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
// method when doing indexed draws, so we need to make sure
|
||||
// to update the vertex buffers if we are doing a regular
|
||||
// draw after a indexed one and vice-versa.
|
||||
if (_drawState.DrawIndexed != _prevDrawIndexed)
|
||||
// Some draws also do not update the engine state, so it is possible for it
|
||||
// to not be dirty even if the vertex counts or other state changed. We need to force it to be dirty in this case.
|
||||
if (_drawState.DrawIndexed != _prevDrawIndexed || _drawState.DrawUsesEngineState != _prevDrawUsesEngineState)
|
||||
{
|
||||
_updateTracker.ForceDirty(VertexBufferStateIndex);
|
||||
|
||||
@@ -251,6 +254,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
}
|
||||
|
||||
_prevDrawIndexed = _drawState.DrawIndexed;
|
||||
_prevDrawUsesEngineState = _drawState.DrawUsesEngineState;
|
||||
}
|
||||
|
||||
// Some draw parameters are used to restrict the vertex buffer size,
|
||||
@@ -260,6 +264,8 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
|
||||
if (_drawState.DrawIndirect != _prevDrawIndirect)
|
||||
{
|
||||
_updateTracker.ForceDirty(VertexBufferStateIndex);
|
||||
|
||||
_prevDrawIndirect = _drawState.DrawIndirect;
|
||||
}
|
||||
|
||||
// In some cases, the index type is also used to guess the
|
||||
|
Reference in New Issue
Block a user