GPU: Don't create tracking handles for buffer textures (#5727)

* GPU: Don't create tracking handles for buffer textures

Buffer texture memory is handled by the buffer cache - the texture shouldn't create any tracking handles as they aren't used. This change simply makes them create and iterate 0 tracking handles, while keeping the rest of the texture group around.

This prevents a possible issue where many buffer textures are created as views of overlapping buffer ranges, and virtual regions have many dependant textures that don't actually contribute anything to handle state.

Should improve performance in Mortal Kombat 1, possibly certain UE4 games when FIFO raises to 100%.

* Fix interval tree bug

* Don't check view compatibility for buffer textures
This commit is contained in:
riperiperi 2023-09-26 16:37:10 +01:00 committed by GitHub
parent 7f2fb049f5
commit e63157cc33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 7 deletions

View file

@ -189,7 +189,7 @@ namespace ARMeilleure.Translation
{
if (start.CompareTo(node.End) < 0)
{
if (overlaps.Length >= overlapCount)
if (overlaps.Length <= overlapCount)
{
Array.Resize(ref overlaps, overlapCount + ArrayGrowthSize);
}

View file

@ -192,7 +192,7 @@ namespace Ryujinx.Common.Collections
{
if (start.CompareTo(overlap.End) < 0)
{
if (overlaps.Length >= overlapCount)
if (overlaps.Length <= overlapCount)
{
Array.Resize(ref overlaps, overlapCount + ArrayGrowthSize);
}

View file

@ -696,11 +696,14 @@ namespace Ryujinx.Graphics.Gpu.Image
}
// Find view compatible matches.
int overlapsCount;
int overlapsCount = 0;
lock (_textures)
if (info.Target != Target.TextureBuffer)
{
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
lock (_textures)
{
overlapsCount = _textures.FindOverlaps(range.Value, ref _textureOverlaps);
}
}
if (_overlapInfo.Length != _textureOverlaps.Length)

View file

@ -79,6 +79,7 @@ namespace Ryujinx.Graphics.Gpu.Image
private int[] _allOffsets;
private int[] _sliceSizes;
private readonly bool _is3D;
private readonly bool _isBuffer;
private bool _hasMipViews;
private bool _hasLayerViews;
private readonly int _layers;
@ -118,6 +119,7 @@ namespace Ryujinx.Graphics.Gpu.Image
_physicalMemory = physicalMemory;
_is3D = storage.Info.Target == Target.Texture3D;
_isBuffer = storage.Info.Target == Target.TextureBuffer;
_layers = storage.Info.GetSlices();
_levels = storage.Info.Levels;
@ -794,7 +796,11 @@ namespace Ryujinx.Graphics.Gpu.Image
int targetLayerHandles = _hasLayerViews ? slices : 1;
int targetLevelHandles = _hasMipViews ? levels : 1;
if (_is3D)
if (_isBuffer)
{
return;
}
else if (_is3D)
{
// Future mip levels come after all layers of the last mip level. Each mipmap has less layers (depth) than the last.
@ -1327,7 +1333,11 @@ namespace Ryujinx.Graphics.Gpu.Image
{
TextureGroupHandle[] handles;
if (!(_hasMipViews || _hasLayerViews))
if (_isBuffer)
{
handles = Array.Empty<TextureGroupHandle>();
}
else if (!(_hasMipViews || _hasLayerViews))
{
// Single dirty region.
var cpuRegionHandles = new RegionHandle[TextureRange.Count];