Merge branch 'Ryujinx:master' into master

This commit is contained in:
Logan Stromberg 2022-05-02 09:45:57 -07:00 committed by GitHub
commit e609901693
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 36 additions and 14 deletions

View file

@ -928,7 +928,7 @@ namespace Ryujinx.Graphics.Gpu.Engine.Threed
size = endAddress.Pack() - address + 1; size = endAddress.Pack() - address + 1;
if (stride > 0 && indexTypeSmall) if (stride > 0 && indexTypeSmall && _drawState.DrawIndexed && !instanced)
{ {
// If the index type is a small integer type, then we might be still able // If the index type is a small integer type, then we might be still able
// to reduce the vertex buffer size based on the maximum possible index value. // to reduce the vertex buffer size based on the maximum possible index value.

View file

@ -1393,6 +1393,12 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="size">The size of the flushing memory access</param> /// <param name="size">The size of the flushing memory access</param>
public void FlushAction(TextureGroupHandle handle, ulong address, ulong size) public void FlushAction(TextureGroupHandle handle, ulong address, ulong size)
{ {
// There is a small gap here where the action is removed but _actionRegistered is still 1.
// In this case it will skip registering the action, but here we are already handling it,
// so there shouldn't be any issue as it's the same handler for all actions.
handle.ClearActionRegistered();
if (!handle.Modified) if (!handle.Modified)
{ {
return; return;

View file

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading;
namespace Ryujinx.Graphics.Gpu.Image namespace Ryujinx.Graphics.Gpu.Image
{ {
@ -32,9 +33,9 @@ namespace Ryujinx.Graphics.Gpu.Image
private ulong _modifiedSync; private ulong _modifiedSync;
/// <summary> /// <summary>
/// Whether a tracking action is currently registered or not. /// Whether a tracking action is currently registered or not. (0/1)
/// </summary> /// </summary>
private bool _actionRegistered; private int _actionRegistered;
/// <summary> /// <summary>
/// Whether a sync action is currently registered or not. /// Whether a sync action is currently registered or not.
@ -171,11 +172,9 @@ namespace Ryujinx.Graphics.Gpu.Image
_syncActionRegistered = true; _syncActionRegistered = true;
} }
if (!_actionRegistered) if (Interlocked.Exchange(ref _actionRegistered, 1) == 0)
{ {
_group.RegisterAction(this); _group.RegisterAction(this);
_actionRegistered = true;
} }
} }
@ -233,8 +232,6 @@ namespace Ryujinx.Graphics.Gpu.Image
/// <param name="context">The GPU context used to wait for sync</param> /// <param name="context">The GPU context used to wait for sync</param>
public void Sync(GpuContext context) public void Sync(GpuContext context)
{ {
_actionRegistered = false;
bool needsSync = !context.IsGpuThread(); bool needsSync = !context.IsGpuThread();
if (needsSync) if (needsSync)
@ -263,21 +260,39 @@ namespace Ryujinx.Graphics.Gpu.Image
} }
} }
/// <summary>
/// Clears the action registered variable, indicating that the tracking action should be
/// re-registered on the next modification.
/// </summary>
public void ClearActionRegistered()
{
Interlocked.Exchange(ref _actionRegistered, 0);
}
/// <summary> /// <summary>
/// Action to perform when a sync number is registered after modification. /// Action to perform when a sync number is registered after modification.
/// This action will register a read tracking action on the memory tracking handle so that a flush from CPU can happen. /// This action will register a read tracking action on the memory tracking handle so that a flush from CPU can happen.
/// </summary> /// </summary>
private void SyncAction() private void SyncAction()
{ {
// The storage will need to signal modified again to update the sync number in future.
_group.Storage.SignalModifiedDirty();
lock (Overlaps)
{
foreach (Texture texture in Overlaps)
{
texture.SignalModifiedDirty();
}
}
// Register region tracking for CPU? (again) // Register region tracking for CPU? (again)
_registeredSync = _modifiedSync; _registeredSync = _modifiedSync;
_syncActionRegistered = false; _syncActionRegistered = false;
if (!_actionRegistered) if (Interlocked.Exchange(ref _actionRegistered, 1) == 0)
{ {
_group.RegisterAction(this); _group.RegisterAction(this);
_actionRegistered = true;
} }
} }

View file

@ -146,7 +146,9 @@ namespace Ryujinx.Memory.Tracking
{ {
_preAction?.Invoke(address, size); _preAction?.Invoke(address, size);
_preAction = null; // The action is removed after it returns, to ensure that the null check above succeeds when
// it's still in progress rather than continuing and possibly missing a required data flush.
Interlocked.Exchange(ref _preAction, null);
} }
} }
finally finally
@ -252,8 +254,7 @@ namespace Ryujinx.Memory.Tracking
lock (_preActionLock) lock (_preActionLock)
{ {
RegionSignal lastAction = _preAction; RegionSignal lastAction = Interlocked.Exchange(ref _preAction, action);
_preAction = action;
if (lastAction == null && action != lastAction) if (lastAction == null && action != lastAction)
{ {