aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics.Texture/BlockLinearLayout.cs
diff options
context:
space:
mode:
authorgdk <gab.dark.100@gmail.com>2019-10-13 03:02:07 -0300
committerThog <thog@protonmail.com>2020-01-09 02:13:00 +0100
commit1876b346fea647e8284a66bb6d62c38801035cff (patch)
tree6eeff094298cda84d1613dc5ec0691e51d7b35f1 /Ryujinx.Graphics.Texture/BlockLinearLayout.cs
parentf617fb542a0e3d36012d77a4b5acbde7b08902f2 (diff)
Initial work
Diffstat (limited to 'Ryujinx.Graphics.Texture/BlockLinearLayout.cs')
-rw-r--r--Ryujinx.Graphics.Texture/BlockLinearLayout.cs106
1 files changed, 106 insertions, 0 deletions
diff --git a/Ryujinx.Graphics.Texture/BlockLinearLayout.cs b/Ryujinx.Graphics.Texture/BlockLinearLayout.cs
new file mode 100644
index 00000000..3d3f13ba
--- /dev/null
+++ b/Ryujinx.Graphics.Texture/BlockLinearLayout.cs
@@ -0,0 +1,106 @@
+using Ryujinx.Common;
+using System;
+
+using static Ryujinx.Graphics.Texture.BlockLinearConstants;
+
+namespace Ryujinx.Graphics.Texture
+{
+ class BlockLinearLayout
+ {
+ private struct RobAndSliceSizes
+ {
+ public int RobSize;
+ public int SliceSize;
+
+ public RobAndSliceSizes(int robSize, int sliceSize)
+ {
+ RobSize = robSize;
+ SliceSize = sliceSize;
+ }
+ }
+
+ private int _texWidth;
+ private int _texHeight;
+ private int _texDepth;
+ private int _texGobBlocksInY;
+ private int _texGobBlocksInZ;
+ private int _texBpp;
+
+ private int _bhMask;
+ private int _bdMask;
+
+ private int _bhShift;
+ private int _bdShift;
+ private int _bppShift;
+
+ private int _xShift;
+
+ private int _robSize;
+ private int _sliceSize;
+
+ public BlockLinearLayout(
+ int width,
+ int height,
+ int depth,
+ int gobBlocksInY,
+ int gobBlocksInZ,
+ int bpp)
+ {
+ _texWidth = width;
+ _texHeight = height;
+ _texDepth = depth;
+ _texGobBlocksInY = gobBlocksInY;
+ _texGobBlocksInZ = gobBlocksInZ;
+ _texBpp = bpp;
+
+ _bppShift = BitUtils.CountTrailingZeros32(bpp);
+
+ _bhMask = gobBlocksInY - 1;
+ _bdMask = gobBlocksInZ - 1;
+
+ _bhShift = BitUtils.CountTrailingZeros32(gobBlocksInY);
+ _bdShift = BitUtils.CountTrailingZeros32(gobBlocksInZ);
+
+ _xShift = BitUtils.CountTrailingZeros32(GobSize * gobBlocksInY * gobBlocksInZ);
+
+ RobAndSliceSizes rsSizes = GetRobAndSliceSizes(width, height, gobBlocksInY, gobBlocksInZ);
+
+ _robSize = rsSizes.RobSize;
+ _sliceSize = rsSizes.SliceSize;
+ }
+
+ private RobAndSliceSizes GetRobAndSliceSizes(int width, int height, int gobBlocksInY, int gobBlocksInZ)
+ {
+ int widthInGobs = BitUtils.DivRoundUp(width * _texBpp, GobStride);
+
+ int robSize = GobSize * gobBlocksInY * gobBlocksInZ * widthInGobs;
+
+ int sliceSize = BitUtils.DivRoundUp(height, gobBlocksInY * GobHeight) * robSize;
+
+ return new RobAndSliceSizes(robSize, sliceSize);
+ }
+
+ public int GetOffset(int x, int y, int z)
+ {
+ x <<= _bppShift;
+
+ int yh = y / GobHeight;
+
+ int position = (z >> _bdShift) * _sliceSize + (yh >> _bhShift) * _robSize;
+
+ position += (x / GobStride) << _xShift;
+
+ position += (yh & _bhMask) * GobSize;
+
+ position += ((z & _bdMask) * GobSize) << _bhShift;
+
+ position += ((x & 0x3f) >> 5) << 8;
+ position += ((y & 0x07) >> 1) << 6;
+ position += ((x & 0x1f) >> 4) << 5;
+ position += ((y & 0x01) >> 0) << 4;
+ position += ((x & 0x0f) >> 0) << 0;
+
+ return position;
+ }
+ }
+} \ No newline at end of file