Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
PixelFormat.Extensions.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 //
4 // Copyright (c) 2010-2012 SharpDX - Alexandre Mutel
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 
24 using System;
25 using System.Collections.Generic;
26 
27 namespace SiliconStudio.Paradox.Graphics
28 {
29  /// <summary>
30  /// Extensions to <see cref="PixelFormat"/>.
31  /// </summary>
32  public static class PixelFormatExtensions
33  {
34  private static readonly int[] sizeOfInBits = new int[256];
35  private static readonly bool[] compressedFormats = new bool[256];
36  private static readonly bool[] srgbFormats = new bool[256];
37  private static readonly bool[] typelessFormats = new bool[256];
38 
39  private static int GetIndex(PixelFormat format)
40  {
41  // DirectX official pixel formats (0..115 use 0..127 in the arrays)
42  // Custom pixel formats (1024..1151? use 128..255 in the array)
43  if ((int)format >= 1024)
44  return (int)format - 1024 + 128;
45 
46  return (int)format;
47  }
48 
49  /// <summary>
50  /// Calculates the size of a <see cref="PixelFormat"/> in bytes.
51  /// </summary>
52  /// <param name="format">The dxgi format.</param>
53  /// <returns>size of in bytes</returns>
54  public static int SizeInBytes(this PixelFormat format)
55  {
56  return SizeInBits(format)/8;
57  }
58 
59  /// <summary>
60  /// Calculates the size of a <see cref="PixelFormat"/> in bits.
61  /// </summary>
62  /// <param name="format">The dxgi format.</param>
63  /// <returns>size of in bits</returns>
64  public static int SizeInBits(this PixelFormat format)
65  {
66  return sizeOfInBits[GetIndex(format)];
67  }
68 
69  /// <summary>
70  /// Returns true if the <see cref="PixelFormat"/> is valid.
71  /// </summary>
72  /// <param name="format">A format to validate</param>
73  /// <returns>True if the <see cref="PixelFormat"/> is valid.</returns>
74  public static bool IsValid(this PixelFormat format )
75  {
76  return ( (int)(format) >= 1 && (int)(format) <= 115 ) // DirectX formats
77  || ((int) (format) >= 1024 && (int) (format) <= 1029) // PVRTC formats
78  || ((int) (format) >= 1088 && (int) (format) <= 1095) // ETC formats
79  || ((int) (format) >= 1120 && (int) (format) <= 1122); // ATITC formats
80  }
81 
82  /// <summary>
83  /// Returns true if the <see cref="PixelFormat"/> is a compressed format.
84  /// </summary>
85  /// <param name="fmt">The format to check for compressed.</param>
86  /// <returns>True if the <see cref="PixelFormat"/> is a compressed format</returns>
87  public static bool IsCompressed(this PixelFormat fmt)
88  {
89  return compressedFormats[GetIndex(fmt)];
90  }
91 
92  /// <summary>
93  /// Determines whether the specified <see cref="PixelFormat"/> is packed.
94  /// </summary>
95  /// <param name="fmt">The DXGI Format.</param>
96  /// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is packed; otherwise, <c>false</c>.</returns>
97  public static bool IsPacked(this PixelFormat fmt )
98  {
99  return ((fmt == PixelFormat.R8G8_B8G8_UNorm) || (fmt == PixelFormat.G8R8_G8B8_UNorm));
100  }
101 
102  /// <summary>
103  /// Determines whether the specified <see cref="PixelFormat"/> is video.
104  /// </summary>
105  /// <param name="fmt">The <see cref="PixelFormat"/>.</param>
106  /// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is video; otherwise, <c>false</c>.</returns>
107  public static bool IsVideo(this PixelFormat fmt )
108  {
109 #if DIRECTX11_1
110  switch ( fmt )
111  {
112  case Format.AYUV:
113  case Format.Y410:
114  case Format.Y416:
115  case Format.NV12:
116  case Format.P010:
117  case Format.P016:
118  case Format.YUY2:
119  case Format.Y210:
120  case Format.Y216:
121  case Format.NV11:
122  // These video formats can be used with the 3D pipeline through special view mappings
123  return true;
124 
125  case Format.Opaque420:
126  case Format.AI44:
127  case Format.IA44:
128  case Format.P8:
129  case Format.A8P8:
130  // These are limited use video formats not usable in any way by the 3D pipeline
131  return true;
132 
133  default:
134  return false;
135  }
136 #else
137  // !DXGI_1_2_FORMATS
138  return false;
139 #endif
140  }
141 
142  /// <summary>
143  /// Determines whether the specified <see cref="PixelFormat"/> is a SRGB format.
144  /// </summary>
145  /// <param name="fmt">The <see cref="PixelFormat"/>.</param>
146  /// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is a SRGB format; otherwise, <c>false</c>.</returns>
147  public static bool IsSRgb(this PixelFormat fmt )
148  {
149  return srgbFormats[GetIndex(fmt)];
150  }
151 
152  /// <summary>
153  /// Determines whether the specified <see cref="PixelFormat"/> is typeless.
154  /// </summary>
155  /// <param name="fmt">The <see cref="PixelFormat"/>.</param>
156  /// <returns><c>true</c> if the specified <see cref="PixelFormat"/> is typeless; otherwise, <c>false</c>.</returns>
157  public static bool IsTypeless(this PixelFormat fmt )
158  {
159  return typelessFormats[GetIndex(fmt)];
160  }
161 
162  /// <summary>
163  /// Computes the scanline count (number of scanlines).
164  /// </summary>
165  /// <param name="fmt">The <see cref="PixelFormat"/>.</param>
166  /// <param name="height">The height.</param>
167  /// <returns>The scanline count.</returns>
168  public static int ComputeScanlineCount(this PixelFormat fmt, int height)
169  {
170  switch (fmt)
171  {
172  case PixelFormat.BC1_Typeless:
173  case PixelFormat.BC1_UNorm:
174  case PixelFormat.BC1_UNorm_SRgb:
175  case PixelFormat.BC2_Typeless:
176  case PixelFormat.BC2_UNorm:
177  case PixelFormat.BC2_UNorm_SRgb:
178  case PixelFormat.BC3_Typeless:
179  case PixelFormat.BC3_UNorm:
180  case PixelFormat.BC3_UNorm_SRgb:
181  case PixelFormat.BC4_Typeless:
182  case PixelFormat.BC4_UNorm:
183  case PixelFormat.BC4_SNorm:
184  case PixelFormat.BC5_Typeless:
185  case PixelFormat.BC5_UNorm:
186  case PixelFormat.BC5_SNorm:
187  case PixelFormat.BC6H_Typeless:
188  case PixelFormat.BC6H_Uf16:
189  case PixelFormat.BC6H_Sf16:
190  case PixelFormat.BC7_Typeless:
191  case PixelFormat.BC7_UNorm:
192  case PixelFormat.BC7_UNorm_SRgb:
193  case PixelFormat.PVRTC_2bpp_RGB:
194  case PixelFormat.PVRTC_2bpp_RGBA:
195  case PixelFormat.PVRTC_4bpp_RGB:
196  case PixelFormat.PVRTC_4bpp_RGBA:
197  case PixelFormat.PVRTC_II_2bpp:
198  case PixelFormat.PVRTC_II_4bpp:
199  case PixelFormat.ETC1:
200  case PixelFormat.ETC2_RGB:
201  case PixelFormat.ETC2_RGBA:
202  case PixelFormat.ETC2_RGB_A1:
203  case PixelFormat.EAC_R11_Unsigned:
204  case PixelFormat.EAC_R11_Signed:
205  case PixelFormat.EAC_RG11_Unsigned:
206  case PixelFormat.EAC_RG11_Signed:
207  case PixelFormat.ATC_RGB:
208  case PixelFormat.ATC_RGBA_Explicit:
209  case PixelFormat.ATC_RGBA_Interpolated:
210  return Math.Max(1, (height + 3) / 4);
211 
212  default:
213  return height;
214  }
215  }
216 
217  /// <summary>
218  /// Static initializer to speed up size calculation (not sure the JIT is enough "smart" for this kind of thing).
219  /// </summary>
220  static PixelFormatExtensions()
221  {
222  InitFormat(new[] { PixelFormat.R1_UNorm }, 1);
223 
224  InitFormat(new[] { PixelFormat.A8_UNorm, PixelFormat.R8_SInt, PixelFormat.R8_SNorm, PixelFormat.R8_Typeless, PixelFormat.R8_UInt, PixelFormat.R8_UNorm }, 8);
225 
226  InitFormat(new[] {
227  PixelFormat.B5G5R5A1_UNorm,
228  PixelFormat.B5G6R5_UNorm,
229  PixelFormat.D16_UNorm,
230  PixelFormat.R16_Float,
231  PixelFormat.R16_SInt,
232  PixelFormat.R16_SNorm,
233  PixelFormat.R16_Typeless,
234  PixelFormat.R16_UInt,
235  PixelFormat.R16_UNorm,
236  PixelFormat.R8G8_SInt,
237  PixelFormat.R8G8_SNorm,
238  PixelFormat.R8G8_Typeless,
239  PixelFormat.R8G8_UInt,
240  PixelFormat.R8G8_UNorm,
241 #if DIRECTX11_1
242  PixelFormat.B4G4R4A4_UNorm,
243 #endif
244  }, 16);
245 
246  InitFormat(new[] {
247  PixelFormat.B8G8R8X8_Typeless,
248  PixelFormat.B8G8R8X8_UNorm,
249  PixelFormat.B8G8R8X8_UNorm_SRgb,
250  PixelFormat.D24_UNorm_S8_UInt,
251  PixelFormat.D32_Float,
252  PixelFormat.D32_Float_S8X24_UInt,
253  PixelFormat.G8R8_G8B8_UNorm,
254  PixelFormat.R10G10B10_Xr_Bias_A2_UNorm,
255  PixelFormat.R10G10B10A2_Typeless,
256  PixelFormat.R10G10B10A2_UInt,
257  PixelFormat.R10G10B10A2_UNorm,
258  PixelFormat.R11G11B10_Float,
259  PixelFormat.R16G16_Float,
260  PixelFormat.R16G16_SInt,
261  PixelFormat.R16G16_SNorm,
262  PixelFormat.R16G16_Typeless,
263  PixelFormat.R16G16_UInt,
264  PixelFormat.R16G16_UNorm,
265  PixelFormat.R24_UNorm_X8_Typeless,
266  PixelFormat.R24G8_Typeless,
267  PixelFormat.R32_Float,
268  PixelFormat.R32_Float_X8X24_Typeless,
269  PixelFormat.R32_SInt,
270  PixelFormat.R32_Typeless,
271  PixelFormat.R32_UInt,
272  PixelFormat.R8G8_B8G8_UNorm,
273  PixelFormat.R8G8B8A8_SInt,
274  PixelFormat.R8G8B8A8_SNorm,
275  PixelFormat.R8G8B8A8_Typeless,
276  PixelFormat.R8G8B8A8_UInt,
277  PixelFormat.R8G8B8A8_UNorm,
278  PixelFormat.R8G8B8A8_UNorm_SRgb,
279  PixelFormat.B8G8R8A8_Typeless,
280  PixelFormat.B8G8R8A8_UNorm,
281  PixelFormat.B8G8R8A8_UNorm_SRgb,
282  PixelFormat.R9G9B9E5_Sharedexp,
283  PixelFormat.X24_Typeless_G8_UInt,
284  PixelFormat.X32_Typeless_G8X24_UInt,
285  }, 32);
286 
287  InitFormat(new[] {
288  PixelFormat.R16G16B16A16_Float,
289  PixelFormat.R16G16B16A16_SInt,
290  PixelFormat.R16G16B16A16_SNorm,
291  PixelFormat.R16G16B16A16_Typeless,
292  PixelFormat.R16G16B16A16_UInt,
293  PixelFormat.R16G16B16A16_UNorm,
294  PixelFormat.R32G32_Float,
295  PixelFormat.R32G32_SInt,
296  PixelFormat.R32G32_Typeless,
297  PixelFormat.R32G32_UInt,
298  PixelFormat.R32G8X24_Typeless,
299  }, 64);
300 
301  InitFormat(new[] {
302  PixelFormat.R32G32B32_Float,
303  PixelFormat.R32G32B32_SInt,
304  PixelFormat.R32G32B32_Typeless,
305  PixelFormat.R32G32B32_UInt,
306  }, 96);
307 
308  InitFormat(new[] {
309  PixelFormat.R32G32B32A32_Float,
310  PixelFormat.R32G32B32A32_SInt,
311  PixelFormat.R32G32B32A32_Typeless,
312  PixelFormat.R32G32B32A32_UInt,
313  }, 128);
314 
315  InitFormat(new[] {
316  PixelFormat.BC1_Typeless,
317  PixelFormat.BC1_UNorm,
318  PixelFormat.BC1_UNorm_SRgb,
319  PixelFormat.BC4_SNorm,
320  PixelFormat.BC4_Typeless,
321  PixelFormat.BC4_UNorm,
322  }, 4);
323 
324 
325  InitFormat(new[] {
326  PixelFormat.BC2_Typeless,
327  PixelFormat.BC2_UNorm,
328  PixelFormat.BC2_UNorm_SRgb,
329  PixelFormat.BC3_Typeless,
330  PixelFormat.BC3_UNorm,
331  PixelFormat.BC3_UNorm_SRgb,
332  PixelFormat.BC5_SNorm,
333  PixelFormat.BC5_Typeless,
334  PixelFormat.BC5_UNorm,
335  PixelFormat.BC6H_Sf16,
336  PixelFormat.BC6H_Typeless,
337  PixelFormat.BC6H_Uf16,
338  PixelFormat.BC7_Typeless,
339  PixelFormat.BC7_UNorm,
340  PixelFormat.BC7_UNorm_SRgb,
341  }, 8);
342 
343 
344  // Init compressed formats
345  InitDefaults(new[]
346  {
347  PixelFormat.BC1_Typeless,
348  PixelFormat.BC1_UNorm,
349  PixelFormat.BC1_UNorm_SRgb,
350  PixelFormat.BC2_Typeless,
351  PixelFormat.BC2_UNorm,
352  PixelFormat.BC2_UNorm_SRgb,
353  PixelFormat.BC3_Typeless,
354  PixelFormat.BC3_UNorm,
355  PixelFormat.BC3_UNorm_SRgb,
356  PixelFormat.BC4_Typeless,
357  PixelFormat.BC4_UNorm,
358  PixelFormat.BC4_SNorm,
359  PixelFormat.BC5_Typeless,
360  PixelFormat.BC5_UNorm,
361  PixelFormat.BC5_SNorm,
362  PixelFormat.BC6H_Typeless,
363  PixelFormat.BC6H_Uf16,
364  PixelFormat.BC6H_Sf16,
365  PixelFormat.BC7_Typeless,
366  PixelFormat.BC7_UNorm,
367  PixelFormat.BC7_UNorm_SRgb,
368  PixelFormat.PVRTC_2bpp_RGB,
369  PixelFormat.PVRTC_2bpp_RGBA,
370  PixelFormat.PVRTC_4bpp_RGB,
371  PixelFormat.PVRTC_4bpp_RGBA,
372  PixelFormat.PVRTC_II_2bpp,
373  PixelFormat.PVRTC_II_4bpp,
374  PixelFormat.ETC1,
375  PixelFormat.ETC2_RGB,
376  PixelFormat.ETC2_RGBA,
377  PixelFormat.ETC2_RGB_A1,
378  PixelFormat.EAC_R11_Unsigned,
379  PixelFormat.EAC_R11_Signed,
380  PixelFormat.EAC_RG11_Unsigned,
381  PixelFormat.EAC_RG11_Signed,
382  PixelFormat.ATC_RGB,
383  PixelFormat.ATC_RGBA_Explicit,
384  PixelFormat.ATC_RGBA_Interpolated,
385  }, compressedFormats);
386 
387  // Init srgb formats
388  InitDefaults(new[]
389  {
390  PixelFormat.R8G8B8A8_UNorm_SRgb,
391  PixelFormat.BC1_UNorm_SRgb,
392  PixelFormat.BC2_UNorm_SRgb,
393  PixelFormat.BC3_UNorm_SRgb,
394  PixelFormat.B8G8R8A8_UNorm_SRgb,
395  PixelFormat.B8G8R8X8_UNorm_SRgb,
396  PixelFormat.BC7_UNorm_SRgb,
397  }, srgbFormats);
398 
399  // Init typeless formats
400  InitDefaults(new[]
401  {
402  PixelFormat.R32G32B32A32_Typeless,
403  PixelFormat.R32G32B32_Typeless,
404  PixelFormat.R16G16B16A16_Typeless,
405  PixelFormat.R32G32_Typeless,
406  PixelFormat.R32G8X24_Typeless,
407  PixelFormat.R32_Float_X8X24_Typeless,
408  PixelFormat.X32_Typeless_G8X24_UInt,
409  PixelFormat.R10G10B10A2_Typeless,
410  PixelFormat.R8G8B8A8_Typeless,
411  PixelFormat.R16G16_Typeless,
412  PixelFormat.R32_Typeless,
413  PixelFormat.R24G8_Typeless,
414  PixelFormat.R24_UNorm_X8_Typeless,
415  PixelFormat.X24_Typeless_G8_UInt,
416  PixelFormat.R8G8_Typeless,
417  PixelFormat.R16_Typeless,
418  PixelFormat.R8_Typeless,
419  PixelFormat.BC1_Typeless,
420  PixelFormat.BC2_Typeless,
421  PixelFormat.BC3_Typeless,
422  PixelFormat.BC4_Typeless,
423  PixelFormat.BC5_Typeless,
424  PixelFormat.B8G8R8A8_Typeless,
425  PixelFormat.B8G8R8X8_Typeless,
426  PixelFormat.BC6H_Typeless,
427  PixelFormat.BC7_Typeless,
428  }, typelessFormats);
429  }
430 
431  private static void InitFormat(IEnumerable<PixelFormat> formats, int bitCount)
432  {
433  foreach (var format in formats)
434  sizeOfInBits[GetIndex(format)] = bitCount;
435  }
436 
437  private static void InitDefaults(IEnumerable<PixelFormat> formats, bool[] outputArray)
438  {
439  foreach (var format in formats)
440  outputArray[GetIndex(format)] = true;
441  }
442  }
443 }
static bool IsPacked(this PixelFormat fmt)
Determines whether the specified PixelFormat is packed.
static bool IsTypeless(this PixelFormat fmt)
Determines whether the specified PixelFormat is typeless.
static int ComputeScanlineCount(this PixelFormat fmt, int height)
Computes the scanline count (number of scanlines).
static bool IsSRgb(this PixelFormat fmt)
Determines whether the specified PixelFormat is a SRGB format.
static bool IsVideo(this PixelFormat fmt)
Determines whether the specified PixelFormat is video.
static int SizeInBits(this PixelFormat format)
Calculates the size of a PixelFormat in bits.
static bool IsValid(this PixelFormat format)
Returns true if the PixelFormat is valid.
static int SizeInBytes(this PixelFormat format)
Calculates the size of a PixelFormat in bytes.
static bool IsCompressed(this PixelFormat fmt)
Returns true if the PixelFormat is a compressed format.
_In_ size_t _In_ size_t _In_ DXGI_FORMAT format
Definition: DirectXTexP.h:175
PixelFormat
Defines various types of pixel formats.
Definition: PixelFormat.cs:32