/ src / Ryujinx.Graphics.Gpu / Image / TextureDescriptor.cs
TextureDescriptor.cs
  1  using System;
  2  using System.Runtime.CompilerServices;
  3  using System.Runtime.Intrinsics;
  4  
  5  namespace Ryujinx.Graphics.Gpu.Image
  6  {
  7      /// <summary>
  8      /// Maxwell texture descriptor, as stored on the GPU texture pool memory region.
  9      /// </summary>
 10      struct TextureDescriptor : ITextureDescriptor, IEquatable<TextureDescriptor>
 11      {
 12  #pragma warning disable CS0649 // Field is never assigned to
 13          public uint Word0;
 14          public uint Word1;
 15          public uint Word2;
 16          public uint Word3;
 17          public uint Word4;
 18          public uint Word5;
 19          public uint Word6;
 20          public uint Word7;
 21  #pragma warning restore CS0649
 22  
 23          /// <summary>
 24          /// Unpacks Maxwell texture format integer.
 25          /// </summary>
 26          /// <returns>The texture format integer</returns>
 27          public readonly uint UnpackFormat()
 28          {
 29              return Word0 & 0x8007ffff;
 30          }
 31  
 32          /// <summary>
 33          /// Unpacks the swizzle component for the texture red color channel.
 34          /// </summary>
 35          /// <returns>The swizzle component</returns>
 36          public readonly TextureComponent UnpackSwizzleR()
 37          {
 38              return (TextureComponent)((Word0 >> 19) & 7);
 39          }
 40  
 41          /// <summary>
 42          /// Unpacks the swizzle component for the texture green color channel.
 43          /// </summary>
 44          /// <returns>The swizzle component</returns>
 45          public readonly TextureComponent UnpackSwizzleG()
 46          {
 47              return (TextureComponent)((Word0 >> 22) & 7);
 48          }
 49  
 50          /// <summary>
 51          /// Unpacks the swizzle component for the texture blue color channel.
 52          /// </summary>
 53          /// <returns>The swizzle component</returns>
 54          public readonly TextureComponent UnpackSwizzleB()
 55          {
 56              return (TextureComponent)((Word0 >> 25) & 7);
 57          }
 58  
 59          /// <summary>
 60          /// Unpacks the swizzle component for the texture alpha color channel.
 61          /// </summary>
 62          /// <returns>The swizzle component</returns>
 63          public readonly TextureComponent UnpackSwizzleA()
 64          {
 65              return (TextureComponent)((Word0 >> 28) & 7);
 66          }
 67  
 68          /// <summary>
 69          /// Unpacks the 40-bits texture GPU virtual address.
 70          /// </summary>
 71          /// <returns>The GPU virtual address</returns>
 72          public readonly ulong UnpackAddress()
 73          {
 74              return Word1 | ((ulong)(Word2 & 0xffff) << 32);
 75          }
 76  
 77          /// <summary>
 78          /// Unpacks texture descriptor type for this texture descriptor.
 79          /// This defines the texture layout, among other things.
 80          /// </summary>
 81          /// <returns>The texture descriptor type</returns>
 82          public readonly TextureDescriptorType UnpackTextureDescriptorType()
 83          {
 84              return (TextureDescriptorType)((Word2 >> 21) & 7);
 85          }
 86  
 87          /// <summary>
 88          /// Unpacks the texture stride (bytes per line) for linear textures only.
 89          /// Always 32-bytes aligned.
 90          /// </summary>
 91          /// <returns>The linear texture stride</returns>
 92          public readonly int UnpackStride()
 93          {
 94              return (int)(Word3 & 0xffff) << 5;
 95          }
 96  
 97          /// <summary>
 98          /// Unpacks the GOB block size in X (width) for block linear textures.
 99          /// Must be always 1, ignored by the GPU.
100          /// </summary>
101          /// <returns>THe GOB block X size</returns>
102          public readonly int UnpackGobBlocksInX()
103          {
104              return 1 << (int)(Word3 & 7);
105          }
106  
107          /// <summary>
108          /// Unpacks the GOB block size in Y (height) for block linear textures.
109          /// Must be always a power of 2, with a maximum value of 32.
110          /// </summary>
111          /// <returns>THe GOB block Y size</returns>
112          public readonly int UnpackGobBlocksInY()
113          {
114              return 1 << (int)((Word3 >> 3) & 7);
115          }
116  
117          /// <summary>
118          /// Unpacks the GOB block size in Z (depth) for block linear textures.
119          /// Must be always a power of 2, with a maximum value of 32.
120          /// Must be 1 for any texture target other than 3D textures.
121          /// </summary>
122          /// <returns>The GOB block Z size</returns>
123          public readonly int UnpackGobBlocksInZ()
124          {
125              return 1 << (int)((Word3 >> 6) & 7);
126          }
127  
128          /// <summary>
129          /// Number of GOB blocks per tile in the X direction.
130          /// This is only used for sparse textures, should be 1 otherwise.
131          /// </summary>
132          /// <returns>The number of GOB blocks per tile</returns>
133          public readonly int UnpackGobBlocksInTileX()
134          {
135              return 1 << (int)((Word3 >> 10) & 7);
136          }
137  
138          /// <summary>
139          /// Unpacks the number of mipmap levels of the texture.
140          /// </summary>
141          /// <returns>The number of mipmap levels</returns>
142          public readonly int UnpackLevels()
143          {
144              return (int)(Word3 >> 28) + 1;
145          }
146  
147          /// <summary>
148          /// Unpack the base level texture width size.
149          /// </summary>
150          /// <returns>The texture width</returns>
151          public readonly int UnpackWidth()
152          {
153              return (int)(Word4 & 0xffff) + 1;
154          }
155  
156          /// <summary>
157          /// Unpack the width of a buffer texture.
158          /// </summary>
159          /// <returns>The texture width</returns>
160          public readonly int UnpackBufferTextureWidth()
161          {
162              return (int)((Word4 & 0xffff) | (Word3 << 16)) + 1;
163          }
164  
165          /// <summary>
166          /// Unpacks the texture sRGB format flag.
167          /// </summary>
168          /// <returns>True if the texture is sRGB, false otherwise</returns>
169          public readonly bool UnpackSrgb()
170          {
171              return (Word4 & (1 << 22)) != 0;
172          }
173  
174          /// <summary>
175          /// Unpacks the texture target.
176          /// </summary>
177          /// <returns>The texture target</returns>
178          public readonly TextureTarget UnpackTextureTarget()
179          {
180              return (TextureTarget)((Word4 >> 23) & 0xf);
181          }
182  
183          /// <summary>
184          /// Unpack the base level texture height size, or array layers for 1D array textures.
185          /// Should be ignored for 1D or buffer textures.
186          /// </summary>
187          /// <returns>The texture height or layers count</returns>
188          public readonly int UnpackHeight()
189          {
190              return (int)(Word5 & 0xffff) + 1;
191          }
192  
193          /// <summary>
194          /// Unpack the base level texture depth size, number of array layers or cubemap faces.
195          /// The meaning of this value depends on the texture target.
196          /// </summary>
197          /// <returns>The texture depth, layer or faces count</returns>
198          public readonly int UnpackDepth()
199          {
200              return (int)((Word5 >> 16) & 0x3fff) + 1;
201          }
202  
203          /// <summary>
204          /// Unpacks the texture coordinates normalized flag.
205          /// When this is true, texture coordinates are expected to be in the [0, 1] range on the shader.
206          /// When this is false, texture coordinates are expected to be in the [0, W], [0, H] and [0, D] range.
207          /// It must be set to false (by the guest driver) for rectangle textures.
208          /// </summary>
209          /// <returns>The texture coordinates normalized flag</returns>
210          public readonly bool UnpackTextureCoordNormalized()
211          {
212              return (Word5 & (1 << 31)) != 0;
213          }
214  
215          /// <summary>
216          /// Unpacks the base mipmap level of the texture.
217          /// </summary>
218          /// <returns>The base mipmap level of the texture</returns>
219          public readonly int UnpackBaseLevel()
220          {
221              return (int)(Word7 & 0xf);
222          }
223  
224          /// <summary>
225          /// Unpacks the maximum mipmap level (inclusive) of the texture.
226          /// Usually equal to Levels minus 1.
227          /// </summary>
228          /// <returns>The maximum mipmap level (inclusive) of the texture</returns>
229          public readonly int UnpackMaxLevelInclusive()
230          {
231              return (int)((Word7 >> 4) & 0xf);
232          }
233  
234          /// <summary>
235          /// Unpacks the multisampled texture samples count in each direction.
236          /// Must be ignored for non-multisample textures.
237          /// </summary>
238          /// <returns>The multisample counts enum</returns>
239          public readonly TextureMsaaMode UnpackTextureMsaaMode()
240          {
241              return (TextureMsaaMode)((Word7 >> 8) & 0xf);
242          }
243  
244          /// <summary>
245          /// Check if two descriptors are equal.
246          /// </summary>
247          /// <param name="other">The descriptor to compare against</param>
248          /// <returns>True if they are equal, false otherwise</returns>
249          public bool Equals(ref TextureDescriptor other)
250          {
251              return Unsafe.As<TextureDescriptor, Vector256<byte>>(ref this).Equals(Unsafe.As<TextureDescriptor, Vector256<byte>>(ref other));
252          }
253  
254          /// <summary>
255          /// Check if two descriptors are equal.
256          /// </summary>
257          /// <param name="other">The descriptor to compare against</param>
258          /// <returns>True if they are equal, false otherwise</returns>
259          public bool Equals(TextureDescriptor other)
260          {
261              return Equals(ref other);
262          }
263  
264          /// <summary>
265          /// Gets a hash code for this descriptor.
266          /// </summary>
267          /// <returns>The hash code for this descriptor.</returns>
268          public override int GetHashCode()
269          {
270              return Unsafe.As<TextureDescriptor, Vector256<byte>>(ref this).GetHashCode();
271          }
272  
273          public override bool Equals(object obj)
274          {
275              return obj is TextureDescriptor descriptor && Equals(descriptor);
276          }
277      }
278  }