aboutsummaryrefslogtreecommitdiff
path: root/Ryujinx.Graphics/Texture/BlockLinearSwizzle.cs
blob: 9451291e9a8f0962421e2cf97c937693202fe71e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
using System;

namespace Ryujinx.Graphics.Texture
{
    class BlockLinearSwizzle : ISwizzle
    {
        private int BhShift;
        private int BppShift;
        private int BhMask;

        private int XShift;
        private int GobStride;

        public BlockLinearSwizzle(int Width, int Bpp, int BlockHeight = 16)
        {
            BhMask = (BlockHeight * 8) - 1;

            BhShift  = CountLsbZeros(BlockHeight * 8);
            BppShift = CountLsbZeros(Bpp);

            int WidthInGobs = (int)MathF.Ceiling(Width * Bpp / 64f);

            GobStride = 512 * BlockHeight * WidthInGobs;

            XShift = CountLsbZeros(512 * BlockHeight);
        }

        private int CountLsbZeros(int Value)
        {
            int Count = 0;

            while (((Value >> Count) & 1) == 0)
            {
                Count++;
            }

            return Count;
        }

        public int GetSwizzleOffset(int X, int Y)
        {
            X <<= BppShift;

            int Position = (Y >> BhShift) * GobStride;

            Position += (X >> 6) << XShift;

            Position += ((Y & BhMask) >> 3) << 9;

            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;
        }
    }
}