diff options
author | gdkchan <gab.dark.100@gmail.com> | 2023-10-30 19:18:28 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-30 23:18:28 +0100 |
commit | 9ef0be477bd6ea4c2c9aada53d94386824a87f00 (patch) | |
tree | 2954711eb9d4c8b4163a767bb295f12189e23f3c | |
parent | c14ce4d2a5c9b373fb454906a6dc142c028d7be2 (diff) |
Skip some invalid texture flushes (#5755)1.1.1066
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/Texture.cs | 15 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs | 2 | ||||
-rw-r--r-- | src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs | 8 |
3 files changed, 22 insertions, 3 deletions
diff --git a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs index 022a3839..dca6263a 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/Texture.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/Texture.cs @@ -102,6 +102,11 @@ namespace Ryujinx.Graphics.Gpu.Image public bool AlwaysFlushOnOverlap { get; private set; } /// <summary> + /// Indicates that the texture was fully unmapped since the modified flag was set, and flushes should be ignored until it is modified again. + /// </summary> + public bool FlushStale { get; private set; } + + /// <summary> /// Increments when the host texture is swapped, or when the texture is removed from all pools. /// </summary> public int InvalidatedSequence { get; private set; } @@ -149,6 +154,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> public bool HadPoolOwner { get; private set; } + /// <summary> /// Physical memory ranges where the texture data is located. /// </summary> public MultiRange Range { get; private set; } @@ -1411,6 +1417,7 @@ namespace Ryujinx.Graphics.Gpu.Image /// </summary> public void SignalModified() { + FlushStale = false; _scaledSetScore = Math.Max(0, _scaledSetScore - 1); if (_modifiedStale || Group.HasCopyDependencies) @@ -1431,6 +1438,7 @@ namespace Ryujinx.Graphics.Gpu.Image { if (bound) { + FlushStale = false; _scaledSetScore = Math.Max(0, _scaledSetScore - 1); } @@ -1695,12 +1703,17 @@ namespace Ryujinx.Graphics.Gpu.Image /// <param name="unmapRange">The range of memory being unmapped</param> public void Unmapped(MultiRange unmapRange) { + if (unmapRange.Contains(Range)) + { + // If this is a full unmap, prevent flushes until the texture is mapped again. + FlushStale = true; + } + ChangedMapping = true; if (Group.Storage == this) { Group.Unmapped(); - Group.ClearModified(unmapRange); } } diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index 5048ccca..432b1085 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -107,8 +107,6 @@ namespace Ryujinx.Graphics.Gpu.Image // Any texture that has been unmapped at any point or is partially unmapped // should update their pool references after the remap completes. - MultiRange unmapped = ((MemoryManager)sender).GetPhysicalRegions(e.Address, e.Size); - foreach (var texture in _partiallyMappedTextures) { texture.UpdatePoolMappings(); diff --git a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs index 746a95ff..21d7939a 100644 --- a/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs +++ b/src/Ryujinx.Graphics.Gpu/Image/TextureGroup.cs @@ -1659,6 +1659,14 @@ namespace Ryujinx.Graphics.Gpu.Image return; } + // If size is zero, we have nothing to flush. + // If the flush is stale, we should ignore it because the texture was unmapped since the modified + // flag was set, and flushing it is not safe anymore as the GPU might no longer own the memory. + if (size == 0 || Storage.FlushStale) + { + return; + } + // 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. |