diff options
Diffstat (limited to 'Ryujinx.Graphics.Gpu/Image/TextureCache.cs')
-rw-r--r-- | Ryujinx.Graphics.Gpu/Image/TextureCache.cs | 50 |
1 files changed, 35 insertions, 15 deletions
diff --git a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs index 58cd3a2f..37682b65 100644 --- a/Ryujinx.Graphics.Gpu/Image/TextureCache.cs +++ b/Ryujinx.Graphics.Gpu/Image/TextureCache.cs @@ -623,29 +623,49 @@ namespace Ryujinx.Graphics.Gpu.Image hasLayerViews |= overlap.Info.GetSlices() < texture.Info.GetSlices(); hasMipViews |= overlap.Info.Levels < texture.Info.Levels; } - else if (overlapInCache || !setData) + else { - if (info.GobBlocksInZ > 1 && info.GobBlocksInZ == overlap.Info.GobBlocksInZ) + bool removeOverlap; + bool modified = overlap.CheckModified(false); + + if (overlapInCache || !setData) { - // Allow overlapping slices of 3D textures. Could be improved in future by making sure the textures don't overlap. - continue; - } + if (info.GobBlocksInZ > 1 && info.GobBlocksInZ == overlap.Info.GobBlocksInZ) + { + // Allow overlapping slices of 3D textures. Could be improved in future by making sure the textures don't overlap. + continue; + } + + // The overlap texture is going to contain garbage data after we draw, or is generally incompatible. + // If the texture cannot be entirely contained in the new address space, and one of its view children is compatible with us, + // it must be flushed before removal, so that the data is not lost. + + // If the texture was modified since its last use, then that data is probably meant to go into this texture. + // If the data has been modified by the CPU, then it also shouldn't be flushed. - // The overlap texture is going to contain garbage data after we draw, or is generally incompatible. - // If the texture cannot be entirely contained in the new address space, and one of its view children is compatible with us, - // it must be flushed before removal, so that the data is not lost. + bool viewCompatibleChild = overlap.HasViewCompatibleChild(texture); - // If the texture was modified since its last use, then that data is probably meant to go into this texture. - // If the data has been modified by the CPU, then it also shouldn't be flushed. - bool modified = overlap.ConsumeModified(); + bool flush = overlapInCache && !modified && !texture.Range.Contains(overlap.Range) && viewCompatibleChild; - bool flush = overlapInCache && !modified && !texture.Range.Contains(overlap.Range) && overlap.HasViewCompatibleChild(texture); + setData |= modified || flush; - setData |= modified || flush; + if (overlapInCache) + { + _cache.Remove(overlap, flush); + } + + removeOverlap = modified && !viewCompatibleChild; + } + else + { + // If an incompatible overlapping texture has been modified, then it's data is likely destined for this texture, + // and the overlapped texture will contain garbage. In this case, it should be removed to save memory. + removeOverlap = modified; + } - if (overlapInCache) + if (removeOverlap && overlap.Info.Target != Target.TextureBuffer) { - _cache.Remove(overlap, flush); + overlap.RemoveFromPools(false); } } } |