Texture Cache: "Texture Groups" and "Texture Dependencies" (#2001)

* Initial implementation (3d tex mips broken)

This works rather well for most games, just need to fix 3d texture mips.

* Cleanup

* Address feedback

* Copy Dependencies and various other fixes

* Fix layer/level offset for copy from view<->view.

* Remove dirty flag from dependency

The dirty flag behaviour is not needed - DeferredCopy is all we need.

* Fix tracking mip slices.

* Propagate granularity (fix astral chain)

* Address Feedback pt 1

* Save slice sizes as part of SizeInfo

* Fix nits

* Fix disposing multiple dependencies causing a crash

This list is obviously modified when removing dependencies, so create a copy of it.
This commit is contained in:
riperiperi 2021-03-02 22:30:54 +00:00 committed by GitHub
parent 7a90abc035
commit b530f0e110
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 1915 additions and 220 deletions

View file

@ -5,34 +5,46 @@ namespace Ryujinx.Graphics.Texture
public struct SizeInfo
{
private readonly int[] _mipOffsets;
private readonly int[] _allOffsets;
private readonly int _levels;
private readonly int _depth;
private readonly bool _is3D;
public readonly int[] AllOffsets;
public readonly int[] SliceSizes;
public int LayerSize { get; }
public int TotalSize { get; }
public SizeInfo(int size)
{
_mipOffsets = new int[] { 0 };
_allOffsets = new int[] { 0 };
AllOffsets = new int[] { 0 };
SliceSizes = new int[] { size };
_depth = 1;
_levels = 1;
LayerSize = size;
TotalSize = size;
_is3D = false;
}
internal SizeInfo(
int[] mipOffsets,
int[] allOffsets,
int[] sliceSizes,
int depth,
int levels,
int layerSize,
int totalSize)
int totalSize,
bool is3D)
{
_mipOffsets = mipOffsets;
_allOffsets = allOffsets;
AllOffsets = allOffsets;
SliceSizes = sliceSizes;
_depth = depth;
_levels = levels;
LayerSize = layerSize;
TotalSize = totalSize;
_is3D = is3D;
}
public int GetMipOffset(int level)
@ -47,7 +59,7 @@ namespace Ryujinx.Graphics.Texture
public bool FindView(int offset, out int firstLayer, out int firstLevel)
{
int index = Array.BinarySearch(_allOffsets, offset);
int index = Array.BinarySearch(AllOffsets, offset);
if (index < 0)
{
@ -57,8 +69,25 @@ namespace Ryujinx.Graphics.Texture
return false;
}
firstLayer = index / _levels;
firstLevel = index - (firstLayer * _levels);
if (_is3D)
{
firstLayer = index;
firstLevel = 0;
int levelDepth = _depth;
while (firstLayer >= levelDepth)
{
firstLayer -= levelDepth;
firstLevel++;
levelDepth = Math.Max(levelDepth >> 1, 1);
}
}
else
{
firstLayer = index / _levels;
firstLevel = index - (firstLayer * _levels);
}
return true;
}