aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Gpu/Engine/Compute/ComputeQmd.cs
blob: 1b20e41c297d7ef8ce32c552a0e4ff918c60791a (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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
using Ryujinx.Graphics.Gpu.Engine.Types;
using System;
using System.Runtime.CompilerServices;

namespace Ryujinx.Graphics.Gpu.Engine.Compute
{
    /// <summary>
    /// Type of the dependent Queue Meta Data.
    /// </summary>
    enum DependentQmdType
    {
        Queue,
        Grid
    }

    /// <summary>
    /// Type of the release memory barrier.
    /// </summary>
    enum ReleaseMembarType
    {
        FeNone,
        FeSysmembar
    }

    /// <summary>
    /// Type of the CWD memory barrier.
    /// </summary>
    enum CwdMembarType
    {
        L1None,
        L1Sysmembar,
        L1Membar
    }

    /// <summary>
    /// NaN behavior of 32-bits float operations on the shader.
    /// </summary>
    enum Fp32NanBehavior
    {
        Legacy,
        Fp64Compatible
    }

    /// <summary>
    /// NaN behavior of 32-bits float to integer conversion on the shader.
    /// </summary>
    enum Fp32F2iNanBehavior
    {
        PassZero,
        PassIndefinite
    }

    /// <summary>
    /// Limit of calls.
    /// </summary>
    enum ApiVisibleCallLimit
    {
        _32,
        NoCheck
    }

    /// <summary>
    /// Shared memory bank mapping mode.
    /// </summary>
    enum SharedMemoryBankMapping
    {
        FourBytesPerBank,
        EightBytesPerBank
    }

    /// <summary>
    /// Denormal behavior of 32-bits float narrowing instructions.
    /// </summary>
    enum Fp32NarrowInstruction
    {
        KeepDenorms,
        FlushDenorms
    }

    /// <summary>
    /// Configuration of the L1 cache.
    /// </summary>
    enum L1Configuration
    {
        DirectlyAddressableMemorySize16kb,
        DirectlyAddressableMemorySize32kb,
        DirectlyAddressableMemorySize48kb
    }

    /// <summary>
    /// Reduction operation.
    /// </summary>
    enum ReductionOp
    {
        RedAdd,
        RedMin,
        RedMax,
        RedInc,
        RedDec,
        RedAnd,
        RedOr,
        RedXor
    }

    /// <summary>
    /// Reduction format.
    /// </summary>
    enum ReductionFormat
    {
        Unsigned32,
        Signed32
    }

    /// <summary>
    /// Size of a structure in words.
    /// </summary>
    enum StructureSize
    {
        FourWords,
        OneWord
    }

    /// <summary>
    /// Compute Queue Meta Data.
    /// </summary>
    unsafe struct ComputeQmd
    {
        private fixed int _words[64];

        public int OuterPut => BitRange(30, 0);
        public bool OuterOverflow => Bit(31);
        public int OuterGet => BitRange(62, 32);
        public bool OuterStickyOverflow => Bit(63);
        public int InnerGet => BitRange(94, 64);
        public bool InnerOverflow => Bit(95);
        public int InnerPut => BitRange(126, 96);
        public bool InnerStickyOverflow => Bit(127);
        public int QmdReservedAA => BitRange(159, 128);
        public int DependentQmdPointer => BitRange(191, 160);
        public int QmdGroupId => BitRange(197, 192);
        public bool SmGlobalCachingEnable => Bit(198);
        public bool RunCtaInOneSmPartition => Bit(199);
        public bool IsQueue => Bit(200);
        public bool AddToHeadOfQmdGroupLinkedList => Bit(201);
        public bool SemaphoreReleaseEnable0 => Bit(202);
        public bool SemaphoreReleaseEnable1 => Bit(203);
        public bool RequireSchedulingPcas => Bit(204);
        public bool DependentQmdScheduleEnable => Bit(205);
        public DependentQmdType DependentQmdType => (DependentQmdType)BitRange(206, 206);
        public bool DependentQmdFieldCopy => Bit(207);
        public int QmdReservedB => BitRange(223, 208);
        public int CircularQueueSize => BitRange(248, 224);
        public bool QmdReservedC => Bit(249);
        public bool InvalidateTextureHeaderCache => Bit(250);
        public bool InvalidateTextureSamplerCache => Bit(251);
        public bool InvalidateTextureDataCache => Bit(252);
        public bool InvalidateShaderDataCache => Bit(253);
        public bool InvalidateInstructionCache => Bit(254);
        public bool InvalidateShaderConstantCache => Bit(255);
        public int ProgramOffset => BitRange(287, 256);
        public int CircularQueueAddrLower => BitRange(319, 288);
        public int CircularQueueAddrUpper => BitRange(327, 320);
        public int QmdReservedD => BitRange(335, 328);
        public int CircularQueueEntrySize => BitRange(351, 336);
        public int CwdReferenceCountId => BitRange(357, 352);
        public int CwdReferenceCountDeltaMinusOne => BitRange(365, 358);
        public ReleaseMembarType ReleaseMembarType => (ReleaseMembarType)BitRange(366, 366);
        public bool CwdReferenceCountIncrEnable => Bit(367);
        public CwdMembarType CwdMembarType => (CwdMembarType)BitRange(369, 368);
        public bool SequentiallyRunCtas => Bit(370);
        public bool CwdReferenceCountDecrEnable => Bit(371);
        public bool Throttled => Bit(372);
        public Fp32NanBehavior Fp32NanBehavior => (Fp32NanBehavior)BitRange(376, 376);
        public Fp32F2iNanBehavior Fp32F2iNanBehavior => (Fp32F2iNanBehavior)BitRange(377, 377);
        public ApiVisibleCallLimit ApiVisibleCallLimit => (ApiVisibleCallLimit)BitRange(378, 378);
        public SharedMemoryBankMapping SharedMemoryBankMapping => (SharedMemoryBankMapping)BitRange(379, 379);
        public SamplerIndex SamplerIndex => (SamplerIndex)BitRange(382, 382);
        public Fp32NarrowInstruction Fp32NarrowInstruction => (Fp32NarrowInstruction)BitRange(383, 383);
        public int CtaRasterWidth => BitRange(415, 384);
        public int CtaRasterHeight => BitRange(431, 416);
        public int CtaRasterDepth => BitRange(447, 432);
        public int CtaRasterWidthResume => BitRange(479, 448);
        public int CtaRasterHeightResume => BitRange(495, 480);
        public int CtaRasterDepthResume => BitRange(511, 496);
        public int QueueEntriesPerCtaMinusOne => BitRange(518, 512);
        public int CoalesceWaitingPeriod => BitRange(529, 522);
        public int SharedMemorySize => BitRange(561, 544);
        public int QmdReservedG => BitRange(575, 562);
        public int QmdVersion => BitRange(579, 576);
        public int QmdMajorVersion => BitRange(583, 580);
        public int QmdReservedH => BitRange(591, 584);
        public int CtaThreadDimension0 => BitRange(607, 592);
        public int CtaThreadDimension1 => BitRange(623, 608);
        public int CtaThreadDimension2 => BitRange(639, 624);
        public bool ConstantBufferValid(int i) => Bit(640 + i * 1);
        public int QmdReservedI => BitRange(668, 648);
        public L1Configuration L1Configuration => (L1Configuration)BitRange(671, 669);
        public int SmDisableMaskLower => BitRange(703, 672);
        public int SmDisableMaskUpper => BitRange(735, 704);
        public int Release0AddressLower => BitRange(767, 736);
        public int Release0AddressUpper => BitRange(775, 768);
        public int QmdReservedJ => BitRange(783, 776);
        public ReductionOp Release0ReductionOp => (ReductionOp)BitRange(790, 788);
        public bool QmdReservedK => Bit(791);
        public ReductionFormat Release0ReductionFormat => (ReductionFormat)BitRange(793, 792);
        public bool Release0ReductionEnable => Bit(794);
        public StructureSize Release0StructureSize => (StructureSize)BitRange(799, 799);
        public int Release0Payload => BitRange(831, 800);
        public int Release1AddressLower => BitRange(863, 832);
        public int Release1AddressUpper => BitRange(871, 864);
        public int QmdReservedL => BitRange(879, 872);
        public ReductionOp Release1ReductionOp => (ReductionOp)BitRange(886, 884);
        public bool QmdReservedM => Bit(887);
        public ReductionFormat Release1ReductionFormat => (ReductionFormat)BitRange(889, 888);
        public bool Release1ReductionEnable => Bit(890);
        public StructureSize Release1StructureSize => (StructureSize)BitRange(895, 895);
        public int Release1Payload => BitRange(927, 896);
        public int ConstantBufferAddrLower(int i) => BitRange(959 + i * 64, 928 + i * 64);
        public int ConstantBufferAddrUpper(int i) => BitRange(967 + i * 64, 960 + i * 64);
        public int ConstantBufferReservedAddr(int i) => BitRange(973 + i * 64, 968 + i * 64);
        public bool ConstantBufferInvalidate(int i) => Bit(974 + i * 64);
        public int ConstantBufferSize(int i) => BitRange(991 + i * 64, 975 + i * 64);
        public int ShaderLocalMemoryLowSize => BitRange(1463, 1440);
        public int QmdReservedN => BitRange(1466, 1464);
        public int BarrierCount => BitRange(1471, 1467);
        public int ShaderLocalMemoryHighSize => BitRange(1495, 1472);
        public int RegisterCount => BitRange(1503, 1496);
        public int ShaderLocalMemoryCrsSize => BitRange(1527, 1504);
        public int SassVersion => BitRange(1535, 1528);
        public int HwOnlyInnerGet => BitRange(1566, 1536);
        public bool HwOnlyRequireSchedulingPcas => Bit(1567);
        public int HwOnlyInnerPut => BitRange(1598, 1568);
        public bool HwOnlyScgType => Bit(1599);
        public int HwOnlySpanListHeadIndex => BitRange(1629, 1600);
        public bool QmdReservedQ => Bit(1630);
        public bool HwOnlySpanListHeadIndexValid => Bit(1631);
        public int HwOnlySkedNextQmdPointer => BitRange(1663, 1632);
        public int QmdSpareE => BitRange(1695, 1664);
        public int QmdSpareF => BitRange(1727, 1696);
        public int QmdSpareG => BitRange(1759, 1728);
        public int QmdSpareH => BitRange(1791, 1760);
        public int QmdSpareI => BitRange(1823, 1792);
        public int QmdSpareJ => BitRange(1855, 1824);
        public int QmdSpareK => BitRange(1887, 1856);
        public int QmdSpareL => BitRange(1919, 1888);
        public int QmdSpareM => BitRange(1951, 1920);
        public int QmdSpareN => BitRange(1983, 1952);
        public int DebugIdUpper => BitRange(2015, 1984);
        public int DebugIdLower => BitRange(2047, 2016);

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private bool Bit(int bit)
        {
            if ((uint)bit >= 64 * 32)
            {
                throw new ArgumentOutOfRangeException(nameof(bit));
            }

            return (_words[bit >> 5] & (1 << (bit & 31))) != 0;
        }

        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        private int BitRange(int upper, int lower)
        {
            if ((uint)lower >= 64 * 32)
            {
                throw new ArgumentOutOfRangeException(nameof(lower));
            }

            int mask = (int)(uint.MaxValue >> (32 - (upper - lower + 1)));

            return (_words[lower >> 5] >> (lower & 31)) & mask;
        }
    }
}