Fix missing texture flush for draw then DMA copy sequence without render target change (#5933)

* Unbind render targets before DMA copy

* Move DirtyAction to TextureGroupHandle

* Fix lost copy dependency bug

* XML doc
This commit is contained in:
gdkchan
2023-11-15 21:36:25 -03:00
committed by GitHub
parent cdc8fed64f
commit dcf10561b9
5 changed files with 102 additions and 61 deletions

View File

@ -709,8 +709,7 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
/// <param name="texture">The texture that has been modified</param>
/// <param name="bound">True if this texture is being bound, false if unbound</param>
/// <param name="setModified">Indicates if the modified flag should be set</param>
public void SignalModifying(Texture texture, bool bound, bool setModified)
public void SignalModifying(Texture texture, bool bound)
{
ModifiedSequence = _context.GetModifiedSequence();
@ -722,7 +721,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
TextureGroupHandle group = _handles[baseHandle + i];
group.SignalModifying(bound, _context, setModified);
group.SignalModifying(bound, _context);
}
});
}
@ -993,26 +992,6 @@ namespace Ryujinx.Graphics.Gpu.Image
}
}
/// <summary>
/// The action to perform when a memory tracking handle is flipped to dirty.
/// This notifies overlapping textures that the memory needs to be synchronized.
/// </summary>
/// <param name="groupHandle">The handle that a dirty flag was set on</param>
private void DirtyAction(TextureGroupHandle groupHandle)
{
// Notify all textures that belong to this handle.
Storage.SignalGroupDirty();
lock (groupHandle.Overlaps)
{
foreach (Texture overlap in groupHandle.Overlaps)
{
overlap.SignalGroupDirty();
}
}
}
/// <summary>
/// Generate a CpuRegionHandle for a given address and size range in CPU VA.
/// </summary>
@ -1084,11 +1063,6 @@ namespace Ryujinx.Graphics.Gpu.Image
views,
result.ToArray());
foreach (RegionHandle handle in result)
{
handle.RegisterDirtyEvent(() => DirtyAction(groupHandle));
}
return groupHandle;
}
@ -1360,11 +1334,6 @@ namespace Ryujinx.Graphics.Gpu.Image
var groupHandle = new TextureGroupHandle(this, 0, Storage.Size, _views, 0, 0, 0, _allOffsets.Length, cpuRegionHandles);
foreach (RegionHandle handle in cpuRegionHandles)
{
handle.RegisterDirtyEvent(() => DirtyAction(groupHandle));
}
handles = new TextureGroupHandle[] { groupHandle };
}
else
@ -1620,6 +1589,7 @@ namespace Ryujinx.Graphics.Gpu.Image
if ((ignore == null || !handle.HasDependencyTo(ignore)) && handle.Modified)
{
handle.Modified = false;
handle.DeferredCopy = null;
Storage.SignalModifiedDirty();
lock (handle.Overlaps)
@ -1666,8 +1636,6 @@ namespace Ryujinx.Graphics.Gpu.Image
return;
}
Storage.ModifiedSinceLastFlush = false;
// 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.