Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
d64594ec74 |
@@ -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;
|
||||||
|
@@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -144,9 +144,9 @@ namespace Ryujinx.Memory.Tracking
|
|||||||
{
|
{
|
||||||
lock (_preActionLock)
|
lock (_preActionLock)
|
||||||
{
|
{
|
||||||
_preAction?.Invoke(address, size);
|
RegionSignal action = Interlocked.Exchange(ref _preAction, null);
|
||||||
|
|
||||||
_preAction = null;
|
action?.Invoke(address, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@@ -252,8 +252,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)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user