diff --git a/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs b/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs index 726b97ea..8bc6d544 100644 --- a/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs +++ b/Ryujinx.Graphics.Gpu/Image/AutoDeleteCache.cs @@ -41,14 +41,14 @@ namespace Ryujinx.Graphics.Gpu.Image { Texture oldestTexture = _textures.First.Value; - oldestTexture.SynchronizeMemory(); - - if (oldestTexture.IsModified && !oldestTexture.CheckModified(true)) + if (oldestTexture.IsModified && !oldestTexture.CheckModified(false)) { // The texture must be flushed if it falls out of the auto delete cache. // Flushes out of the auto delete cache do not trigger write tracking, // as it is expected that other overlapping textures exist that have more up-to-date contents. - oldestTexture.Flush(false); + + oldestTexture.Group.SynchronizeDependents(oldestTexture); + oldestTexture.Flush(false); } _textures.RemoveFirst(); diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index 1fe0bbf7..2bd97432 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -234,6 +234,23 @@ namespace Ryujinx.Graphics.Gpu.Image } } + /// + /// Synchronize dependent textures, if any of them have deferred a copy from the given texture. + /// + /// The texture to synchronize dependents of + public void SynchronizeDependents(Texture texture) + { + EvaluateRelevantHandles(texture, (baseHandle, regionCount, split) => + { + for (int i = 0; i < regionCount; i++) + { + TextureGroupHandle group = _handles[baseHandle + i]; + + group.SynchronizeDependents(); + } + }); + } + /// /// Signal that a texture in the group has been modified by the GPU. /// diff --git a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs index 27ee1e49..0b69b6c7 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureGroupHandle.cs @@ -140,6 +140,22 @@ namespace Ryujinx.Graphics.Gpu.Image _bindCount = Math.Max(0, _bindCount + (bound ? 1 : -1)); } + /// + /// Synchronize dependent textures, if any of them have deferred a copy from this texture. + /// + public void SynchronizeDependents() + { + foreach (TextureDependency dependency in Dependencies) + { + TextureGroupHandle otherHandle = dependency.Other.Handle; + + if (otherHandle.DeferredCopy == this) + { + otherHandle._group.Storage.SynchronizeMemory(); + } + } + } + /// /// Signal that a copy dependent texture has been modified, and must have its data copied to this one. ///