/ src / Ryujinx.Graphics.Gpu / Image / FormatTable.cs
FormatTable.cs
  1  using Ryujinx.Graphics.GAL;
  2  using System.Collections.Generic;
  3  using System.Diagnostics.CodeAnalysis;
  4  
  5  namespace Ryujinx.Graphics.Gpu.Image
  6  {
  7      /// <summary>
  8      /// Contains format tables, for texture and vertex attribute formats.
  9      /// </summary>
 10      static class FormatTable
 11      {
 12  #pragma warning disable IDE0055 // Disable formatting
 13          [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
 14          private enum TextureFormat : uint
 15          {
 16              // Formats
 17              R32G32B32A32 = 0x01,
 18              R32G32B32 = 0x02,
 19              R16G16B16A16 = 0x03,
 20              R32G32 = 0x04,
 21              R32B24G8 = 0x05,
 22              X8B8G8R8 = 0x07,
 23              A8B8G8R8 = 0x08,
 24              A2B10G10R10 = 0x09,
 25              R16G16 = 0x0c,
 26              G8R24 = 0x0d,
 27              G24R8 = 0x0e,
 28              R32 = 0x0f,
 29              A4B4G4R4 = 0x12,
 30              A5B5G5R1 = 0x13,
 31              A1B5G5R5 = 0x14,
 32              B5G6R5 = 0x15,
 33              B6G5R5 = 0x16,
 34              G8R8 = 0x18,
 35              R16 = 0x1b,
 36              Y8Video = 0x1c,
 37              R8 = 0x1d,
 38              G4R4 = 0x1e,
 39              R1 = 0x1f,
 40              E5B9G9R9SharedExp = 0x20,
 41              Bf10Gf11Rf11 = 0x21,
 42              G8B8G8R8 = 0x22,
 43              B8G8R8G8 = 0x23,
 44              Bc1 = 0x24,
 45              Bc2 = 0x25,
 46              Bc3 = 0x26,
 47              Bc4 = 0x27,
 48              Bc5 = 0x28,
 49              Bc6HSf16 = 0x10,
 50              Bc6HUf16 = 0x11,
 51              Bc7U = 0x17,
 52              Etc2Rgb = 0x06,
 53              Etc2RgbPta = 0x0a,
 54              Etc2Rgba = 0x0b,
 55              Eac = 0x19,
 56              Eacx2 = 0x1a,
 57              Z24S8 = 0x29,
 58              X8Z24 = 0x2a,
 59              S8Z24 = 0x2b,
 60              X4V4Z24Cov4R4V = 0x2c,
 61              X4V4Z24Cov8R8V = 0x2d,
 62              V8Z24Cov4R12V = 0x2e,
 63              Zf32 = 0x2f,
 64              Zf32X24S8 = 0x30,
 65              X8Z24X20V4S8Cov4R4V = 0x31,
 66              X8Z24X20V4S8Cov8R8V = 0x32,
 67              Zf32X20V4X8Cov4R4V = 0x33,
 68              Zf32X20V4X8Cov8R8V = 0x34,
 69              Zf32X20V4S8Cov4R4V = 0x35,
 70              Zf32X20V4S8Cov8R8V = 0x36,
 71              X8Z24X16V8S8Cov4R12V = 0x37,
 72              Zf32X16V8X8Cov4R12V = 0x38,
 73              Zf32X16V8S8Cov4R12V = 0x39,
 74              Z16 = 0x3a,
 75              V8Z24Cov8R24V = 0x3b,
 76              X8Z24X16V8S8Cov8R24V = 0x3c,
 77              Zf32X16V8X8Cov8R24V = 0x3d,
 78              Zf32X16V8S8Cov8R24V = 0x3e,
 79              Astc2D4x4 = 0x40,
 80              Astc2D5x4 = 0x50,
 81              Astc2D5x5 = 0x41,
 82              Astc2D6x5 = 0x51,
 83              Astc2D6x6 = 0x42,
 84              Astc2D8x5 = 0x55,
 85              Astc2D8x6 = 0x52,
 86              Astc2D8x8 = 0x44,
 87              Astc2D10x5 = 0x56,
 88              Astc2D10x6 = 0x57,
 89              Astc2D10x8 = 0x53,
 90              Astc2D10x10 = 0x45,
 91              Astc2D12x10 = 0x54,
 92              Astc2D12x12 = 0x46,
 93  
 94              // Types
 95              Snorm = 0x1,
 96              Unorm = 0x2,
 97              Sint = 0x3,
 98              Uint = 0x4,
 99              SnormForceFp16 = 0x5,
100              UnormForceFp16 = 0x6,
101              Float = 0x7,
102  
103              // Component Types
104              RSnorm = Snorm << 7,
105              GSnorm = Snorm << 10,
106              BSnorm = Snorm << 13,
107              ASnorm = Snorm << 16,
108  
109              RUnorm = Unorm << 7,
110              GUnorm = Unorm << 10,
111              BUnorm = Unorm << 13,
112              AUnorm = Unorm << 16,
113  
114              RSint = Sint << 7,
115              GSint = Sint << 10,
116              BSint = Sint << 13,
117              ASint = Sint << 16,
118  
119              RUint = Uint << 7,
120              GUint = Uint << 10,
121              BUint = Uint << 13,
122              AUint = Uint << 16,
123  
124              RSnormForceFp16 = SnormForceFp16 << 7,
125              GSnormForceFp16 = SnormForceFp16 << 10,
126              BSnormForceFp16 = SnormForceFp16 << 13,
127              ASnormForceFp16 = SnormForceFp16 << 16,
128  
129              RUnormForceFp16 = UnormForceFp16 << 7,
130              GUnormForceFp16 = UnormForceFp16 << 10,
131              BUnormForceFp16 = UnormForceFp16 << 13,
132              AUnormForceFp16 = UnormForceFp16 << 16,
133  
134              RFloat = Float << 7,
135              GFloat = Float << 10,
136              BFloat = Float << 13,
137              AFloat = Float << 16,
138  
139              Srgb = 0x1 << 19, // Custom encoding
140  
141              // Combinations
142              R8Unorm                          = R8                | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2491d
143              R8Snorm                          = R8                | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x1249d
144              R8Uint                           = R8                | RUint  | GUint  | BUint  | AUint,         // 0x4921d
145              R8Sint                           = R8                | RSint  | GSint  | BSint  | ASint,         // 0x36d9d
146              R16Float                         = R16               | RFloat | GFloat | BFloat | AFloat,        // 0x7ff9b
147              R16Unorm                         = R16               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2491b
148              R16Snorm                         = R16               | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x1249b
149              R16Uint                          = R16               | RUint  | GUint  | BUint  | AUint,         // 0x4921b
150              R16Sint                          = R16               | RSint  | GSint  | BSint  | ASint,         // 0x36d9b
151              R32Float                         = R32               | RFloat | GFloat | BFloat | AFloat,        // 0x7ff8f
152              R32Uint                          = R32               | RUint  | GUint  | BUint  | AUint,         // 0x4920f
153              R32Sint                          = R32               | RSint  | GSint  | BSint  | ASint,         // 0x36d8f
154              G8R8Unorm                        = G8R8              | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24918
155              G8R8Snorm                        = G8R8              | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x12498
156              G8R8Uint                         = G8R8              | RUint  | GUint  | BUint  | AUint,         // 0x49218
157              G8R8Sint                         = G8R8              | RSint  | GSint  | BSint  | ASint,         // 0x36d98
158              R16G16Float                      = R16G16            | RFloat | GFloat | BFloat | AFloat,        // 0x7ff8c
159              R16G16Unorm                      = R16G16            | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2490c
160              R16G16Snorm                      = R16G16            | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x1248c
161              R16G16Uint                       = R16G16            | RUint  | GUint  | BUint  | AUint,         // 0x4920c
162              R16G16Sint                       = R16G16            | RSint  | GSint  | BSint  | ASint,         // 0x36d8c
163              R32G32Float                      = R32G32            | RFloat | GFloat | BFloat | AFloat,        // 0x7ff84
164              R32G32Uint                       = R32G32            | RUint  | GUint  | BUint  | AUint,         // 0x49204
165              R32G32Sint                       = R32G32            | RSint  | GSint  | BSint  | ASint,         // 0x36d84
166              R32G32B32Float                   = R32G32B32         | RFloat | GFloat | BFloat | AFloat,        // 0x7ff82
167              R32G32B32Uint                    = R32G32B32         | RUint  | GUint  | BUint  | AUint,         // 0x49202
168              R32G32B32Sint                    = R32G32B32         | RSint  | GSint  | BSint  | ASint,         // 0x36d82
169              A8B8G8R8Unorm                    = A8B8G8R8          | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24908
170              A8B8G8R8Snorm                    = A8B8G8R8          | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x12488
171              A8B8G8R8Uint                     = A8B8G8R8          | RUint  | GUint  | BUint  | AUint,         // 0x49208
172              A8B8G8R8Sint                     = A8B8G8R8          | RSint  | GSint  | BSint  | ASint,         // 0x36d88
173              R16G16B16A16Float                = R16G16B16A16      | RFloat | GFloat | BFloat | AFloat,        // 0x7ff83
174              R16G16B16A16Unorm                = R16G16B16A16      | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24903
175              R16G16B16A16Snorm                = R16G16B16A16      | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x12483
176              R16G16B16A16Uint                 = R16G16B16A16      | RUint  | GUint  | BUint  | AUint,         // 0x49203
177              R16G16B16A16Sint                 = R16G16B16A16      | RSint  | GSint  | BSint  | ASint,         // 0x36d83
178              R32G32B32A32Float                = R32G32B32A32      | RFloat | GFloat | BFloat | AFloat,        // 0x7ff81
179              R32G32B32A32Uint                 = R32G32B32A32      | RUint  | GUint  | BUint  | AUint,         // 0x49201
180              R32G32B32A32Sint                 = R32G32B32A32      | RSint  | GSint  | BSint  | ASint,         // 0x36d81
181              Z16Unorm                         = Z16               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2493a
182              Z16RUnormGUintBUintAUint         = Z16               | RUnorm | GUint  | BUint  | AUint,         // 0x4913a
183              Zf32RFloatGUintBUintAUint        = Zf32              | RFloat | GUint  | BUint  | AUint,         // 0x493af
184              Zf32Float                        = Zf32              | RFloat | GFloat | BFloat | AFloat,        // 0x7ffaf
185              G24R8RUintGUnormBUnormAUnorm     = G24R8             | RUint  | GUnorm | BUnorm | AUnorm,        // 0x24a0e
186              Z24S8RUintGUnormBUnormAUnorm     = Z24S8             | RUint  | GUnorm | BUnorm | AUnorm,        // 0x24a29
187              Z24S8RUintGUnormBUintAUint       = Z24S8             | RUint  | GUnorm | BUint  | AUint,         // 0x48a29
188              X8Z24RUnormGUintBUintAUint       = X8Z24             | RUnorm | GUint  | BUint  | AUint,         // 0x4912a
189              S8Z24RUnormGUintBUintAUint       = S8Z24             | RUnorm | GUint  | BUint  | AUint,         // 0x4912b
190              R32B24G8RFloatGUintBUnormAUnorm  = R32B24G8          | RFloat | GUint  | BUnorm | AUnorm,        // 0x25385
191              Zf32X24S8RFloatGUintBUnormAUnorm = Zf32X24S8         | RFloat | GUint  | BUnorm | AUnorm,        // 0x253b0
192              A8B8G8R8UnormSrgb                = A8B8G8R8          | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4908
193              G4R4Unorm                        = G4R4              | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2491e
194              A4B4G4R4Unorm                    = A4B4G4R4          | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24912
195              A1B5G5R5Unorm                    = A1B5G5R5          | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24914
196              B5G6R5Unorm                      = B5G6R5            | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24915
197              A2B10G10R10Unorm                 = A2B10G10R10       | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24909
198              A2B10G10R10Uint                  = A2B10G10R10       | RUint  | GUint  | BUint  | AUint,         // 0x49209
199              Bf10Gf11Rf11Float                = Bf10Gf11Rf11      | RFloat | GFloat | BFloat | AFloat,        // 0x7ffa1
200              E5B9G9R9SharedExpFloat           = E5B9G9R9SharedExp | RFloat | GFloat | BFloat | AFloat,        // 0x7ffa0
201              Bc1Unorm                         = Bc1               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24924
202              Bc2Unorm                         = Bc2               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24925
203              Bc3Unorm                         = Bc3               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24926
204              Bc1UnormSrgb                     = Bc1               | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4924
205              Bc2UnormSrgb                     = Bc2               | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4925
206              Bc3UnormSrgb                     = Bc3               | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4926
207              Bc4Unorm                         = Bc4               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24927
208              Bc4Snorm                         = Bc4               | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x124a7
209              Bc5Unorm                         = Bc5               | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24928
210              Bc5Snorm                         = Bc5               | RSnorm | GSnorm | BSnorm | ASnorm,        // 0x124a8
211              Bc7UUnorm                        = Bc7U              | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24917
212              Bc7UUnormSrgb                    = Bc7U              | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4917
213              Bc6HSf16Float                    = Bc6HSf16          | RFloat | GFloat | BFloat | AFloat,        // 0x7ff90
214              Bc6HUf16Float                    = Bc6HUf16          | RFloat | GFloat | BFloat | AFloat,        // 0x7ff91
215              Etc2RgbUnorm                     = Etc2Rgb           | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24906
216              Etc2RgbPtaUnorm                  = Etc2RgbPta        | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2490a
217              Etc2RgbaUnorm                    = Etc2Rgba          | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x2490b
218              Etc2RgbUnormSrgb                 = Etc2Rgb           | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4906
219              Etc2RgbPtaUnormSrgb              = Etc2RgbPta        | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa490a
220              Etc2RgbaUnormSrgb                = Etc2Rgba          | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa490b
221              Astc2D4x4Unorm                   = Astc2D4x4         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24940
222              Astc2D5x4Unorm                   = Astc2D5x4         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24950
223              Astc2D5x5Unorm                   = Astc2D5x5         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24941
224              Astc2D6x5Unorm                   = Astc2D6x5         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24951
225              Astc2D6x6Unorm                   = Astc2D6x6         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24942
226              Astc2D8x5Unorm                   = Astc2D8x5         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24955
227              Astc2D8x6Unorm                   = Astc2D8x6         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24952
228              Astc2D8x8Unorm                   = Astc2D8x8         | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24944
229              Astc2D10x5Unorm                  = Astc2D10x5        | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24956
230              Astc2D10x6Unorm                  = Astc2D10x6        | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24957
231              Astc2D10x8Unorm                  = Astc2D10x8        | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24953
232              Astc2D10x10Unorm                 = Astc2D10x10       | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24945
233              Astc2D12x10Unorm                 = Astc2D12x10       | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24954
234              Astc2D12x12Unorm                 = Astc2D12x12       | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24946
235              Astc2D4x4UnormSrgb               = Astc2D4x4         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4940
236              Astc2D5x4UnormSrgb               = Astc2D5x4         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4950
237              Astc2D5x5UnormSrgb               = Astc2D5x5         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4941
238              Astc2D6x5UnormSrgb               = Astc2D6x5         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4951
239              Astc2D6x6UnormSrgb               = Astc2D6x6         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4942
240              Astc2D8x5UnormSrgb               = Astc2D8x5         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4955
241              Astc2D8x6UnormSrgb               = Astc2D8x6         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4952
242              Astc2D8x8UnormSrgb               = Astc2D8x8         | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4944
243              Astc2D10x5UnormSrgb              = Astc2D10x5        | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4956
244              Astc2D10x6UnormSrgb              = Astc2D10x6        | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4957
245              Astc2D10x8UnormSrgb              = Astc2D10x8        | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4953
246              Astc2D10x10UnormSrgb             = Astc2D10x10       | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4945
247              Astc2D12x10UnormSrgb             = Astc2D12x10       | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4954
248              Astc2D12x12UnormSrgb             = Astc2D12x12       | RUnorm | GUnorm | BUnorm | AUnorm | Srgb, // 0xa4946
249              A5B5G5R1Unorm                    = A5B5G5R1          | RUnorm | GUnorm | BUnorm | AUnorm,        // 0x24913
250          }
251  
252          [SuppressMessage("Design", "CA1069: Enums values should not be duplicated")]
253          private enum VertexAttributeFormat : uint
254          {
255              // Width
256              R32G32B32A32 = 0x01,
257              R32G32B32 = 0x02,
258              R16G16B16A16 = 0x03,
259              R32G32 = 0x04,
260              R16G16B16 = 0x05,
261              A8B8G8R8 = 0x2f,
262              R8G8B8A8 = 0x0a,
263              X8B8G8R8 = 0x33,
264              A2B10G10R10 = 0x30,
265              B10G11R11 = 0x31,
266              R16G16 = 0x0f,
267              R32 = 0x12,
268              R8G8B8 = 0x13,
269              G8R8 = 0x32,
270              R8G8 = 0x18,
271              R16 = 0x1b,
272              R8 = 0x1d,
273              A8 = 0x34,
274  
275              // Type
276              Snorm = 0x01,
277              Unorm = 0x02,
278              Sint = 0x03,
279              Uint = 0x04,
280              Uscaled = 0x05,
281              Sscaled = 0x06,
282              Float = 0x07,
283  
284              // Combinations
285              R8Unorm             = (R8 << 21)           | (Unorm << 27),   // 0x13a00000
286              R8Snorm             = (R8 << 21)           | (Snorm << 27),   // 0x0ba00000
287              R8Uint              = (R8 << 21)           | (Uint << 27),    // 0x23a00000
288              R8Sint              = (R8 << 21)           | (Sint << 27),    // 0x1ba00000
289              R16Float            = (R16 << 21)          | (Float << 27),   // 0x3b600000
290              R16Unorm            = (R16 << 21)          | (Unorm << 27),   // 0x13600000
291              R16Snorm            = (R16 << 21)          | (Snorm << 27),   // 0x0b600000
292              R16Uint             = (R16 << 21)          | (Uint << 27),    // 0x23600000
293              R16Sint             = (R16 << 21)          | (Sint << 27),    // 0x1b600000
294              R32Float            = (R32 << 21)          | (Float << 27),   // 0x3a400000
295              R32Uint             = (R32 << 21)          | (Uint << 27),    // 0x22400000
296              R32Sint             = (R32 << 21)          | (Sint << 27),    // 0x1a400000
297              R8G8Unorm           = (R8G8 << 21)         | (Unorm << 27),   // 0x13000000
298              R8G8Snorm           = (R8G8 << 21)         | (Snorm << 27),   // 0x0b000000
299              R8G8Uint            = (R8G8 << 21)         | (Uint << 27),    // 0x23000000
300              R8G8Sint            = (R8G8 << 21)         | (Sint << 27),    // 0x1b000000
301              R16G16Float         = (R16G16 << 21)       | (Float << 27),   // 0x39e00000
302              R16G16Unorm         = (R16G16 << 21)       | (Unorm << 27),   // 0x11e00000
303              R16G16Snorm         = (R16G16 << 21)       | (Snorm << 27),   // 0x09e00000
304              R16G16Uint          = (R16G16 << 21)       | (Uint << 27),    // 0x21e00000
305              R16G16Sint          = (R16G16 << 21)       | (Sint << 27),    // 0x19e00000
306              R32G32Float         = (R32G32 << 21)       | (Float << 27),   // 0x38800000
307              R32G32Uint          = (R32G32 << 21)       | (Uint << 27),    // 0x20800000
308              R32G32Sint          = (R32G32 << 21)       | (Sint << 27),    // 0x18800000
309              R8G8B8Unorm         = (R8G8B8 << 21)       | (Unorm << 27),   // 0x12600000
310              R8G8B8Snorm         = (R8G8B8 << 21)       | (Snorm << 27),   // 0x0a600000
311              R8G8B8Uint          = (R8G8B8 << 21)       | (Uint << 27),    // 0x22600000
312              R8G8B8Sint          = (R8G8B8 << 21)       | (Sint << 27),    // 0x1a600000
313              R16G16B16Float      = (R16G16B16 << 21)    | (Float << 27),   // 0x38a00000
314              R16G16B16Unorm      = (R16G16B16 << 21)    | (Unorm << 27),   // 0x10a00000
315              R16G16B16Snorm      = (R16G16B16 << 21)    | (Snorm << 27),   // 0x08a00000
316              R16G16B16Uint       = (R16G16B16 << 21)    | (Uint << 27),    // 0x20a00000
317              R16G16B16Sint       = (R16G16B16 << 21)    | (Sint << 27),    // 0x18a00000
318              R32G32B32Float      = (R32G32B32 << 21)    | (Float << 27),   // 0x38400000
319              R32G32B32Uint       = (R32G32B32 << 21)    | (Uint << 27),    // 0x20400000
320              R32G32B32Sint       = (R32G32B32 << 21)    | (Sint << 27),    // 0x18400000
321              R8G8B8A8Unorm       = (R8G8B8A8 << 21)     | (Unorm << 27),   // 0x11400000
322              R8G8B8A8Snorm       = (R8G8B8A8 << 21)     | (Snorm << 27),   // 0x09400000
323              R8G8B8A8Uint        = (R8G8B8A8 << 21)     | (Uint << 27),    // 0x21400000
324              R8G8B8A8Sint        = (R8G8B8A8 << 21)     | (Sint << 27),    // 0x19400000
325              R16G16B16A16Float   = (R16G16B16A16 << 21) | (Float << 27),   // 0x38600000
326              R16G16B16A16Unorm   = (R16G16B16A16 << 21) | (Unorm << 27),   // 0x10600000
327              R16G16B16A16Snorm   = (R16G16B16A16 << 21) | (Snorm << 27),   // 0x08600000
328              R16G16B16A16Uint    = (R16G16B16A16 << 21) | (Uint << 27),    // 0x20600000
329              R16G16B16A16Sint    = (R16G16B16A16 << 21) | (Sint << 27),    // 0x18600000
330              R32G32B32A32Float   = (R32G32B32A32 << 21) | (Float << 27),   // 0x38200000
331              R32G32B32A32Uint    = (R32G32B32A32 << 21) | (Uint << 27),    // 0x20200000
332              R32G32B32A32Sint    = (R32G32B32A32 << 21) | (Sint << 27),    // 0x18200000
333              A2B10G10R10Unorm    = (A2B10G10R10 << 21)  | (Unorm << 27),   // 0x16000000
334              A2B10G10R10Uint     = (A2B10G10R10 << 21)  | (Uint << 27),    // 0x26000000
335              B10G11R11Float      = (B10G11R11 << 21)    | (Float << 27),   // 0x3e200000
336              R8Uscaled           = (R8 << 21)           | (Uscaled << 27), // 0x2ba00000
337              R8Sscaled           = (R8 << 21)           | (Sscaled << 27), // 0x33a00000
338              R16Uscaled          = (R16 << 21)          | (Uscaled << 27), // 0x2b600000
339              R16Sscaled          = (R16 << 21)          | (Sscaled << 27), // 0x33600000
340              R32Uscaled          = (R32 << 21)          | (Uscaled << 27), // 0x2a400000
341              R32Sscaled          = (R32 << 21)          | (Sscaled << 27), // 0x32400000
342              R8G8Uscaled         = (R8G8 << 21)         | (Uscaled << 27), // 0x2b000000
343              R8G8Sscaled         = (R8G8 << 21)         | (Sscaled << 27), // 0x33000000
344              R16G16Uscaled       = (R16G16 << 21)       | (Uscaled << 27), // 0x29e00000
345              R16G16Sscaled       = (R16G16 << 21)       | (Sscaled << 27), // 0x31e00000
346              R32G32Uscaled       = (R32G32 << 21)       | (Uscaled << 27), // 0x28800000
347              R32G32Sscaled       = (R32G32 << 21)       | (Sscaled << 27), // 0x30800000
348              R8G8B8Uscaled       = (R8G8B8 << 21)       | (Uscaled << 27), // 0x2a600000
349              R8G8B8Sscaled       = (R8G8B8 << 21)       | (Sscaled << 27), // 0x32600000
350              R16G16B16Uscaled    = (R16G16B16 << 21)    | (Uscaled << 27), // 0x28a00000
351              R16G16B16Sscaled    = (R16G16B16 << 21)    | (Sscaled << 27), // 0x30a00000
352              R32G32B32Uscaled    = (R32G32B32 << 21)    | (Uscaled << 27), // 0x28400000
353              R32G32B32Sscaled    = (R32G32B32 << 21)    | (Sscaled << 27), // 0x30400000
354              R8G8B8A8Uscaled     = (R8G8B8A8 << 21)     | (Uscaled << 27), // 0x29400000
355              R8G8B8A8Sscaled     = (R8G8B8A8 << 21)     | (Sscaled << 27), // 0x31400000
356              R16G16B16A16Uscaled = (R16G16B16A16 << 21) | (Uscaled << 27), // 0x28600000
357              R16G16B16A16Sscaled = (R16G16B16A16 << 21) | (Sscaled << 27), // 0x30600000
358              R32G32B32A32Uscaled = (R32G32B32A32 << 21) | (Uscaled << 27), // 0x28200000
359              R32G32B32A32Sscaled = (R32G32B32A32 << 21) | (Sscaled << 27), // 0x30200000
360              A2B10G10R10Snorm    = (A2B10G10R10 << 21)  | (Snorm << 27),   // 0x0e000000
361              A2B10G10R10Sint     = (A2B10G10R10 << 21)  | (Sint << 27),    // 0x1e000000
362              A2B10G10R10Uscaled  = (A2B10G10R10 << 21)  | (Uscaled << 27), // 0x2e000000
363              A2B10G10R10Sscaled  = (A2B10G10R10 << 21)  | (Sscaled << 27), // 0x36000000
364          }
365  
366          private static readonly Dictionary<TextureFormat, FormatInfo> _textureFormats = new()
367          {
368              { TextureFormat.R8Unorm,                          new FormatInfo(Format.R8Unorm,           1,  1,  1,  1) },
369              { TextureFormat.R8Snorm,                          new FormatInfo(Format.R8Snorm,           1,  1,  1,  1) },
370              { TextureFormat.R8Uint,                           new FormatInfo(Format.R8Uint,            1,  1,  1,  1) },
371              { TextureFormat.R8Sint,                           new FormatInfo(Format.R8Sint,            1,  1,  1,  1) },
372              { TextureFormat.R16Float,                         new FormatInfo(Format.R16Float,          1,  1,  2,  1) },
373              { TextureFormat.R16Unorm,                         new FormatInfo(Format.R16Unorm,          1,  1,  2,  1) },
374              { TextureFormat.R16Snorm,                         new FormatInfo(Format.R16Snorm,          1,  1,  2,  1) },
375              { TextureFormat.R16Uint,                          new FormatInfo(Format.R16Uint,           1,  1,  2,  1) },
376              { TextureFormat.R16Sint,                          new FormatInfo(Format.R16Sint,           1,  1,  2,  1) },
377              { TextureFormat.R32Float,                         new FormatInfo(Format.R32Float,          1,  1,  4,  1) },
378              { TextureFormat.R32Uint,                          new FormatInfo(Format.R32Uint,           1,  1,  4,  1) },
379              { TextureFormat.R32Sint,                          new FormatInfo(Format.R32Sint,           1,  1,  4,  1) },
380              { TextureFormat.G8R8Unorm,                        new FormatInfo(Format.R8G8Unorm,         1,  1,  2,  2) },
381              { TextureFormat.G8R8Snorm,                        new FormatInfo(Format.R8G8Snorm,         1,  1,  2,  2) },
382              { TextureFormat.G8R8Uint,                         new FormatInfo(Format.R8G8Uint,          1,  1,  2,  2) },
383              { TextureFormat.G8R8Sint,                         new FormatInfo(Format.R8G8Sint,          1,  1,  2,  2) },
384              { TextureFormat.R16G16Float,                      new FormatInfo(Format.R16G16Float,       1,  1,  4,  2) },
385              { TextureFormat.R16G16Unorm,                      new FormatInfo(Format.R16G16Unorm,       1,  1,  4,  2) },
386              { TextureFormat.R16G16Snorm,                      new FormatInfo(Format.R16G16Snorm,       1,  1,  4,  2) },
387              { TextureFormat.R16G16Uint,                       new FormatInfo(Format.R16G16Uint,        1,  1,  4,  2) },
388              { TextureFormat.R16G16Sint,                       new FormatInfo(Format.R16G16Sint,        1,  1,  4,  2) },
389              { TextureFormat.R32G32Float,                      new FormatInfo(Format.R32G32Float,       1,  1,  8,  2) },
390              { TextureFormat.R32G32Uint,                       new FormatInfo(Format.R32G32Uint,        1,  1,  8,  2) },
391              { TextureFormat.R32G32Sint,                       new FormatInfo(Format.R32G32Sint,        1,  1,  8,  2) },
392              { TextureFormat.R32G32B32Float,                   new FormatInfo(Format.R32G32B32Float,    1,  1,  12, 3) },
393              { TextureFormat.R32G32B32Uint,                    new FormatInfo(Format.R32G32B32Uint,     1,  1,  12, 3) },
394              { TextureFormat.R32G32B32Sint,                    new FormatInfo(Format.R32G32B32Sint,     1,  1,  12, 3) },
395              { TextureFormat.A8B8G8R8Unorm,                    new FormatInfo(Format.R8G8B8A8Unorm,     1,  1,  4,  4) },
396              { TextureFormat.A8B8G8R8Snorm,                    new FormatInfo(Format.R8G8B8A8Snorm,     1,  1,  4,  4) },
397              { TextureFormat.A8B8G8R8Uint,                     new FormatInfo(Format.R8G8B8A8Uint,      1,  1,  4,  4) },
398              { TextureFormat.A8B8G8R8Sint,                     new FormatInfo(Format.R8G8B8A8Sint,      1,  1,  4,  4) },
399              { TextureFormat.R16G16B16A16Float,                new FormatInfo(Format.R16G16B16A16Float, 1,  1,  8,  4) },
400              { TextureFormat.R16G16B16A16Unorm,                new FormatInfo(Format.R16G16B16A16Unorm, 1,  1,  8,  4) },
401              { TextureFormat.R16G16B16A16Snorm,                new FormatInfo(Format.R16G16B16A16Snorm, 1,  1,  8,  4) },
402              { TextureFormat.R16G16B16A16Uint,                 new FormatInfo(Format.R16G16B16A16Uint,  1,  1,  8,  4) },
403              { TextureFormat.R16G16B16A16Sint,                 new FormatInfo(Format.R16G16B16A16Sint,  1,  1,  8,  4) },
404              { TextureFormat.R32G32B32A32Float,                new FormatInfo(Format.R32G32B32A32Float, 1,  1,  16, 4) },
405              { TextureFormat.R32G32B32A32Uint,                 new FormatInfo(Format.R32G32B32A32Uint,  1,  1,  16, 4) },
406              { TextureFormat.R32G32B32A32Sint,                 new FormatInfo(Format.R32G32B32A32Sint,  1,  1,  16, 4) },
407              { TextureFormat.Z16Unorm,                         new FormatInfo(Format.D16Unorm,          1,  1,  2,  1) },
408              { TextureFormat.Z16RUnormGUintBUintAUint,         new FormatInfo(Format.D16Unorm,          1,  1,  2,  1) },
409              { TextureFormat.Zf32RFloatGUintBUintAUint,        new FormatInfo(Format.D32Float,          1,  1,  4,  1) },
410              { TextureFormat.Zf32Float,                        new FormatInfo(Format.D32Float,          1,  1,  4,  1) },
411              { TextureFormat.G24R8RUintGUnormBUnormAUnorm,     new FormatInfo(Format.D24UnormS8Uint,    1,  1,  4,  2) },
412              { TextureFormat.Z24S8RUintGUnormBUnormAUnorm,     new FormatInfo(Format.D24UnormS8Uint,    1,  1,  4,  2) },
413              { TextureFormat.Z24S8RUintGUnormBUintAUint,       new FormatInfo(Format.D24UnormS8Uint,    1,  1,  4,  2) },
414              { TextureFormat.X8Z24RUnormGUintBUintAUint,       new FormatInfo(Format.X8UintD24Unorm,    1,  1,  4,  2) },
415              { TextureFormat.S8Z24RUnormGUintBUintAUint,       new FormatInfo(Format.S8UintD24Unorm,    1,  1,  4,  2) },
416              { TextureFormat.R32B24G8RFloatGUintBUnormAUnorm,  new FormatInfo(Format.D32FloatS8Uint,    1,  1,  8,  2) },
417              { TextureFormat.Zf32X24S8RFloatGUintBUnormAUnorm, new FormatInfo(Format.D32FloatS8Uint,    1,  1,  8,  2) },
418              { TextureFormat.A8B8G8R8UnormSrgb,                new FormatInfo(Format.R8G8B8A8Srgb,      1,  1,  4,  4) },
419              { TextureFormat.G4R4Unorm,                        new FormatInfo(Format.R4G4Unorm,         1,  1,  1,  2) },
420              { TextureFormat.A4B4G4R4Unorm,                    new FormatInfo(Format.R4G4B4A4Unorm,     1,  1,  2,  4) },
421              { TextureFormat.A1B5G5R5Unorm,                    new FormatInfo(Format.R5G5B5A1Unorm,     1,  1,  2,  4) },
422              { TextureFormat.B5G6R5Unorm,                      new FormatInfo(Format.R5G6B5Unorm,       1,  1,  2,  3) },
423              { TextureFormat.A2B10G10R10Unorm,                 new FormatInfo(Format.R10G10B10A2Unorm,  1,  1,  4,  4) },
424              { TextureFormat.A2B10G10R10Uint,                  new FormatInfo(Format.R10G10B10A2Uint,   1,  1,  4,  4) },
425              { TextureFormat.Bf10Gf11Rf11Float,                new FormatInfo(Format.R11G11B10Float,    1,  1,  4,  3) },
426              { TextureFormat.E5B9G9R9SharedExpFloat,           new FormatInfo(Format.R9G9B9E5Float,     1,  1,  4,  4) },
427              { TextureFormat.Bc1Unorm,                         new FormatInfo(Format.Bc1RgbaUnorm,      4,  4,  8,  4) },
428              { TextureFormat.Bc2Unorm,                         new FormatInfo(Format.Bc2Unorm,          4,  4,  16, 4) },
429              { TextureFormat.Bc3Unorm,                         new FormatInfo(Format.Bc3Unorm,          4,  4,  16, 4) },
430              { TextureFormat.Bc1UnormSrgb,                     new FormatInfo(Format.Bc1RgbaSrgb,       4,  4,  8,  4) },
431              { TextureFormat.Bc2UnormSrgb,                     new FormatInfo(Format.Bc2Srgb,           4,  4,  16, 4) },
432              { TextureFormat.Bc3UnormSrgb,                     new FormatInfo(Format.Bc3Srgb,           4,  4,  16, 4) },
433              { TextureFormat.Bc4Unorm,                         new FormatInfo(Format.Bc4Unorm,          4,  4,  8,  1) },
434              { TextureFormat.Bc4Snorm,                         new FormatInfo(Format.Bc4Snorm,          4,  4,  8,  1) },
435              { TextureFormat.Bc5Unorm,                         new FormatInfo(Format.Bc5Unorm,          4,  4,  16, 2) },
436              { TextureFormat.Bc5Snorm,                         new FormatInfo(Format.Bc5Snorm,          4,  4,  16, 2) },
437              { TextureFormat.Bc7UUnorm,                        new FormatInfo(Format.Bc7Unorm,          4,  4,  16, 4) },
438              { TextureFormat.Bc7UUnormSrgb,                    new FormatInfo(Format.Bc7Srgb,           4,  4,  16, 4) },
439              { TextureFormat.Bc6HSf16Float,                    new FormatInfo(Format.Bc6HSfloat,        4,  4,  16, 4) },
440              { TextureFormat.Bc6HUf16Float,                    new FormatInfo(Format.Bc6HUfloat,        4,  4,  16, 4) },
441              { TextureFormat.Etc2RgbUnorm,                     new FormatInfo(Format.Etc2RgbUnorm,      4,  4,  8,  3) },
442              { TextureFormat.Etc2RgbPtaUnorm,                  new FormatInfo(Format.Etc2RgbPtaUnorm,   4,  4,  8,  4) },
443              { TextureFormat.Etc2RgbaUnorm,                    new FormatInfo(Format.Etc2RgbaUnorm,     4,  4,  16, 4) },
444              { TextureFormat.Etc2RgbUnormSrgb,                 new FormatInfo(Format.Etc2RgbSrgb,       4,  4,  8,  3) },
445              { TextureFormat.Etc2RgbPtaUnormSrgb,              new FormatInfo(Format.Etc2RgbPtaSrgb,    4,  4,  8,  4) },
446              { TextureFormat.Etc2RgbaUnormSrgb,                new FormatInfo(Format.Etc2RgbaSrgb,      4,  4,  16, 4) },
447              { TextureFormat.Astc2D4x4Unorm,                   new FormatInfo(Format.Astc4x4Unorm,      4,  4,  16, 4) },
448              { TextureFormat.Astc2D5x4Unorm,                   new FormatInfo(Format.Astc5x4Unorm,      5,  4,  16, 4) },
449              { TextureFormat.Astc2D5x5Unorm,                   new FormatInfo(Format.Astc5x5Unorm,      5,  5,  16, 4) },
450              { TextureFormat.Astc2D6x5Unorm,                   new FormatInfo(Format.Astc6x5Unorm,      6,  5,  16, 4) },
451              { TextureFormat.Astc2D6x6Unorm,                   new FormatInfo(Format.Astc6x6Unorm,      6,  6,  16, 4) },
452              { TextureFormat.Astc2D8x5Unorm,                   new FormatInfo(Format.Astc8x5Unorm,      8,  5,  16, 4) },
453              { TextureFormat.Astc2D8x6Unorm,                   new FormatInfo(Format.Astc8x6Unorm,      8,  6,  16, 4) },
454              { TextureFormat.Astc2D8x8Unorm,                   new FormatInfo(Format.Astc8x8Unorm,      8,  8,  16, 4) },
455              { TextureFormat.Astc2D10x5Unorm,                  new FormatInfo(Format.Astc10x5Unorm,     10, 5,  16, 4) },
456              { TextureFormat.Astc2D10x6Unorm,                  new FormatInfo(Format.Astc10x6Unorm,     10, 6,  16, 4) },
457              { TextureFormat.Astc2D10x8Unorm,                  new FormatInfo(Format.Astc10x8Unorm,     10, 8,  16, 4) },
458              { TextureFormat.Astc2D10x10Unorm,                 new FormatInfo(Format.Astc10x10Unorm,    10, 10, 16, 4) },
459              { TextureFormat.Astc2D12x10Unorm,                 new FormatInfo(Format.Astc12x10Unorm,    12, 10, 16, 4) },
460              { TextureFormat.Astc2D12x12Unorm,                 new FormatInfo(Format.Astc12x12Unorm,    12, 12, 16, 4) },
461              { TextureFormat.Astc2D4x4UnormSrgb,               new FormatInfo(Format.Astc4x4Srgb,       4,  4,  16, 4) },
462              { TextureFormat.Astc2D5x4UnormSrgb,               new FormatInfo(Format.Astc5x4Srgb,       5,  4,  16, 4) },
463              { TextureFormat.Astc2D5x5UnormSrgb,               new FormatInfo(Format.Astc5x5Srgb,       5,  5,  16, 4) },
464              { TextureFormat.Astc2D6x5UnormSrgb,               new FormatInfo(Format.Astc6x5Srgb,       6,  5,  16, 4) },
465              { TextureFormat.Astc2D6x6UnormSrgb,               new FormatInfo(Format.Astc6x6Srgb,       6,  6,  16, 4) },
466              { TextureFormat.Astc2D8x5UnormSrgb,               new FormatInfo(Format.Astc8x5Srgb,       8,  5,  16, 4) },
467              { TextureFormat.Astc2D8x6UnormSrgb,               new FormatInfo(Format.Astc8x6Srgb,       8,  6,  16, 4) },
468              { TextureFormat.Astc2D8x8UnormSrgb,               new FormatInfo(Format.Astc8x8Srgb,       8,  8,  16, 4) },
469              { TextureFormat.Astc2D10x5UnormSrgb,              new FormatInfo(Format.Astc10x5Srgb,      10, 5,  16, 4) },
470              { TextureFormat.Astc2D10x6UnormSrgb,              new FormatInfo(Format.Astc10x6Srgb,      10, 6,  16, 4) },
471              { TextureFormat.Astc2D10x8UnormSrgb,              new FormatInfo(Format.Astc10x8Srgb,      10, 8,  16, 4) },
472              { TextureFormat.Astc2D10x10UnormSrgb,             new FormatInfo(Format.Astc10x10Srgb,     10, 10, 16, 4) },
473              { TextureFormat.Astc2D12x10UnormSrgb,             new FormatInfo(Format.Astc12x10Srgb,     12, 10, 16, 4) },
474              { TextureFormat.Astc2D12x12UnormSrgb,             new FormatInfo(Format.Astc12x12Srgb,     12, 12, 16, 4) },
475              { TextureFormat.A5B5G5R1Unorm,                    new FormatInfo(Format.A1B5G5R5Unorm,     1,  1,  2,  4) },
476          };
477  
478          private static readonly Dictionary<VertexAttributeFormat, Format> _attribFormats = new()
479          {
480              { VertexAttributeFormat.R8Unorm,             Format.R8Unorm             },
481              { VertexAttributeFormat.R8Snorm,             Format.R8Snorm             },
482              { VertexAttributeFormat.R8Uint,              Format.R8Uint              },
483              { VertexAttributeFormat.R8Sint,              Format.R8Sint              },
484              { VertexAttributeFormat.R16Float,            Format.R16Float            },
485              { VertexAttributeFormat.R16Unorm,            Format.R16Unorm            },
486              { VertexAttributeFormat.R16Snorm,            Format.R16Snorm            },
487              { VertexAttributeFormat.R16Uint,             Format.R16Uint             },
488              { VertexAttributeFormat.R16Sint,             Format.R16Sint             },
489              { VertexAttributeFormat.R32Float,            Format.R32Float            },
490              { VertexAttributeFormat.R32Uint,             Format.R32Uint             },
491              { VertexAttributeFormat.R32Sint,             Format.R32Sint             },
492              { VertexAttributeFormat.R8G8Unorm,           Format.R8G8Unorm           },
493              { VertexAttributeFormat.R8G8Snorm,           Format.R8G8Snorm           },
494              { VertexAttributeFormat.R8G8Uint,            Format.R8G8Uint            },
495              { VertexAttributeFormat.R8G8Sint,            Format.R8G8Sint            },
496              { VertexAttributeFormat.R16G16Float,         Format.R16G16Float         },
497              { VertexAttributeFormat.R16G16Unorm,         Format.R16G16Unorm         },
498              { VertexAttributeFormat.R16G16Snorm,         Format.R16G16Snorm         },
499              { VertexAttributeFormat.R16G16Uint,          Format.R16G16Uint          },
500              { VertexAttributeFormat.R16G16Sint,          Format.R16G16Sint          },
501              { VertexAttributeFormat.R32G32Float,         Format.R32G32Float         },
502              { VertexAttributeFormat.R32G32Uint,          Format.R32G32Uint          },
503              { VertexAttributeFormat.R32G32Sint,          Format.R32G32Sint          },
504              { VertexAttributeFormat.R8G8B8Unorm,         Format.R8G8B8Unorm         },
505              { VertexAttributeFormat.R8G8B8Snorm,         Format.R8G8B8Snorm         },
506              { VertexAttributeFormat.R8G8B8Uint,          Format.R8G8B8Uint          },
507              { VertexAttributeFormat.R8G8B8Sint,          Format.R8G8B8Sint          },
508              { VertexAttributeFormat.R16G16B16Float,      Format.R16G16B16Float      },
509              { VertexAttributeFormat.R16G16B16Unorm,      Format.R16G16B16Unorm      },
510              { VertexAttributeFormat.R16G16B16Snorm,      Format.R16G16B16Snorm      },
511              { VertexAttributeFormat.R16G16B16Uint,       Format.R16G16B16Uint       },
512              { VertexAttributeFormat.R16G16B16Sint,       Format.R16G16B16Sint       },
513              { VertexAttributeFormat.R32G32B32Float,      Format.R32G32B32Float      },
514              { VertexAttributeFormat.R32G32B32Uint,       Format.R32G32B32Uint       },
515              { VertexAttributeFormat.R32G32B32Sint,       Format.R32G32B32Sint       },
516              { VertexAttributeFormat.R8G8B8A8Unorm,       Format.R8G8B8A8Unorm       },
517              { VertexAttributeFormat.R8G8B8A8Snorm,       Format.R8G8B8A8Snorm       },
518              { VertexAttributeFormat.R8G8B8A8Uint,        Format.R8G8B8A8Uint        },
519              { VertexAttributeFormat.R8G8B8A8Sint,        Format.R8G8B8A8Sint        },
520              { VertexAttributeFormat.R16G16B16A16Float,   Format.R16G16B16A16Float   },
521              { VertexAttributeFormat.R16G16B16A16Unorm,   Format.R16G16B16A16Unorm   },
522              { VertexAttributeFormat.R16G16B16A16Snorm,   Format.R16G16B16A16Snorm   },
523              { VertexAttributeFormat.R16G16B16A16Uint,    Format.R16G16B16A16Uint    },
524              { VertexAttributeFormat.R16G16B16A16Sint,    Format.R16G16B16A16Sint    },
525              { VertexAttributeFormat.R32G32B32A32Float,   Format.R32G32B32A32Float   },
526              { VertexAttributeFormat.R32G32B32A32Uint,    Format.R32G32B32A32Uint    },
527              { VertexAttributeFormat.R32G32B32A32Sint,    Format.R32G32B32A32Sint    },
528              { VertexAttributeFormat.A2B10G10R10Unorm,    Format.R10G10B10A2Unorm    },
529              { VertexAttributeFormat.A2B10G10R10Uint,     Format.R10G10B10A2Uint     },
530              { VertexAttributeFormat.B10G11R11Float,      Format.R11G11B10Float      },
531              { VertexAttributeFormat.R8Uscaled,           Format.R8Uscaled           },
532              { VertexAttributeFormat.R8Sscaled,           Format.R8Sscaled           },
533              { VertexAttributeFormat.R16Uscaled,          Format.R16Uscaled          },
534              { VertexAttributeFormat.R16Sscaled,          Format.R16Sscaled          },
535              { VertexAttributeFormat.R32Uscaled,          Format.R32Uscaled          },
536              { VertexAttributeFormat.R32Sscaled,          Format.R32Sscaled          },
537              { VertexAttributeFormat.R8G8Uscaled,         Format.R8G8Uscaled         },
538              { VertexAttributeFormat.R8G8Sscaled,         Format.R8G8Sscaled         },
539              { VertexAttributeFormat.R16G16Uscaled,       Format.R16G16Uscaled       },
540              { VertexAttributeFormat.R16G16Sscaled,       Format.R16G16Sscaled       },
541              { VertexAttributeFormat.R32G32Uscaled,       Format.R32G32Uscaled       },
542              { VertexAttributeFormat.R32G32Sscaled,       Format.R32G32Sscaled       },
543              { VertexAttributeFormat.R8G8B8Uscaled,       Format.R8G8B8Uscaled       },
544              { VertexAttributeFormat.R8G8B8Sscaled,       Format.R8G8B8Sscaled       },
545              { VertexAttributeFormat.R16G16B16Uscaled,    Format.R16G16B16Uscaled    },
546              { VertexAttributeFormat.R16G16B16Sscaled,    Format.R16G16B16Sscaled    },
547              { VertexAttributeFormat.R32G32B32Uscaled,    Format.R32G32B32Uscaled    },
548              { VertexAttributeFormat.R32G32B32Sscaled,    Format.R32G32B32Sscaled    },
549              { VertexAttributeFormat.R8G8B8A8Uscaled,     Format.R8G8B8A8Uscaled     },
550              { VertexAttributeFormat.R8G8B8A8Sscaled,     Format.R8G8B8A8Sscaled     },
551              { VertexAttributeFormat.R16G16B16A16Uscaled, Format.R16G16B16A16Uscaled },
552              { VertexAttributeFormat.R16G16B16A16Sscaled, Format.R16G16B16A16Sscaled },
553              { VertexAttributeFormat.R32G32B32A32Uscaled, Format.R32G32B32A32Uscaled },
554              { VertexAttributeFormat.R32G32B32A32Sscaled, Format.R32G32B32A32Sscaled },
555              { VertexAttributeFormat.A2B10G10R10Snorm,    Format.R10G10B10A2Snorm    },
556              { VertexAttributeFormat.A2B10G10R10Sint,     Format.R10G10B10A2Sint     },
557              { VertexAttributeFormat.A2B10G10R10Uscaled,  Format.R10G10B10A2Uscaled  },
558              { VertexAttributeFormat.A2B10G10R10Sscaled,  Format.R10G10B10A2Sscaled  },
559          };
560  #pragma warning restore IDE0055
561  
562          // Note: Some of those formats have been changed and requires conversion on the shader,
563          // as GPUs don't support them when used as buffer texture format.
564          private static readonly Dictionary<VertexAttributeFormat, (Format, int)> _singleComponentAttribFormats = new()
565          {
566              { VertexAttributeFormat.R8Unorm,             (Format.R8Unorm, 1)          },
567              { VertexAttributeFormat.R8Snorm,             (Format.R8Snorm, 1)          },
568              { VertexAttributeFormat.R8Uint,              (Format.R8Uint, 1)           },
569              { VertexAttributeFormat.R8Sint,              (Format.R8Sint, 1)           },
570              { VertexAttributeFormat.R16Float,            (Format.R16Float, 1)         },
571              { VertexAttributeFormat.R16Unorm,            (Format.R16Unorm, 1)         },
572              { VertexAttributeFormat.R16Snorm,            (Format.R16Snorm, 1)         },
573              { VertexAttributeFormat.R16Uint,             (Format.R16Uint, 1)          },
574              { VertexAttributeFormat.R16Sint,             (Format.R16Sint, 1)          },
575              { VertexAttributeFormat.R32Float,            (Format.R32Float, 1)         },
576              { VertexAttributeFormat.R32Uint,             (Format.R32Uint, 1)          },
577              { VertexAttributeFormat.R32Sint,             (Format.R32Sint, 1)          },
578              { VertexAttributeFormat.R8G8Unorm,           (Format.R8Unorm, 2)          },
579              { VertexAttributeFormat.R8G8Snorm,           (Format.R8Snorm, 2)          },
580              { VertexAttributeFormat.R8G8Uint,            (Format.R8Uint, 2)           },
581              { VertexAttributeFormat.R8G8Sint,            (Format.R8Sint, 2)           },
582              { VertexAttributeFormat.R16G16Float,         (Format.R16Float, 2)         },
583              { VertexAttributeFormat.R16G16Unorm,         (Format.R16Unorm, 2)         },
584              { VertexAttributeFormat.R16G16Snorm,         (Format.R16Snorm, 2)         },
585              { VertexAttributeFormat.R16G16Uint,          (Format.R16Uint, 2)          },
586              { VertexAttributeFormat.R16G16Sint,          (Format.R16Sint, 2)          },
587              { VertexAttributeFormat.R32G32Float,         (Format.R32Float, 2)         },
588              { VertexAttributeFormat.R32G32Uint,          (Format.R32Uint, 2)          },
589              { VertexAttributeFormat.R32G32Sint,          (Format.R32Sint, 2)          },
590              { VertexAttributeFormat.R8G8B8Unorm,         (Format.R8Unorm, 3)          },
591              { VertexAttributeFormat.R8G8B8Snorm,         (Format.R8Snorm, 3)          },
592              { VertexAttributeFormat.R8G8B8Uint,          (Format.R8Uint, 3)           },
593              { VertexAttributeFormat.R8G8B8Sint,          (Format.R8Sint, 3)           },
594              { VertexAttributeFormat.R16G16B16Float,      (Format.R16Float, 3)         },
595              { VertexAttributeFormat.R16G16B16Unorm,      (Format.R16Unorm, 3)         },
596              { VertexAttributeFormat.R16G16B16Snorm,      (Format.R16Snorm, 3)         },
597              { VertexAttributeFormat.R16G16B16Uint,       (Format.R16Uint, 3)          },
598              { VertexAttributeFormat.R16G16B16Sint,       (Format.R16Sint, 3)          },
599              { VertexAttributeFormat.R32G32B32Float,      (Format.R32Float, 3)         },
600              { VertexAttributeFormat.R32G32B32Uint,       (Format.R32Uint, 3)          },
601              { VertexAttributeFormat.R32G32B32Sint,       (Format.R32Sint, 3)          },
602              { VertexAttributeFormat.R8G8B8A8Unorm,       (Format.R8Unorm, 4)          },
603              { VertexAttributeFormat.R8G8B8A8Snorm,       (Format.R8Snorm, 4)          },
604              { VertexAttributeFormat.R8G8B8A8Uint,        (Format.R8Uint, 4)           },
605              { VertexAttributeFormat.R8G8B8A8Sint,        (Format.R8Sint, 4)           },
606              { VertexAttributeFormat.R16G16B16A16Float,   (Format.R16Float, 4)         },
607              { VertexAttributeFormat.R16G16B16A16Unorm,   (Format.R16Unorm, 4)         },
608              { VertexAttributeFormat.R16G16B16A16Snorm,   (Format.R16Snorm, 4)         },
609              { VertexAttributeFormat.R16G16B16A16Uint,    (Format.R16Uint, 4)          },
610              { VertexAttributeFormat.R16G16B16A16Sint,    (Format.R16Sint, 4)          },
611              { VertexAttributeFormat.R32G32B32A32Float,   (Format.R32Float, 4)         },
612              { VertexAttributeFormat.R32G32B32A32Uint,    (Format.R32Uint, 4)          },
613              { VertexAttributeFormat.R32G32B32A32Sint,    (Format.R32Sint, 4)          },
614              { VertexAttributeFormat.A2B10G10R10Unorm,    (Format.R10G10B10A2Unorm, 4) },
615              { VertexAttributeFormat.A2B10G10R10Uint,     (Format.R10G10B10A2Uint, 4)  },
616              { VertexAttributeFormat.B10G11R11Float,      (Format.R11G11B10Float, 3)   },
617              { VertexAttributeFormat.R8Uscaled,           (Format.R8Uint, 1)           }, // Uscaled -> Uint
618              { VertexAttributeFormat.R8Sscaled,           (Format.R8Sint, 1)           }, // Sscaled -> Sint
619              { VertexAttributeFormat.R16Uscaled,          (Format.R16Uint, 1)          }, // Uscaled -> Uint
620              { VertexAttributeFormat.R16Sscaled,          (Format.R16Sint, 1)          }, // Sscaled -> Sint
621              { VertexAttributeFormat.R32Uscaled,          (Format.R32Uint, 1)          }, // Uscaled -> Uint
622              { VertexAttributeFormat.R32Sscaled,          (Format.R32Sint, 1)          }, // Sscaled -> Sint
623              { VertexAttributeFormat.R8G8Uscaled,         (Format.R8Uint, 2)           }, // Uscaled -> Uint
624              { VertexAttributeFormat.R8G8Sscaled,         (Format.R8Sint, 2)           }, // Sscaled -> Sint
625              { VertexAttributeFormat.R16G16Uscaled,       (Format.R16Uint, 2)          }, // Uscaled -> Uint
626              { VertexAttributeFormat.R16G16Sscaled,       (Format.R16Sint, 2)          }, // Sscaled -> Sint
627              { VertexAttributeFormat.R32G32Uscaled,       (Format.R32Uint, 2)          }, // Uscaled -> Uint
628              { VertexAttributeFormat.R32G32Sscaled,       (Format.R32Sint, 2)          }, // Sscaled -> Sint
629              { VertexAttributeFormat.R8G8B8Uscaled,       (Format.R8Uint, 3)           }, // Uscaled -> Uint
630              { VertexAttributeFormat.R8G8B8Sscaled,       (Format.R8Sint, 3)           }, // Sscaled -> Sint
631              { VertexAttributeFormat.R16G16B16Uscaled,    (Format.R16Uint, 3)          }, // Uscaled -> Uint
632              { VertexAttributeFormat.R16G16B16Sscaled,    (Format.R16Sint, 3)          }, // Sscaled -> Sint
633              { VertexAttributeFormat.R32G32B32Uscaled,    (Format.R32Uint, 3)          }, // Uscaled -> Uint
634              { VertexAttributeFormat.R32G32B32Sscaled,    (Format.R32Sint , 3)         }, // Sscaled -> Sint
635              { VertexAttributeFormat.R8G8B8A8Uscaled,     (Format.R8Uint, 4)           }, // Uscaled -> Uint
636              { VertexAttributeFormat.R8G8B8A8Sscaled,     (Format.R8Sint, 4)           }, // Sscaled -> Sint
637              { VertexAttributeFormat.R16G16B16A16Uscaled, (Format.R16Uint, 4)          }, // Uscaled -> Uint
638              { VertexAttributeFormat.R16G16B16A16Sscaled, (Format.R16Sint, 4)          }, // Sscaled -> Sint
639              { VertexAttributeFormat.R32G32B32A32Uscaled, (Format.R32Uint, 4)          }, // Uscaled -> Uint
640              { VertexAttributeFormat.R32G32B32A32Sscaled, (Format.R32Sint, 4)          }, // Sscaled -> Sint
641              { VertexAttributeFormat.A2B10G10R10Snorm,    (Format.R10G10B10A2Uint, 4)  }, // Snorm -> Uint
642              { VertexAttributeFormat.A2B10G10R10Sint,     (Format.R10G10B10A2Uint, 4)  }, // Sint -> Uint
643              { VertexAttributeFormat.A2B10G10R10Uscaled,  (Format.R10G10B10A2Uint, 4)  }, // Uscaled -> Uint
644              { VertexAttributeFormat.A2B10G10R10Sscaled,  (Format.R10G10B10A2Sint, 4)  }  // Sscaled -> Sint
645          };
646  
647          /// <summary>
648          /// Try getting the texture format from an encoded format integer from the Maxwell texture descriptor.
649          /// </summary>
650          /// <param name="encoded">The encoded format integer from the texture descriptor</param>
651          /// <param name="isSrgb">Indicates if the format is a sRGB format</param>
652          /// <param name="format">The output texture format</param>
653          /// <returns>True if the format is valid, false otherwise</returns>
654          public static bool TryGetTextureFormat(uint encoded, bool isSrgb, out FormatInfo format)
655          {
656              bool isPacked = (encoded & 0x80000000u) != 0;
657              if (isPacked)
658              {
659                  encoded &= ~0x80000000u;
660              }
661  
662              encoded |= isSrgb ? 1u << 19 : 0u;
663  
664              bool found = _textureFormats.TryGetValue((TextureFormat)encoded, out format);
665  
666              if (found && isPacked && !format.Format.IsDepthOrStencil())
667              {
668                  // If the packed flag is set, then the components of the pixel are tightly packed into the
669                  // GPU registers on the shader.
670                  // We can get the same behaviour by aliasing the texture as a format with the same amount of
671                  // bytes per pixel, but only a single or the lowest possible number of components.
672  
673                  format = format.BytesPerPixel switch
674                  {
675                      1 => new FormatInfo(Format.R8Unorm, 1, 1, 1, 1),
676                      2 => new FormatInfo(Format.R16Unorm, 1, 1, 2, 1),
677                      4 => new FormatInfo(Format.R32Uint, 1, 1, 4, 1),
678                      8 => new FormatInfo(Format.R32G32Uint, 1, 1, 8, 2),
679                      16 => new FormatInfo(Format.R32G32B32A32Uint, 1, 1, 16, 4),
680                      _ => format,
681                  };
682              }
683  
684              return found;
685          }
686  
687          /// <summary>
688          /// Try getting the vertex attribute format from an encoded format integer from Maxwell attribute registers.
689          /// </summary>
690          /// <param name="encoded">The encoded format integer from the attribute registers</param>
691          /// <param name="format">The output vertex attribute format</param>
692          /// <returns>True if the format is valid, false otherwise</returns>
693          public static bool TryGetAttribFormat(uint encoded, out Format format)
694          {
695              return _attribFormats.TryGetValue((VertexAttributeFormat)encoded, out format);
696          }
697  
698          /// <summary>
699          /// Try getting a single component vertex attribute format from an encoded format integer from Maxwell attribute registers.
700          /// </summary>
701          /// <param name="encoded">The encoded format integer from the attribute registers</param>
702          /// <param name="format">The output single component vertex attribute format</param>
703          /// <param name="componentsCount">Number of components that the format has</param>
704          /// <returns>True if the format is valid, false otherwise</returns>
705          public static bool TryGetSingleComponentAttribFormat(uint encoded, out Format format, out int componentsCount)
706          {
707              bool result = _singleComponentAttribFormats.TryGetValue((VertexAttributeFormat)encoded, out var tuple);
708  
709              format = tuple.Item1;
710              componentsCount = tuple.Item2;
711  
712              return result;
713          }
714      }
715  }