1//-------------------------------------------------------------------------------------
2// DirectXTex.inl
3//
4// DirectX Texture Library
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#pragma once
17
18//=====================================================================================
19// DXGI Format Utilities
20//=====================================================================================
21
22_Use_decl_annotations_
23inline bool __cdecl IsValid( DXGI_FORMAT fmt )
24{
25    return ( static_cast<size_t>(fmt) >= 1 && static_cast<size_t>(fmt) <= 120 );
26}
27
28_Use_decl_annotations_
29inline bool __cdecl IsCompressed(DXGI_FORMAT fmt)
30{
31    switch ( fmt )
32    {
33    case DXGI_FORMAT_BC1_TYPELESS:
34    case DXGI_FORMAT_BC1_UNORM:
35    case DXGI_FORMAT_BC1_UNORM_SRGB:
36    case DXGI_FORMAT_BC2_TYPELESS:
37    case DXGI_FORMAT_BC2_UNORM:
38    case DXGI_FORMAT_BC2_UNORM_SRGB:
39    case DXGI_FORMAT_BC3_TYPELESS:
40    case DXGI_FORMAT_BC3_UNORM:
41    case DXGI_FORMAT_BC3_UNORM_SRGB:
42    case DXGI_FORMAT_BC4_TYPELESS:
43    case DXGI_FORMAT_BC4_UNORM:
44    case DXGI_FORMAT_BC4_SNORM:
45    case DXGI_FORMAT_BC5_TYPELESS:
46    case DXGI_FORMAT_BC5_UNORM:
47    case DXGI_FORMAT_BC5_SNORM:
48    case DXGI_FORMAT_BC6H_TYPELESS:
49    case DXGI_FORMAT_BC6H_UF16:
50    case DXGI_FORMAT_BC6H_SF16:
51    case DXGI_FORMAT_BC7_TYPELESS:
52    case DXGI_FORMAT_BC7_UNORM:
53    case DXGI_FORMAT_BC7_UNORM_SRGB:
54        return true;
55
56    default:
57        return false;
58    }
59}
60
61_Use_decl_annotations_
62inline bool __cdecl IsPacked(DXGI_FORMAT fmt)
63{
64    switch( fmt )
65    {
66    case DXGI_FORMAT_R8G8_B8G8_UNORM:
67    case DXGI_FORMAT_G8R8_G8B8_UNORM:
68    case DXGI_FORMAT_YUY2: // 4:2:2 8-bit
69    case DXGI_FORMAT_Y210: // 4:2:2 10-bit
70    case DXGI_FORMAT_Y216: // 4:2:2 16-bit
71        return true;
72
73    default:
74        return false;
75    }
76}
77
78_Use_decl_annotations_
79inline bool __cdecl IsPlanar(DXGI_FORMAT fmt)
80{
81    switch ( static_cast<int>(fmt) )
82    {
83    case DXGI_FORMAT_NV12:      // 4:2:0 8-bit
84    case DXGI_FORMAT_P010:      // 4:2:0 10-bit
85    case DXGI_FORMAT_P016:      // 4:2:0 16-bit
86    case DXGI_FORMAT_420_OPAQUE:// 4:2:0 8-bit
87    case DXGI_FORMAT_NV11:      // 4:1:1 8-bit
88        return true;
89
90    case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
91    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
92    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
93        // These are Xbox One platform specific types
94        return true;
95
96    default:
97        return false;
98    }
99}
100
101_Use_decl_annotations_
102inline bool __cdecl IsPalettized(DXGI_FORMAT fmt)
103{
104    switch( fmt )
105    {
106    case DXGI_FORMAT_AI44:
107    case DXGI_FORMAT_IA44:
108    case DXGI_FORMAT_P8:
109    case DXGI_FORMAT_A8P8:
110        return true;
111
112    default:
113        return false;
114    }
115}
116
117_Use_decl_annotations_
118inline bool __cdecl IsVideo(DXGI_FORMAT fmt)
119{
120    switch ( fmt )
121    {
122    case DXGI_FORMAT_AYUV:
123    case DXGI_FORMAT_Y410:
124    case DXGI_FORMAT_Y416:
125    case DXGI_FORMAT_NV12:
126    case DXGI_FORMAT_P010:
127    case DXGI_FORMAT_P016:
128    case DXGI_FORMAT_YUY2:
129    case DXGI_FORMAT_Y210:
130    case DXGI_FORMAT_Y216:
131    case DXGI_FORMAT_NV11:
132        // These video formats can be used with the 3D pipeline through special view mappings
133
134    case DXGI_FORMAT_420_OPAQUE:
135    case DXGI_FORMAT_AI44:
136    case DXGI_FORMAT_IA44:
137    case DXGI_FORMAT_P8:
138    case DXGI_FORMAT_A8P8:
139        // These are limited use video formats not usable in any way by the 3D pipeline
140        return true;
141
142    default:
143        return false;
144    }
145}
146
147_Use_decl_annotations_
148inline bool __cdecl IsDepthStencil(DXGI_FORMAT fmt)
149{
150    switch( static_cast<int>(fmt) )
151    {
152    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
153    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
154    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
155    case DXGI_FORMAT_D32_FLOAT:
156    case DXGI_FORMAT_D24_UNORM_S8_UINT:
157    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
158    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
159    case DXGI_FORMAT_D16_UNORM:
160    case 118 /* DXGI_FORMAT_D16_UNORM_S8_UINT */:
161    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
162    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
163        return true;
164
165    default:
166        return false;
167    }
168}
169
170_Use_decl_annotations_
171inline bool __cdecl IsSRGB(DXGI_FORMAT fmt)
172{
173    switch( fmt )
174    {
175    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
176    case DXGI_FORMAT_BC1_UNORM_SRGB:
177    case DXGI_FORMAT_BC2_UNORM_SRGB:
178    case DXGI_FORMAT_BC3_UNORM_SRGB:
179    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
180    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:
181    case DXGI_FORMAT_BC7_UNORM_SRGB:
182        return true;
183
184    default:
185        return false;
186    }
187}
188
189_Use_decl_annotations_
190inline bool __cdecl IsTypeless(DXGI_FORMAT fmt, bool partialTypeless)
191{
192    switch( static_cast<int>(fmt) )
193    {
194    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
195    case DXGI_FORMAT_R32G32B32_TYPELESS:
196    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
197    case DXGI_FORMAT_R32G32_TYPELESS:
198    case DXGI_FORMAT_R32G8X24_TYPELESS:
199    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
200    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
201    case DXGI_FORMAT_R16G16_TYPELESS:
202    case DXGI_FORMAT_R32_TYPELESS:
203    case DXGI_FORMAT_R24G8_TYPELESS:
204    case DXGI_FORMAT_R8G8_TYPELESS:
205    case DXGI_FORMAT_R16_TYPELESS:
206    case DXGI_FORMAT_R8_TYPELESS:
207    case DXGI_FORMAT_BC1_TYPELESS:
208    case DXGI_FORMAT_BC2_TYPELESS:
209    case DXGI_FORMAT_BC3_TYPELESS:
210    case DXGI_FORMAT_BC4_TYPELESS:
211    case DXGI_FORMAT_BC5_TYPELESS:
212    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
213    case DXGI_FORMAT_B8G8R8X8_TYPELESS:
214    case DXGI_FORMAT_BC6H_TYPELESS:
215    case DXGI_FORMAT_BC7_TYPELESS:
216        return true;
217
218    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
219    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
220    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
221    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
222        return partialTypeless;
223
224    case 119 /* DXGI_FORMAT_R16_UNORM_X8_TYPELESS */:
225    case 120 /* DXGI_FORMAT_X16_TYPELESS_G8_UINT */:
226        // These are Xbox One platform specific types
227        return partialTypeless;
228
229    default:
230        return false;
231    }
232}
233
234_Use_decl_annotations_
235inline bool __cdecl HasAlpha(DXGI_FORMAT fmt)
236{
237    switch( static_cast<int>(fmt) )
238    {
239    case DXGI_FORMAT_R32G32B32A32_TYPELESS:
240    case DXGI_FORMAT_R32G32B32A32_FLOAT:
241    case DXGI_FORMAT_R32G32B32A32_UINT:
242    case DXGI_FORMAT_R32G32B32A32_SINT:
243    case DXGI_FORMAT_R16G16B16A16_TYPELESS:
244    case DXGI_FORMAT_R16G16B16A16_FLOAT:
245    case DXGI_FORMAT_R16G16B16A16_UNORM:
246    case DXGI_FORMAT_R16G16B16A16_UINT:
247    case DXGI_FORMAT_R16G16B16A16_SNORM:
248    case DXGI_FORMAT_R16G16B16A16_SINT:
249    case DXGI_FORMAT_R10G10B10A2_TYPELESS:
250    case DXGI_FORMAT_R10G10B10A2_UNORM:
251    case DXGI_FORMAT_R10G10B10A2_UINT:
252    case DXGI_FORMAT_R8G8B8A8_TYPELESS:
253    case DXGI_FORMAT_R8G8B8A8_UNORM:
254    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
255    case DXGI_FORMAT_R8G8B8A8_UINT:
256    case DXGI_FORMAT_R8G8B8A8_SNORM:
257    case DXGI_FORMAT_R8G8B8A8_SINT:
258    case DXGI_FORMAT_A8_UNORM:
259    case DXGI_FORMAT_BC1_TYPELESS:
260    case DXGI_FORMAT_BC1_UNORM:
261    case DXGI_FORMAT_BC1_UNORM_SRGB:
262    case DXGI_FORMAT_BC2_TYPELESS:
263    case DXGI_FORMAT_BC2_UNORM:
264    case DXGI_FORMAT_BC2_UNORM_SRGB:
265    case DXGI_FORMAT_BC3_TYPELESS:
266    case DXGI_FORMAT_BC3_UNORM:
267    case DXGI_FORMAT_BC3_UNORM_SRGB:
268    case DXGI_FORMAT_B5G5R5A1_UNORM:
269    case DXGI_FORMAT_B8G8R8A8_UNORM:
270    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:
271    case DXGI_FORMAT_B8G8R8A8_TYPELESS:
272    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:
273    case DXGI_FORMAT_BC7_TYPELESS:
274    case DXGI_FORMAT_BC7_UNORM:
275    case DXGI_FORMAT_BC7_UNORM_SRGB:
276    case DXGI_FORMAT_AYUV:
277    case DXGI_FORMAT_Y410:
278    case DXGI_FORMAT_Y416:
279    case DXGI_FORMAT_AI44:
280    case DXGI_FORMAT_IA44:
281    case DXGI_FORMAT_A8P8:
282    case DXGI_FORMAT_B4G4R4A4_UNORM:
283        return true;
284
285    case 116 /* DXGI_FORMAT_R10G10B10_7E3_A2_FLOAT */:
286    case 117 /* DXGI_FORMAT_R10G10B10_6E4_A2_FLOAT */:
287        // These are Xbox One platform specific types
288        return true;
289
290    default:
291        return false;
292    }
293}
294
295_Use_decl_annotations_
296inline size_t __cdecl ComputeScanlines(DXGI_FORMAT fmt, size_t height)
297{
298    if ( IsCompressed(fmt) )
299    {
300        return std::max<size_t>( 1, (height + 3) / 4 );
301    }
302    else if ( fmt == DXGI_FORMAT_NV11 )
303    {
304        // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
305        return height * 2;
306    }
307    else if ( IsPlanar(fmt) )
308    {
309        return height + ( ( height + 1 ) >> 1 );
310    }
311    else
312    {
313        return height;
314    }
315}
316
317//=====================================================================================
318// Image I/O
319//=====================================================================================
320_Use_decl_annotations_
321inline HRESULT __cdecl SaveToDDSMemory(const Image& image, DWORD flags, Blob& blob)
322{
323    TexMetadata mdata;
324    memset( &mdata, 0, sizeof(mdata) );
325    mdata.width = image.width;
326    mdata.height = image.height;
327    mdata.depth = 1;
328    mdata.arraySize = 1;
329    mdata.mipLevels = 1;
330    mdata.format = image.format;
331    mdata.dimension = TEX_DIMENSION_TEXTURE2D;
332
333    return SaveToDDSMemory( &image, 1, mdata, flags, blob );
334}
335
336_Use_decl_annotations_
337inline HRESULT __cdecl SaveToDDSFile(const Image& image, DWORD flags, LPCWSTR szFile)
338{
339    TexMetadata mdata;
340    memset( &mdata, 0, sizeof(mdata) );
341    mdata.width = image.width;
342    mdata.height = image.height;
343    mdata.depth = 1;
344    mdata.arraySize = 1;
345    mdata.mipLevels = 1;
346    mdata.format = image.format;
347    mdata.dimension = TEX_DIMENSION_TEXTURE2D;
348
349    return SaveToDDSFile( &image, 1, mdata, flags, szFile );
350}
351