]> git.cworth.org Git - apitrace/blob - thirdparty/directxtex/DirectXTex/DirectXTexUtil.cpp
directxtex: Fix include filename case.
[apitrace] / thirdparty / directxtex / DirectXTex / DirectXTexUtil.cpp
1 //-------------------------------------------------------------------------------------
2 // DirectXTexUtil.cpp
3 //  
4 // DirectX Texture Library - Utilities
5 //
6 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
7 // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
8 // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
9 // PARTICULAR PURPOSE.
10 //
11 // Copyright (c) Microsoft Corporation. All rights reserved.
12 //
13 // http://go.microsoft.com/fwlink/?LinkId=248926
14 //-------------------------------------------------------------------------------------
15
16 #include "DirectXTexP.h"
17
18 //-------------------------------------------------------------------------------------
19 // WIC Pixel Format Translation Data
20 //-------------------------------------------------------------------------------------
21 struct WICTranslate
22 {
23     GUID        wic;
24     DXGI_FORMAT format;
25 };
26
27 static WICTranslate g_WICFormats[] = 
28 {
29     { GUID_WICPixelFormat128bppRGBAFloat,       DXGI_FORMAT_R32G32B32A32_FLOAT },
30
31     { GUID_WICPixelFormat64bppRGBAHalf,         DXGI_FORMAT_R16G16B16A16_FLOAT },
32     { GUID_WICPixelFormat64bppRGBA,             DXGI_FORMAT_R16G16B16A16_UNORM },
33
34     { GUID_WICPixelFormat32bppRGBA,             DXGI_FORMAT_R8G8B8A8_UNORM },
35     { GUID_WICPixelFormat32bppBGRA,             DXGI_FORMAT_B8G8R8A8_UNORM }, // DXGI 1.1
36     { GUID_WICPixelFormat32bppBGR,              DXGI_FORMAT_B8G8R8X8_UNORM }, // DXGI 1.1
37
38     { GUID_WICPixelFormat32bppRGBA1010102XR,    DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM }, // DXGI 1.1
39     { GUID_WICPixelFormat32bppRGBA1010102,      DXGI_FORMAT_R10G10B10A2_UNORM },
40     { GUID_WICPixelFormat32bppRGBE,             DXGI_FORMAT_R9G9B9E5_SHAREDEXP },
41
42     { GUID_WICPixelFormat16bppBGRA5551,         DXGI_FORMAT_B5G5R5A1_UNORM },
43     { GUID_WICPixelFormat16bppBGR565,           DXGI_FORMAT_B5G6R5_UNORM },
44
45     { GUID_WICPixelFormat32bppGrayFloat,        DXGI_FORMAT_R32_FLOAT },
46     { GUID_WICPixelFormat16bppGrayHalf,         DXGI_FORMAT_R16_FLOAT },
47     { GUID_WICPixelFormat16bppGray,             DXGI_FORMAT_R16_UNORM },
48     { GUID_WICPixelFormat8bppGray,              DXGI_FORMAT_R8_UNORM },
49
50     { GUID_WICPixelFormat8bppAlpha,             DXGI_FORMAT_A8_UNORM },
51
52     { GUID_WICPixelFormatBlackWhite,            DXGI_FORMAT_R1_UNORM },
53 };
54
55 static bool g_WIC2 = false;
56
57 namespace DirectX
58 {
59
60 //=====================================================================================
61 // WIC Utilities
62 //=====================================================================================
63
64 DXGI_FORMAT _WICToDXGI( const GUID& guid )
65 {
66     for( size_t i=0; i < _countof(g_WICFormats); ++i )
67     {
68         if ( memcmp( &g_WICFormats[i].wic, &guid, sizeof(GUID) ) == 0 )
69             return g_WICFormats[i].format;
70     }
71
72 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE)
73     if ( g_WIC2 )
74     {
75         if ( memcmp( &GUID_WICPixelFormat96bppRGBFloat, &guid, sizeof(GUID) ) == 0 )
76             return DXGI_FORMAT_R32G32B32_FLOAT;
77     }
78 #endif
79
80     return DXGI_FORMAT_UNKNOWN;
81 }
82
83 bool _DXGIToWIC( DXGI_FORMAT format, GUID& guid )
84 {
85     switch( format )
86     {
87     case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
88         memcpy( &guid, &GUID_WICPixelFormat32bppRGBA, sizeof(GUID) );
89         return true;
90
91     case DXGI_FORMAT_D32_FLOAT:
92         memcpy( &guid, &GUID_WICPixelFormat32bppGrayFloat, sizeof(GUID) );
93         return true;
94
95     case DXGI_FORMAT_D16_UNORM:
96         memcpy( &guid, &GUID_WICPixelFormat16bppGray, sizeof(GUID) );
97         return true;    
98
99     case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
100         memcpy( &guid, &GUID_WICPixelFormat32bppBGRA, sizeof(GUID) );
101         return true;
102
103     case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
104         memcpy( &guid, &GUID_WICPixelFormat32bppBGR, sizeof(GUID) );
105         return true;
106
107 #if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE)
108     case DXGI_FORMAT_R32G32B32_FLOAT:
109         if ( g_WIC2 )
110         {
111             memcpy( &guid, &GUID_WICPixelFormat96bppRGBFloat, sizeof(GUID) );
112             return true;
113         }
114         break;
115 #endif
116
117     default:
118         for( size_t i=0; i < _countof(g_WICFormats); ++i )
119         {
120             if ( g_WICFormats[i].format == format )
121             {
122                 memcpy( &guid, &g_WICFormats[i].wic, sizeof(GUID) );
123                 return true;
124             }
125         }
126         break;
127     }
128
129     memcpy( &guid, &GUID_NULL, sizeof(GUID) );
130     return false;
131 }
132
133 bool _IsWIC2()
134 {
135     return g_WIC2;
136 }
137
138 IWICImagingFactory* _GetWIC()
139 {
140     static IWICImagingFactory* s_Factory = nullptr;
141
142     if ( s_Factory )
143         return s_Factory;
144
145 #if(_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) || defined(_WIN7_PLATFORM_UPDATE)
146     HRESULT hr = CoCreateInstance(
147         CLSID_WICImagingFactory2,
148         nullptr,
149         CLSCTX_INPROC_SERVER,
150         __uuidof(IWICImagingFactory2),
151         (LPVOID*)&s_Factory
152         );
153
154     if ( SUCCEEDED(hr) )
155     {
156         // WIC2 is available on Windows 8 and Windows 7 SP1 with KB 2670838 installed
157         g_WIC2 = true;
158     }
159     else
160     {
161         hr = CoCreateInstance(
162             CLSID_WICImagingFactory1,
163             nullptr,
164             CLSCTX_INPROC_SERVER,
165             __uuidof(IWICImagingFactory),
166             (LPVOID*)&s_Factory
167             );
168
169         if ( FAILED(hr) )
170         {
171             s_Factory = nullptr;
172             return nullptr;
173         }
174     }
175 #else
176     HRESULT hr = CoCreateInstance(
177         CLSID_WICImagingFactory,
178         nullptr,
179         CLSCTX_INPROC_SERVER,
180         __uuidof(IWICImagingFactory),
181         (LPVOID*)&s_Factory
182         );
183
184     if ( FAILED(hr) )
185     {
186         s_Factory = nullptr;
187         return nullptr;
188     }
189 #endif
190
191     return s_Factory;
192 }
193
194
195 //-------------------------------------------------------------------------------------
196 // Public helper function to get common WIC codec GUIDs
197 //-------------------------------------------------------------------------------------
198 REFGUID GetWICCodec( _In_ WICCodecs codec )
199 {
200     switch( codec )
201     {
202     case WIC_CODEC_BMP:
203         return GUID_ContainerFormatBmp;
204
205     case WIC_CODEC_JPEG:
206         return GUID_ContainerFormatJpeg;
207
208     case WIC_CODEC_PNG:
209         return GUID_ContainerFormatPng;
210
211     case WIC_CODEC_TIFF:
212         return GUID_ContainerFormatTiff;
213
214     case WIC_CODEC_GIF:
215         return GUID_ContainerFormatGif;
216
217     case WIC_CODEC_WMP:
218         return GUID_ContainerFormatWmp;
219
220     case WIC_CODEC_ICO:
221         return GUID_ContainerFormatIco;
222
223     default:
224         return GUID_NULL;
225     }
226 }
227
228
229 //=====================================================================================
230 // DXGI Format Utilities
231 //=====================================================================================
232
233 //-------------------------------------------------------------------------------------
234 // Returns bits-per-pixel for a given DXGI format, or 0 on failure
235 //-------------------------------------------------------------------------------------
236 size_t BitsPerPixel( DXGI_FORMAT fmt )
237 {
238     switch( fmt )
239     {
240     case DXGI_FORMAT_R32G32B32A32_TYPELESS:
241     case DXGI_FORMAT_R32G32B32A32_FLOAT:
242     case DXGI_FORMAT_R32G32B32A32_UINT:
243     case DXGI_FORMAT_R32G32B32A32_SINT:
244         return 128;
245
246     case DXGI_FORMAT_R32G32B32_TYPELESS:
247     case DXGI_FORMAT_R32G32B32_FLOAT:
248     case DXGI_FORMAT_R32G32B32_UINT:
249     case DXGI_FORMAT_R32G32B32_SINT:
250         return 96;
251
252     case DXGI_FORMAT_R16G16B16A16_TYPELESS:
253     case DXGI_FORMAT_R16G16B16A16_FLOAT:
254     case DXGI_FORMAT_R16G16B16A16_UNORM:
255     case DXGI_FORMAT_R16G16B16A16_UINT:
256     case DXGI_FORMAT_R16G16B16A16_SNORM:
257     case DXGI_FORMAT_R16G16B16A16_SINT:
258     case DXGI_FORMAT_R32G32_TYPELESS:
259     case DXGI_FORMAT_R32G32_FLOAT:
260     case DXGI_FORMAT_R32G32_UINT:
261     case DXGI_FORMAT_R32G32_SINT:
262     case DXGI_FORMAT_R32G8X24_TYPELESS:
263     case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
264     case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
265     case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
266         return 64;
267
268     case DXGI_FORMAT_R10G10B10A2_TYPELESS:
269     case DXGI_FORMAT_R10G10B10A2_UNORM:
270     case DXGI_FORMAT_R10G10B10A2_UINT:
271     case DXGI_FORMAT_R11G11B10_FLOAT:
272     case DXGI_FORMAT_R8G8B8A8_TYPELESS:
273     case DXGI_FORMAT_R8G8B8A8_UNORM:
274     case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
275     case DXGI_FORMAT_R8G8B8A8_UINT:
276     case DXGI_FORMAT_R8G8B8A8_SNORM:
277     case DXGI_FORMAT_R8G8B8A8_SINT:
278     case DXGI_FORMAT_R16G16_TYPELESS:
279     case DXGI_FORMAT_R16G16_FLOAT:
280     case DXGI_FORMAT_R16G16_UNORM:
281     case DXGI_FORMAT_R16G16_UINT:
282     case DXGI_FORMAT_R16G16_SNORM:
283     case DXGI_FORMAT_R16G16_SINT:
284     case DXGI_FORMAT_R32_TYPELESS:
285     case DXGI_FORMAT_D32_FLOAT:
286     case DXGI_FORMAT_R32_FLOAT:
287     case DXGI_FORMAT_R32_UINT:
288     case DXGI_FORMAT_R32_SINT:
289     case DXGI_FORMAT_R24G8_TYPELESS:
290     case DXGI_FORMAT_D24_UNORM_S8_UINT:
291     case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
292     case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
293     case DXGI_FORMAT_R9G9B9E5_SHAREDEXP:
294     case DXGI_FORMAT_R8G8_B8G8_UNORM:
295     case DXGI_FORMAT_G8R8_G8B8_UNORM:
296     case DXGI_FORMAT_B8G8R8A8_UNORM:
297     case DXGI_FORMAT_B8G8R8X8_UNORM:
298     case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
299     case DXGI_FORMAT_B8G8R8A8_TYPELESS:
300     case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
301     case DXGI_FORMAT_B8G8R8X8_TYPELESS:
302     case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
303         return 32;
304
305     case DXGI_FORMAT_R8G8_TYPELESS:
306     case DXGI_FORMAT_R8G8_UNORM:
307     case DXGI_FORMAT_R8G8_UINT:
308     case DXGI_FORMAT_R8G8_SNORM:
309     case DXGI_FORMAT_R8G8_SINT:
310     case DXGI_FORMAT_R16_TYPELESS:
311     case DXGI_FORMAT_R16_FLOAT:
312     case DXGI_FORMAT_D16_UNORM:
313     case DXGI_FORMAT_R16_UNORM:
314     case DXGI_FORMAT_R16_UINT:
315     case DXGI_FORMAT_R16_SNORM:
316     case DXGI_FORMAT_R16_SINT:
317     case DXGI_FORMAT_B5G6R5_UNORM:
318     case DXGI_FORMAT_B5G5R5A1_UNORM:
319         return 16;
320
321     case DXGI_FORMAT_R8_TYPELESS:
322     case DXGI_FORMAT_R8_UNORM:
323     case DXGI_FORMAT_R8_UINT:
324     case DXGI_FORMAT_R8_SNORM:
325     case DXGI_FORMAT_R8_SINT:
326     case DXGI_FORMAT_A8_UNORM:
327         return 8;
328
329     case DXGI_FORMAT_R1_UNORM:
330         return 1;
331
332     case DXGI_FORMAT_BC1_TYPELESS:
333     case DXGI_FORMAT_BC1_UNORM:
334     case DXGI_FORMAT_BC1_UNORM_SRGB:
335     case DXGI_FORMAT_BC4_TYPELESS:
336     case DXGI_FORMAT_BC4_UNORM:
337     case DXGI_FORMAT_BC4_SNORM:
338         return 4;
339
340     case DXGI_FORMAT_BC2_TYPELESS:
341     case DXGI_FORMAT_BC2_UNORM:
342     case DXGI_FORMAT_BC2_UNORM_SRGB:
343     case DXGI_FORMAT_BC3_TYPELESS:
344     case DXGI_FORMAT_BC3_UNORM:
345     case DXGI_FORMAT_BC3_UNORM_SRGB:
346     case DXGI_FORMAT_BC5_TYPELESS:
347     case DXGI_FORMAT_BC5_UNORM:
348     case DXGI_FORMAT_BC5_SNORM:
349     case DXGI_FORMAT_BC6H_TYPELESS:
350     case DXGI_FORMAT_BC6H_UF16:
351     case DXGI_FORMAT_BC6H_SF16:
352     case DXGI_FORMAT_BC7_TYPELESS:
353     case DXGI_FORMAT_BC7_UNORM:
354     case DXGI_FORMAT_BC7_UNORM_SRGB:
355         return 8;
356
357 #ifdef DXGI_1_2_FORMATS
358     case DXGI_FORMAT_B4G4R4A4_UNORM:
359         return 16;
360
361     // We don't support the video formats ( see IsVideo function )
362
363 #endif // DXGI_1_2_FORMATS
364
365     default:
366         return 0;
367     }
368 }
369
370
371 //-------------------------------------------------------------------------------------
372 // Computes the image row pitch in bytes, and the slice ptich (size in bytes of the image)
373 // based on DXGI format, width, and height
374 //-------------------------------------------------------------------------------------
375 void ComputePitch( DXGI_FORMAT fmt, size_t width, size_t height,
376                    size_t& rowPitch, size_t& slicePitch, DWORD flags )
377 {
378     assert( IsValid(fmt) && !IsVideo(fmt) );
379
380     if ( IsCompressed(fmt) )
381     {
382         size_t bpb = ( fmt == DXGI_FORMAT_BC1_TYPELESS
383                      || fmt == DXGI_FORMAT_BC1_UNORM
384                      || fmt == DXGI_FORMAT_BC1_UNORM_SRGB
385                      || fmt == DXGI_FORMAT_BC4_TYPELESS
386                      || fmt == DXGI_FORMAT_BC4_UNORM
387                      || fmt == DXGI_FORMAT_BC4_SNORM) ? 8 : 16;
388         size_t nbw = std::max<size_t>( 1, (width + 3) / 4 );
389         size_t nbh = std::max<size_t>( 1, (height + 3) / 4 );
390         rowPitch = nbw * bpb;
391
392         slicePitch = rowPitch * nbh;
393     }
394     else if ( IsPacked(fmt) )
395     {
396         rowPitch = ( ( width + 1 ) >> 1) * 4;
397
398         slicePitch = rowPitch * height;
399     }
400     else
401     {
402         size_t bpp;
403
404         if ( flags & CP_FLAGS_24BPP )
405             bpp = 24;
406         else if ( flags & CP_FLAGS_16BPP )
407             bpp = 16;
408         else if ( flags & CP_FLAGS_8BPP )
409             bpp = 8;
410         else
411             bpp = BitsPerPixel( fmt );
412
413         if ( flags & CP_FLAGS_LEGACY_DWORD )
414         {
415             // Special computation for some incorrectly created DDS files based on
416             // legacy DirectDraw assumptions about pitch alignment
417             rowPitch = ( ( width * bpp + 31 ) / 32 ) * sizeof(uint32_t);
418             slicePitch = rowPitch * height;
419         }
420         else
421         {
422             rowPitch = ( width * bpp + 7 ) / 8;
423             slicePitch = rowPitch * height;
424         }
425     }
426 }
427
428
429 //-------------------------------------------------------------------------------------
430 // Converts to an SRGB equivalent type if available
431 //-------------------------------------------------------------------------------------
432 DXGI_FORMAT MakeSRGB( _In_ DXGI_FORMAT fmt )
433 {
434     switch( fmt )
435     {
436     case DXGI_FORMAT_R8G8B8A8_UNORM:
437         return DXGI_FORMAT_R8G8B8A8_UNORM_SRGB;
438
439     case DXGI_FORMAT_BC1_UNORM:
440         return DXGI_FORMAT_BC1_UNORM_SRGB;
441
442     case DXGI_FORMAT_BC2_UNORM:
443         return DXGI_FORMAT_BC2_UNORM_SRGB;
444
445     case DXGI_FORMAT_BC3_UNORM:
446         return DXGI_FORMAT_BC3_UNORM_SRGB;
447
448     case DXGI_FORMAT_B8G8R8A8_UNORM:
449         return DXGI_FORMAT_B8G8R8A8_UNORM_SRGB;
450
451     case DXGI_FORMAT_B8G8R8X8_UNORM:
452         return DXGI_FORMAT_B8G8R8X8_UNORM_SRGB;
453
454     case DXGI_FORMAT_BC7_UNORM:
455         return DXGI_FORMAT_BC7_UNORM_SRGB;
456
457     default:
458         return fmt;
459     }
460 }
461
462
463 //-------------------------------------------------------------------------------------
464 // Converts to a format to an equivalent TYPELESS format if available
465 //-------------------------------------------------------------------------------------
466 DXGI_FORMAT MakeTypeless( _In_ DXGI_FORMAT fmt )
467 {
468     switch( fmt )
469     {
470     case DXGI_FORMAT_R32G32B32A32_FLOAT:
471     case DXGI_FORMAT_R32G32B32A32_UINT:
472     case DXGI_FORMAT_R32G32B32A32_SINT:
473         return DXGI_FORMAT_R32G32B32A32_TYPELESS;
474
475     case DXGI_FORMAT_R32G32B32_FLOAT:
476     case DXGI_FORMAT_R32G32B32_UINT:
477     case DXGI_FORMAT_R32G32B32_SINT:
478         return DXGI_FORMAT_R32G32B32_TYPELESS;
479
480     case DXGI_FORMAT_R16G16B16A16_FLOAT:
481     case DXGI_FORMAT_R16G16B16A16_UNORM:
482     case DXGI_FORMAT_R16G16B16A16_UINT:
483     case DXGI_FORMAT_R16G16B16A16_SNORM:
484     case DXGI_FORMAT_R16G16B16A16_SINT:
485         return DXGI_FORMAT_R16G16B16A16_TYPELESS;
486
487     case DXGI_FORMAT_R32G32_FLOAT:
488     case DXGI_FORMAT_R32G32_UINT:
489     case DXGI_FORMAT_R32G32_SINT:
490         return DXGI_FORMAT_R32G32_TYPELESS;
491
492     case DXGI_FORMAT_R10G10B10A2_UNORM:
493     case DXGI_FORMAT_R10G10B10A2_UINT:
494         return DXGI_FORMAT_R10G10B10A2_TYPELESS;
495
496     case DXGI_FORMAT_R8G8B8A8_UNORM:
497     case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
498     case DXGI_FORMAT_R8G8B8A8_UINT:
499     case DXGI_FORMAT_R8G8B8A8_SNORM:
500     case DXGI_FORMAT_R8G8B8A8_SINT:
501         return DXGI_FORMAT_R8G8B8A8_TYPELESS;
502
503     case DXGI_FORMAT_R16G16_FLOAT:
504     case DXGI_FORMAT_R16G16_UNORM:
505     case DXGI_FORMAT_R16G16_UINT:
506     case DXGI_FORMAT_R16G16_SNORM:
507     case DXGI_FORMAT_R16G16_SINT:
508         return DXGI_FORMAT_R16G16_TYPELESS;
509
510     case DXGI_FORMAT_D32_FLOAT:
511     case DXGI_FORMAT_R32_FLOAT:
512     case DXGI_FORMAT_R32_UINT:
513     case DXGI_FORMAT_R32_SINT:
514         return DXGI_FORMAT_R32_TYPELESS;
515
516     case DXGI_FORMAT_R8G8_UNORM:
517     case DXGI_FORMAT_R8G8_UINT:
518     case DXGI_FORMAT_R8G8_SNORM:
519     case DXGI_FORMAT_R8G8_SINT:
520         return DXGI_FORMAT_R8G8_TYPELESS;
521
522     case DXGI_FORMAT_R16_FLOAT:
523     case DXGI_FORMAT_D16_UNORM:
524     case DXGI_FORMAT_R16_UNORM:
525     case DXGI_FORMAT_R16_UINT:
526     case DXGI_FORMAT_R16_SNORM:
527     case DXGI_FORMAT_R16_SINT:
528         return DXGI_FORMAT_R16_TYPELESS;
529
530     case DXGI_FORMAT_R8_UNORM:
531     case DXGI_FORMAT_R8_UINT:
532     case DXGI_FORMAT_R8_SNORM:
533     case DXGI_FORMAT_R8_SINT:
534     case DXGI_FORMAT_A8_UNORM:
535         return DXGI_FORMAT_R8_TYPELESS;
536
537     case DXGI_FORMAT_BC1_UNORM:
538     case DXGI_FORMAT_BC1_UNORM_SRGB:
539         return DXGI_FORMAT_BC1_TYPELESS;
540
541     case DXGI_FORMAT_BC2_UNORM:
542     case DXGI_FORMAT_BC2_UNORM_SRGB:
543         return DXGI_FORMAT_BC2_TYPELESS;
544
545     case DXGI_FORMAT_BC3_UNORM:
546     case DXGI_FORMAT_BC3_UNORM_SRGB:
547         return DXGI_FORMAT_BC3_TYPELESS;
548
549     case DXGI_FORMAT_BC4_UNORM:
550     case DXGI_FORMAT_BC4_SNORM:
551         return DXGI_FORMAT_BC4_TYPELESS;
552
553     case DXGI_FORMAT_BC5_UNORM:
554     case DXGI_FORMAT_BC5_SNORM:
555         return DXGI_FORMAT_BC5_TYPELESS;
556
557     case DXGI_FORMAT_B8G8R8A8_UNORM:
558     case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
559         return DXGI_FORMAT_B8G8R8A8_TYPELESS;
560
561     case DXGI_FORMAT_B8G8R8X8_UNORM:
562     case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
563         return DXGI_FORMAT_B8G8R8X8_TYPELESS;
564
565     case DXGI_FORMAT_BC6H_UF16:
566     case DXGI_FORMAT_BC6H_SF16:
567         return DXGI_FORMAT_BC6H_TYPELESS;
568
569     case DXGI_FORMAT_BC7_UNORM:
570     case DXGI_FORMAT_BC7_UNORM_SRGB:
571         return DXGI_FORMAT_BC7_TYPELESS;
572
573     default:
574         return fmt;
575     }
576 }
577
578
579 //-------------------------------------------------------------------------------------
580 // Converts to a TYPELESS format to an equivalent UNORM format if available
581 //-------------------------------------------------------------------------------------
582 DXGI_FORMAT MakeTypelessUNORM( _In_ DXGI_FORMAT fmt )
583 {
584     switch( fmt )
585     {
586     case DXGI_FORMAT_R16G16B16A16_TYPELESS:
587         return DXGI_FORMAT_R16G16B16A16_UNORM;
588
589     case DXGI_FORMAT_R10G10B10A2_TYPELESS:
590         return DXGI_FORMAT_R10G10B10A2_UNORM;
591
592     case DXGI_FORMAT_R8G8B8A8_TYPELESS:
593         return DXGI_FORMAT_R8G8B8A8_UNORM;
594
595     case DXGI_FORMAT_R16G16_TYPELESS:
596         return DXGI_FORMAT_R16G16_UNORM;
597
598     case DXGI_FORMAT_R8G8_TYPELESS:
599         return DXGI_FORMAT_R8G8_UNORM;
600
601     case DXGI_FORMAT_R16_TYPELESS:
602         return DXGI_FORMAT_R16_UNORM;
603
604     case DXGI_FORMAT_R8_TYPELESS:
605         return DXGI_FORMAT_R8_UNORM;
606
607     case DXGI_FORMAT_BC1_TYPELESS:
608         return DXGI_FORMAT_BC1_UNORM;
609
610     case DXGI_FORMAT_BC2_TYPELESS:
611         return DXGI_FORMAT_BC2_UNORM;
612
613     case DXGI_FORMAT_BC3_TYPELESS:
614         return DXGI_FORMAT_BC3_UNORM;
615
616     case DXGI_FORMAT_BC4_TYPELESS:
617         return DXGI_FORMAT_BC4_UNORM;
618
619     case DXGI_FORMAT_BC5_TYPELESS:
620         return DXGI_FORMAT_BC5_UNORM;
621
622     case DXGI_FORMAT_B8G8R8A8_TYPELESS:
623         return DXGI_FORMAT_B8G8R8A8_UNORM;
624
625     case DXGI_FORMAT_B8G8R8X8_TYPELESS:
626         return DXGI_FORMAT_B8G8R8X8_UNORM;
627
628     case DXGI_FORMAT_BC7_TYPELESS:
629         return DXGI_FORMAT_BC7_UNORM;
630
631     default:
632         return fmt;
633     }
634 }
635
636
637 //-------------------------------------------------------------------------------------
638 // Converts to a TYPELESS format to an equivalent FLOAT format if available
639 //-------------------------------------------------------------------------------------
640 DXGI_FORMAT MakeTypelessFLOAT( _In_ DXGI_FORMAT fmt )
641 {
642     switch( fmt )
643     {
644     case DXGI_FORMAT_R32G32B32A32_TYPELESS:
645         return DXGI_FORMAT_R32G32B32A32_FLOAT;
646
647     case DXGI_FORMAT_R32G32B32_TYPELESS:
648         return DXGI_FORMAT_R32G32B32_FLOAT;
649
650     case DXGI_FORMAT_R16G16B16A16_TYPELESS:
651         return DXGI_FORMAT_R16G16B16A16_FLOAT;
652
653     case DXGI_FORMAT_R32G32_TYPELESS:
654         return DXGI_FORMAT_R32G32_FLOAT;
655
656     case DXGI_FORMAT_R16G16_TYPELESS:
657         return DXGI_FORMAT_R16G16_FLOAT;
658
659     case DXGI_FORMAT_R32_TYPELESS:
660         return DXGI_FORMAT_R32_FLOAT;
661
662     case DXGI_FORMAT_R16_TYPELESS:
663         return DXGI_FORMAT_R16_FLOAT;
664
665     default:
666         return fmt;
667     }
668 }
669
670
671 //=====================================================================================
672 // TexMetadata
673 //=====================================================================================
674
675 size_t TexMetadata::ComputeIndex( _In_ size_t mip, _In_ size_t item, _In_ size_t slice ) const
676 {
677     if ( mip >= mipLevels )
678         return size_t(-1);
679
680     switch( dimension )
681     {
682     case TEX_DIMENSION_TEXTURE1D:
683     case TEX_DIMENSION_TEXTURE2D:
684         if ( slice > 0 )
685             return size_t(-1);
686
687         if ( item >= arraySize )
688             return size_t(-1);
689
690         return (item*( mipLevels ) + mip);
691
692     case TEX_DIMENSION_TEXTURE3D:
693         if ( item > 0 )
694         {
695             // No support for arrays of volumes
696             return size_t(-1);
697         }
698         else
699         {
700             size_t index = 0;
701             size_t d = depth;
702
703             for( size_t level = 0; level < mip; ++level )
704             {
705                 index += d;
706                 if ( d > 1 )
707                     d >>= 1;
708             }
709
710             if ( slice >= d )
711                 return size_t(-1);
712
713             index += slice;
714
715             return index;
716         }
717         break;
718
719     default:
720         return size_t(-1);
721     }
722 }
723
724
725 //=====================================================================================
726 // Blob - Bitmap image container
727 //=====================================================================================
728
729 void Blob::Release()
730 {
731     if ( _buffer )
732     {
733         _aligned_free( _buffer );
734         _buffer = nullptr;
735     }
736
737     _size = 0;
738 }
739
740 HRESULT Blob::Initialize( size_t size )
741 {
742     if ( !size )
743         return E_INVALIDARG;
744
745     Release();
746
747     _buffer = _aligned_malloc( size, 16 );
748     if ( !_buffer )
749     {
750         Release();
751         return E_OUTOFMEMORY;
752     }
753
754     _size = size;
755
756     return S_OK;
757 }
758
759 }; // namespace