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 }