aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Texture/SizeCalculator.cs
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2021-03-02 22:30:54 +0000
committerGitHub <noreply@github.com>2021-03-02 19:30:54 -0300
commitb530f0e1104723b894695b2860cf0f568f24cc9a (patch)
tree04f6b7d76d334ddc5c0378f6aa00b98739bc793e /Ryujinx.Graphics.Texture/SizeCalculator.cs
parent7a90abc03555f41ba7589bc8e1f714839f9e2fed (diff)
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.
Diffstat (limited to 'Ryujinx.Graphics.Texture/SizeCalculator.cs')
-rw-r--r--Ryujinx.Graphics.Texture/SizeCalculator.cs29
1 files changed, 24 insertions, 5 deletions
diff --git a/Ryujinx.Graphics.Texture/SizeCalculator.cs b/Ryujinx.Graphics.Texture/SizeCalculator.cs
index 2dc60869..7eee13c0 100644
--- a/Ryujinx.Graphics.Texture/SizeCalculator.cs
+++ b/Ryujinx.Graphics.Texture/SizeCalculator.cs
@@ -9,6 +9,19 @@ namespace Ryujinx.Graphics.Texture
{
private const int StrideAlignment = 32;
+ private static int Calculate3DOffsetCount(int levels, int depth)
+ {
+ int offsetCount = depth;
+
+ while (--levels > 0)
+ {
+ depth = Math.Max(1, depth >> 1);
+ offsetCount += depth;
+ }
+
+ return offsetCount;
+ }
+
public static SizeInfo GetBlockLinearTextureSize(
int width,
int height,
@@ -27,8 +40,9 @@ namespace Ryujinx.Graphics.Texture
int layerSize = 0;
- int[] allOffsets = new int[levels * layers * depth];
+ int[] allOffsets = new int[is3D ? Calculate3DOffsetCount(levels, depth) : levels * layers * depth];
int[] mipOffsets = new int[levels];
+ int[] sliceSizes = new int[levels];
int mipGobBlocksInY = gobBlocksInY;
int mipGobBlocksInZ = gobBlocksInZ;
@@ -36,6 +50,8 @@ namespace Ryujinx.Graphics.Texture
int gobWidth = (GobStride / bytesPerPixel) * gobBlocksInTileX;
int gobHeight = gobBlocksInY * GobHeight;
+ int depthLevelOffset = 0;
+
for (int level = 0; level < levels; level++)
{
int w = Math.Max(1, width >> level);
@@ -86,13 +102,16 @@ namespace Ryujinx.Graphics.Texture
int zLow = z & mask;
int zHigh = z & ~mask;
- allOffsets[z * levels + level] = baseOffset + zLow * gobSize + zHigh * sliceSize;
+ allOffsets[z + depthLevelOffset] = baseOffset + zLow * gobSize + zHigh * sliceSize;
}
}
mipOffsets[level] = layerSize;
+ sliceSizes[level] = totalBlocksOfGobsInY * robSize;
+
+ layerSize += totalBlocksOfGobsInZ * sliceSizes[level];
- layerSize += totalBlocksOfGobsInZ * totalBlocksOfGobsInY * robSize;
+ depthLevelOffset += d;
}
if (layers > 1)
@@ -133,7 +152,7 @@ namespace Ryujinx.Graphics.Texture
}
}
- return new SizeInfo(mipOffsets, allOffsets, levels, layerSize, totalSize);
+ return new SizeInfo(mipOffsets, allOffsets, sliceSizes, depth, levels, layerSize, totalSize, is3D);
}
public static SizeInfo GetLinearTextureSize(int stride, int height, int blockHeight)
@@ -142,7 +161,7 @@ namespace Ryujinx.Graphics.Texture
// so we only need to handle a single case (2D textures without mipmaps).
int totalSize = stride * BitUtils.DivRoundUp(height, blockHeight);
- return new SizeInfo(new int[] { 0 }, new int[] { 0 }, 1, totalSize, totalSize);
+ return new SizeInfo(totalSize);
}
private static int AlignLayerSize(