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
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 102 additions and 61 deletions

View file

@ -152,6 +152,32 @@ namespace Ryujinx.Graphics.Gpu.Image
// Linear textures are presumed to be used for readback initially.
_flushBalance = FlushBalanceThreshold + FlushBalanceIncrement;
}
foreach (RegionHandle handle in handles)
{
handle.RegisterDirtyEvent(DirtyAction);
}
}
/// <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>
private void DirtyAction()
{
// Notify all textures that belong to this handle.
_group.Storage.SignalGroupDirty();
lock (Overlaps)
{
foreach (Texture overlap in Overlaps)
{
overlap.SignalGroupDirty();
}
}
DeferredCopy = null;
}
/// <summary>
@ -304,17 +330,9 @@ namespace Ryujinx.Graphics.Gpu.Image
/// </summary>
/// <param name="bound">True if this handle is being bound, false if unbound</param>
/// <param name="context">The GPU context to register a sync action on</param>
/// <param name="setModified">Indicates if the modified flag should be set</param>
public void SignalModifying(bool bound, GpuContext context, bool setModified)
public void SignalModifying(bool bound, GpuContext context)
{
if (setModified)
{
SignalModified(context);
}
else
{
RegisterSync(context);
}
SignalModified(context);
if (!bound && _syncActionRegistered && NextSyncCopies())
{
@ -457,7 +475,6 @@ namespace Ryujinx.Graphics.Gpu.Image
public void DeferCopy(TextureGroupHandle copyFrom)
{
Modified = false;
DeferredCopy = copyFrom;
_group.Storage.SignalGroupDirty();
@ -514,7 +531,7 @@ namespace Ryujinx.Graphics.Gpu.Image
{
existing.Other.Handle.CreateCopyDependency(this);
if (copyToOther)
if (copyToOther && Modified)
{
existing.Other.Handle.DeferCopy(this);
}
@ -558,10 +575,10 @@ namespace Ryujinx.Graphics.Gpu.Image
if (fromHandle != null)
{
// Only copy if the copy texture is still modified.
// It will be set as unmodified if new data is written from CPU, as the data previously in the texture will flush.
// DeferredCopy will be set to null if new data is written from CPU (see the DirtyAction method).
// It will also set as unmodified if a copy is deferred to it.
shouldCopy = fromHandle.Modified;
shouldCopy = true;
if (fromHandle._bindCount == 0)
{