xref: /aosp_15_r20/external/mesa3d/src/gallium/drivers/d3d12/d3d12_format.c (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © Microsoft Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21  * IN THE SOFTWARE.
22  */
23 
24 #include "d3d12_format.h"
25 
26 #include "util/format/u_formats.h"
27 #include "pipe/p_video_enums.h"
28 #include "util/format/u_format.h"
29 #include "util/u_math.h"
30 #include "util/compiler.h"
31 
32 #define MAP_FORMAT_YUV(NAME) \
33    [PIPE_FORMAT_ ## NAME] = DXGI_FORMAT_ ## NAME,
34 #define MAP_FORMAT_NO_TYPELESS(BITS, TYPE) \
35    [PIPE_FORMAT_ ## BITS ## _ ## TYPE] = DXGI_FORMAT_ ## BITS ## _ ## TYPE,
36 #define MAP_FORMAT2_NO_TYPELESS(BITS1, TYPE1, BITS2, TYPE2) \
37    [PIPE_FORMAT_ ## BITS1 ## _ ## TYPE1] = DXGI_FORMAT_ ## BITS2 ## _ ## TYPE2,
38 
39 #define MAP_FORMAT(BITS, TYPE) MAP_FORMAT_NO_TYPELESS(BITS, TYPE)
40 #define MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPE2) \
41    MAP_FORMAT2_NO_TYPELESS(BITS1, TYPE1, BITS2, TYPE2)
42 
43 #define MAP_FORMAT_CUSTOM_TYPELESS(BITS, TYPE, TYPELESS_BITS) \
44    MAP_FORMAT(BITS, TYPE)
45 #define MAP_FORMAT2_CUSTOM_TYPELESS(BITS1, TYPE1, BITS2, TYPE2) \
46    MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPE2)
47 
48 #define MAP_FORMAT_NORM(FMT) \
49    MAP_FORMAT(FMT, UNORM) \
50    MAP_FORMAT(FMT, SNORM)
51 
52 #define MAP_FORMAT_INT(FMT) \
53    MAP_FORMAT(FMT, UINT) \
54    MAP_FORMAT(FMT, SINT)
55 
56 #define MAP_FORMAT_SRGB(FMT) \
57    MAP_FORMAT2(FMT, SRGB, FMT, UNORM_SRGB)
58 
59 #define MAP_FORMAT_FLOAT(FMT) \
60    MAP_FORMAT(FMT, FLOAT)
61 
62 #define MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) \
63    MAP_FORMAT2(L ## BITS, TYPE, R ## BITS, TYPE) \
64    MAP_FORMAT2(I ## BITS, TYPE, R ## BITS, TYPE) \
65    MAP_FORMAT2(L ## BITS ## A ## BITS, TYPE, R ## BITS ## G ## BITS, TYPE)
66 
67 #define MAP_EMU_FORMAT(BITS, TYPE) \
68    MAP_FORMAT2(A ## BITS, TYPE, R ## BITS, TYPE) \
69    MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE)
70 
71 #define MAP_FORMAT_X8(BITS, TYPE) \
72    MAP_FORMAT2(BITS ## X8, TYPE, BITS ## A8, TYPE) \
73 
74 #define FORMAT_TABLE() \
75    MAP_FORMAT_NORM(R8) \
76    MAP_FORMAT_INT(R8) \
77 \
78    MAP_FORMAT_NORM(R8G8) \
79    MAP_FORMAT_INT(R8G8) \
80 \
81    MAP_FORMAT_NORM(R8G8B8A8) \
82    MAP_FORMAT_INT(R8G8B8A8) \
83    MAP_FORMAT_SRGB(R8G8B8A8) \
84 \
85    /* We can rely on st/mesa to force the alpha to 1 for these, so we can \
86     * just use RGBA. This is needed to support RGB configs, since some apps \
87     * will only choose RGB (not RGBA) configs. \
88     */ \
89    MAP_FORMAT_X8(R8G8B8, UNORM) \
90    MAP_FORMAT_X8(R8G8B8, SNORM) \
91    MAP_FORMAT_X8(R8G8B8, UINT) \
92    MAP_FORMAT_X8(R8G8B8, SINT) \
93 \
94    MAP_FORMAT(B8G8R8X8, UNORM) \
95    MAP_FORMAT(B8G8R8A8, UNORM) \
96 \
97    MAP_FORMAT_SRGB(B8G8R8A8) \
98 \
99    MAP_FORMAT_INT(R32) \
100    MAP_FORMAT_FLOAT(R32) \
101    MAP_FORMAT_INT(R32G32) \
102    MAP_FORMAT_FLOAT(R32G32) \
103    MAP_FORMAT_INT(R32G32B32) \
104    MAP_FORMAT_FLOAT(R32G32B32) \
105    MAP_FORMAT_INT(R32G32B32A32) \
106    MAP_FORMAT_FLOAT(R32G32B32A32) \
107 \
108    MAP_FORMAT_NORM(R16) \
109    MAP_FORMAT_INT(R16) \
110    MAP_FORMAT_FLOAT(R16) \
111 \
112    MAP_FORMAT_NORM(R16G16) \
113    MAP_FORMAT_INT(R16G16) \
114    MAP_FORMAT_FLOAT(R16G16) \
115 \
116    MAP_FORMAT_NORM(R16G16B16A16) \
117    MAP_FORMAT_INT(R16G16B16A16) \
118    MAP_FORMAT_FLOAT(R16G16B16A16) \
119 \
120    MAP_FORMAT_NO_TYPELESS(A8, UNORM) \
121    MAP_EMU_FORMAT_NO_ALPHA(8, UNORM) \
122    MAP_EMU_FORMAT(8, SNORM) \
123    MAP_EMU_FORMAT(8, SINT) \
124    MAP_EMU_FORMAT(8, UINT) \
125    MAP_EMU_FORMAT(16, UNORM) \
126    MAP_EMU_FORMAT(16, SNORM) \
127    MAP_EMU_FORMAT(16, SINT) \
128    MAP_EMU_FORMAT(16, UINT) \
129    MAP_EMU_FORMAT(16, FLOAT) \
130    MAP_EMU_FORMAT(32, SINT) \
131    MAP_EMU_FORMAT(32, UINT) \
132    MAP_EMU_FORMAT(32, FLOAT) \
133 \
134    MAP_FORMAT2_NO_TYPELESS(R9G9B9E5, FLOAT, R9G9B9E5, SHAREDEXP) \
135    MAP_FORMAT_NO_TYPELESS(R11G11B10, FLOAT) \
136    MAP_FORMAT(R10G10B10A2, UINT) \
137    MAP_FORMAT(R10G10B10A2, UNORM) \
138 \
139    MAP_FORMAT_NO_TYPELESS(B5G6R5, UNORM) \
140    MAP_FORMAT_NO_TYPELESS(B5G5R5A1, UNORM) \
141    MAP_FORMAT2_NO_TYPELESS(B5G5R5X1, UNORM, B5G5R5A1, UNORM) \
142 \
143    MAP_FORMAT_NO_TYPELESS(B4G4R4A4, UNORM) \
144 \
145    MAP_FORMAT2(DXT1, RGB, BC1, UNORM) \
146    MAP_FORMAT2(DXT1, RGBA, BC1, UNORM) \
147    MAP_FORMAT2(DXT3, RGBA, BC2, UNORM) \
148    MAP_FORMAT2(DXT5, RGBA, BC3, UNORM) \
149 \
150    MAP_FORMAT2(DXT1, SRGB, BC1, UNORM_SRGB) \
151    MAP_FORMAT2(DXT1, SRGBA, BC1, UNORM_SRGB) \
152    MAP_FORMAT2(DXT3, SRGBA, BC2, UNORM_SRGB) \
153    MAP_FORMAT2(DXT5, SRGBA, BC3, UNORM_SRGB) \
154 \
155    MAP_FORMAT2(RGTC1, UNORM, BC4, UNORM) \
156    MAP_FORMAT2(RGTC1, SNORM, BC4, SNORM) \
157    MAP_FORMAT2(RGTC2, UNORM, BC5, UNORM) \
158    MAP_FORMAT2(RGTC2, SNORM, BC5, SNORM) \
159 \
160    MAP_FORMAT2(BPTC, RGBA_UNORM, BC7, UNORM) \
161    MAP_FORMAT2(BPTC, SRGBA, BC7, UNORM_SRGB) \
162    MAP_FORMAT2(BPTC, RGB_FLOAT, BC6H, SF16) \
163    MAP_FORMAT2(BPTC, RGB_UFLOAT, BC6H, UF16) \
164 \
165    MAP_FORMAT2(Z32, FLOAT, R32, TYPELESS) \
166    MAP_FORMAT2(Z16, UNORM, R16, TYPELESS) \
167    MAP_FORMAT2(Z24X8, UNORM, R24G8, TYPELESS) \
168    MAP_FORMAT2(X24S8, UINT, R24G8, TYPELESS) \
169 \
170    MAP_FORMAT2(Z24_UNORM_S8, UINT, R24G8, TYPELESS) \
171    MAP_FORMAT2(Z32_FLOAT_S8X24, UINT, R32G8X24, TYPELESS) \
172    MAP_FORMAT2(X32_S8X24, UINT, R32G8X24, TYPELESS) \
173 \
174    MAP_FORMAT_YUV(NV12) \
175    MAP_FORMAT_YUV(P010) \
176    MAP_FORMAT_YUV(AYUV)
177 
178 static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
179    FORMAT_TABLE()
180 };
181 
182 #undef MAP_FORMAT
183 #undef MAP_FORMAT2
184 #undef MAP_FORMAT_CUSTOM_TYPELESS
185 #undef MAP_FORMAT2_CUSTOM_TYPELESS
186 
187 #define MAP_FORMAT(BITS, TYPE) \
188    [PIPE_FORMAT_ ## BITS ## _ ## TYPE] = DXGI_FORMAT_ ## BITS ## _TYPELESS,
189 
190 #define MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPE2) \
191    [PIPE_FORMAT_ ## BITS1 ## _ ## TYPE1] = DXGI_FORMAT_ ## BITS2 ## _TYPELESS,
192 
193 #define MAP_FORMAT_CUSTOM_TYPELESS(BITS1, TYPE, BITS2) \
194    MAP_FORMAT2(BITS1, TYPE, BITS2, TYPELESS)
195 
196 #define MAP_FORMAT2_CUSTOM_TYPELESS(BITS1, TYPE1, BITS2, TYPE2) \
197    MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPELESS)
198 
199 static const DXGI_FORMAT typeless_formats[PIPE_FORMAT_COUNT] = {
200    FORMAT_TABLE()
201 };
202 
203 DXGI_FORMAT
d3d12_get_format(enum pipe_format format)204 d3d12_get_format(enum pipe_format format)
205 {
206    return formats[format];
207 }
208 
209 DXGI_FORMAT
d3d12_get_typeless_format(enum pipe_format format)210 d3d12_get_typeless_format(enum pipe_format format)
211 {
212    return typeless_formats[format];
213 }
214 
215 const DXGI_FORMAT cast_table_8bit[] = {
216    DXGI_FORMAT_R8_UINT,
217    DXGI_FORMAT_R8_UNORM,
218    DXGI_FORMAT_R8_SINT,
219    DXGI_FORMAT_R8_SNORM,
220    DXGI_FORMAT_A8_UNORM,
221 };
222 
223 const DXGI_FORMAT cast_table_16bit[] = {
224    DXGI_FORMAT_R8G8_UINT,
225    DXGI_FORMAT_R8G8_UNORM,
226    DXGI_FORMAT_R8G8_SINT,
227    DXGI_FORMAT_R8G8_SNORM,
228    DXGI_FORMAT_R16_UINT,
229    DXGI_FORMAT_R16_UNORM,
230    DXGI_FORMAT_R16_SINT,
231    DXGI_FORMAT_R16_SNORM,
232    DXGI_FORMAT_R16_FLOAT,
233 };
234 
235 const DXGI_FORMAT cast_table_32bit[] = {
236    DXGI_FORMAT_R8G8B8A8_UINT,
237    DXGI_FORMAT_R8G8B8A8_UNORM,
238    DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
239    DXGI_FORMAT_R8G8B8A8_SINT,
240    DXGI_FORMAT_R8G8B8A8_SNORM,
241    DXGI_FORMAT_B8G8R8A8_UNORM,
242    DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
243    DXGI_FORMAT_B8G8R8X8_UNORM,
244    DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
245    DXGI_FORMAT_R16G16_UINT,
246    DXGI_FORMAT_R16G16_UNORM,
247    DXGI_FORMAT_R16G16_SINT,
248    DXGI_FORMAT_R16G16_SNORM,
249    DXGI_FORMAT_R16G16_FLOAT,
250    DXGI_FORMAT_R32_UINT,
251    DXGI_FORMAT_R32_SINT,
252    DXGI_FORMAT_R32_FLOAT,
253    DXGI_FORMAT_D32_FLOAT,
254    DXGI_FORMAT_R11G11B10_FLOAT,
255    DXGI_FORMAT_R10G10B10A2_UINT,
256    DXGI_FORMAT_R10G10B10A2_UNORM,
257    DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
258 };
259 
260 const DXGI_FORMAT cast_table_64bit[] = {
261    DXGI_FORMAT_R16G16B16A16_UINT,
262    DXGI_FORMAT_R16G16B16A16_UNORM,
263    DXGI_FORMAT_R16G16B16A16_SINT,
264    DXGI_FORMAT_R16G16B16A16_SNORM,
265    DXGI_FORMAT_R16G16B16A16_FLOAT,
266    DXGI_FORMAT_R32G32_UINT,
267    DXGI_FORMAT_R32G32_SINT,
268    DXGI_FORMAT_R32G32_FLOAT,
269 };
270 
271 const DXGI_FORMAT cast_table_96bit[] = {
272    DXGI_FORMAT_R32G32B32_UINT,
273    DXGI_FORMAT_R32G32B32_SINT,
274    DXGI_FORMAT_R32G32B32_FLOAT,
275 };
276 
277 const DXGI_FORMAT cast_table_128bit[] = {
278    DXGI_FORMAT_R32G32B32A32_UINT,
279    DXGI_FORMAT_R32G32B32A32_SINT,
280    DXGI_FORMAT_R32G32B32A32_FLOAT,
281 };
282 
283 const DXGI_FORMAT cast_table_bc1[] = {
284    DXGI_FORMAT_BC1_UNORM,
285    DXGI_FORMAT_BC1_UNORM_SRGB,
286 };
287 
288 const DXGI_FORMAT cast_table_bc2[] = {
289    DXGI_FORMAT_BC2_UNORM,
290    DXGI_FORMAT_BC2_UNORM_SRGB,
291 };
292 
293 const DXGI_FORMAT cast_table_bc3[] = {
294    DXGI_FORMAT_BC3_UNORM,
295    DXGI_FORMAT_BC3_UNORM_SRGB,
296 };
297 
298 const DXGI_FORMAT cast_table_bc4[] = {
299    DXGI_FORMAT_BC4_SNORM,
300    DXGI_FORMAT_BC4_UNORM,
301 };
302 
303 const DXGI_FORMAT cast_table_bc5[] = {
304    DXGI_FORMAT_BC5_SNORM,
305    DXGI_FORMAT_BC5_UNORM,
306 };
307 
308 const DXGI_FORMAT cast_table_bc6[] = {
309    DXGI_FORMAT_BC6H_SF16,
310    DXGI_FORMAT_BC6H_UF16,
311 };
312 
313 const DXGI_FORMAT cast_table_bc7[] = {
314    DXGI_FORMAT_BC7_UNORM,
315    DXGI_FORMAT_BC7_UNORM_SRGB,
316 };
317 
318 const DXGI_FORMAT *
d3d12_get_format_cast_list(enum pipe_format format,uint32_t * num_formats)319 d3d12_get_format_cast_list(enum pipe_format format, uint32_t *num_formats)
320 {
321    const struct util_format_description *format_desc = util_format_description(format);
322    if (util_format_has_depth(format_desc) || util_format_has_stencil(format_desc) || util_format_is_yuv(format))
323       return NULL;
324 
325 #define RET(table) *num_formats = ARRAY_SIZE(table); return table;
326    switch (format) {
327    case PIPE_FORMAT_DXT1_RGB:
328    case PIPE_FORMAT_DXT1_SRGB:
329    case PIPE_FORMAT_DXT1_RGBA:
330    case PIPE_FORMAT_DXT1_SRGBA:
331       RET(cast_table_bc1);
332    case PIPE_FORMAT_DXT3_RGBA:
333    case PIPE_FORMAT_DXT3_SRGBA:
334       RET(cast_table_bc2);
335    case PIPE_FORMAT_DXT5_RGBA:
336    case PIPE_FORMAT_DXT5_SRGBA:
337       RET(cast_table_bc3);
338    case PIPE_FORMAT_RGTC1_SNORM:
339    case PIPE_FORMAT_RGTC1_UNORM:
340       RET(cast_table_bc4);
341    case PIPE_FORMAT_RGTC2_SNORM:
342    case PIPE_FORMAT_RGTC2_UNORM:
343       RET(cast_table_bc5);
344    case PIPE_FORMAT_BPTC_RGBA_UNORM:
345    case PIPE_FORMAT_BPTC_SRGBA:
346       RET(cast_table_bc7);
347    case PIPE_FORMAT_BPTC_RGB_UFLOAT:
348    case PIPE_FORMAT_BPTC_RGB_FLOAT:
349       RET(cast_table_bc6);
350    default:
351       break;
352    }
353    switch (util_format_get_blocksizebits(format)) {
354    case 8: RET(cast_table_8bit);
355    case 16: RET(cast_table_16bit);
356    case 32: RET(cast_table_32bit);
357    case 64: RET(cast_table_64bit);
358    case 96: RET(cast_table_96bit);
359    case 128: RET(cast_table_128bit);
360    }
361    return NULL;
362 }
363 
364 enum pipe_format
d3d12_get_pipe_format(DXGI_FORMAT format)365 d3d12_get_pipe_format(DXGI_FORMAT format)
366 {
367    for (unsigned i = 0; i < ARRAY_SIZE(formats); ++i) {
368       if (formats[i] == format) {
369          return (enum pipe_format)i;
370       }
371    }
372    return PIPE_FORMAT_NONE;
373 }
374 
375 enum pipe_format
d3d12_get_default_pipe_format(DXGI_FORMAT format)376 d3d12_get_default_pipe_format(DXGI_FORMAT format)
377 {
378 #define TYPELESS_TO(channels, suffix) \
379    case DXGI_FORMAT_##channels##_TYPELESS: \
380       return PIPE_FORMAT_##channels##_##suffix
381 
382    switch (format) {
383       TYPELESS_TO(R8, UNORM);
384       TYPELESS_TO(R8G8, UNORM);
385       TYPELESS_TO(R8G8B8A8, UNORM);
386       TYPELESS_TO(B8G8R8X8, UNORM);
387       TYPELESS_TO(B8G8R8A8, UNORM);
388       TYPELESS_TO(R16, FLOAT);
389       TYPELESS_TO(R16G16, FLOAT);
390       TYPELESS_TO(R16G16B16A16, FLOAT);
391       TYPELESS_TO(R32, FLOAT);
392       TYPELESS_TO(R32G32, FLOAT);
393       TYPELESS_TO(R32G32B32, FLOAT);
394       TYPELESS_TO(R32G32B32A32, FLOAT);
395    case DXGI_FORMAT_BC1_TYPELESS:
396       return PIPE_FORMAT_DXT1_RGBA;
397    case DXGI_FORMAT_BC2_TYPELESS:
398       return PIPE_FORMAT_DXT3_RGBA;
399    case DXGI_FORMAT_BC3_TYPELESS:
400       return PIPE_FORMAT_DXT5_RGBA;
401    case DXGI_FORMAT_BC4_TYPELESS:
402       return PIPE_FORMAT_RGTC1_UNORM;
403    case DXGI_FORMAT_BC5_TYPELESS:
404       return PIPE_FORMAT_RGTC2_UNORM;
405    case DXGI_FORMAT_BC6H_TYPELESS:
406       return PIPE_FORMAT_BPTC_RGB_FLOAT;
407    case DXGI_FORMAT_BC7_TYPELESS:
408       return PIPE_FORMAT_BPTC_RGBA_UNORM;
409    default:
410       return PIPE_FORMAT_NONE;
411    }
412 }
413 
414 DXGI_FORMAT
d3d12_get_resource_rt_format(enum pipe_format f)415 d3d12_get_resource_rt_format(enum pipe_format f)
416 {
417    switch (f) {
418    case PIPE_FORMAT_Z16_UNORM:
419       return DXGI_FORMAT_D16_UNORM;
420    case PIPE_FORMAT_Z32_FLOAT:
421       return DXGI_FORMAT_D32_FLOAT;
422    case PIPE_FORMAT_Z24X8_UNORM:
423    case PIPE_FORMAT_X24S8_UINT:
424       return DXGI_FORMAT_D24_UNORM_S8_UINT;
425    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
426    case PIPE_FORMAT_X32_S8X24_UINT:
427       return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
428    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
429       return DXGI_FORMAT_D24_UNORM_S8_UINT;
430    default:
431       return d3d12_get_format(f);
432    }
433 }
434 
435 DXGI_FORMAT
d3d12_get_resource_srv_format(enum pipe_format f,enum pipe_texture_target target)436 d3d12_get_resource_srv_format(enum pipe_format f, enum pipe_texture_target target)
437 {
438    switch (f) {
439    case PIPE_FORMAT_Z16_UNORM:
440       return DXGI_FORMAT_R16_UNORM;
441    case PIPE_FORMAT_Z32_FLOAT:
442       return DXGI_FORMAT_R32_FLOAT;
443    case PIPE_FORMAT_Z24X8_UNORM:
444    case PIPE_FORMAT_Z24_UNORM_S8_UINT:
445       return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
446    case PIPE_FORMAT_X24S8_UINT:
447       return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
448    case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
449       return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
450    case PIPE_FORMAT_X32_S8X24_UINT:
451       return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
452    case PIPE_FORMAT_A8_UNORM:
453       if (target == PIPE_BUFFER)
454          return DXGI_FORMAT_R8_UNORM; /* A8_UNORM is not supported for buffer SRV */
455       FALLTHROUGH;
456    default:
457       return d3d12_get_format(f);
458    }
459 }
460 
461 #define DEF_SWIZZLE(name, X, Y, Z, W) \
462    static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \
463       { PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \
464         PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE }
465 
466 struct d3d12_format_info
d3d12_get_format_info(enum pipe_format resource_format,enum pipe_format pformat,enum pipe_texture_target target)467 d3d12_get_format_info(enum pipe_format resource_format, enum pipe_format pformat, enum pipe_texture_target target)
468 {
469    DEF_SWIZZLE(IDENTITY, X, Y, Z, W);
470    DEF_SWIZZLE(RGB1, X, Y, Z, 1);
471    DEF_SWIZZLE(ALPHA, 0, 0, 0, W);
472    DEF_SWIZZLE(BUFFER, 0, 0, 0, X);
473    DEF_SWIZZLE(INTENSITY, X, X, X, X);
474    DEF_SWIZZLE(LUMINANCE, X, X, X, 1);
475    DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y);
476    DEF_SWIZZLE(DEPTH, X, X, X, X);
477    DEF_SWIZZLE(STENCIL, Y, Y, Y, Y);
478 
479    const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE;
480    unsigned plane_slice = 0;
481 
482    if (pformat == PIPE_FORMAT_DXT1_RGB ||
483        pformat == PIPE_FORMAT_DXT1_SRGB)
484       swizzle = RGB1_SWIZZLE;
485 
486    const struct util_format_description
487       *format_desc = util_format_description(pformat);
488    unsigned plane_count = util_format_get_num_planes(resource_format);
489    if (!util_format_is_srgb(pformat)) {
490       if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) {
491          swizzle = BUFFER_SWIZZLE;
492       } else if (plane_count > 1) {
493          for (plane_slice = 0; plane_slice < plane_count; ++plane_slice) {
494             if (util_format_get_plane_format(resource_format, plane_slice) == pformat)
495                break;
496          }
497          assert(plane_slice < plane_count);
498       } else if (pformat == PIPE_FORMAT_A8_UNORM) {
499          /* no need to swizzle, it's natively supported */
500       } else if (util_format_is_intensity(pformat)) {
501          swizzle = INTENSITY_SWIZZLE;
502       } else if (util_format_is_luminance(pformat)) {
503          swizzle = LUMINANCE_SWIZZLE;
504       } else if (util_format_is_luminance_alpha(pformat)) {
505          swizzle = LUMINANCE_ALPHA_SWIZZLE;
506       } else if (util_format_is_alpha(pformat)) {
507          swizzle = ALPHA_SWIZZLE;
508       } else if (util_format_has_depth(format_desc)) {
509          swizzle = DEPTH_SWIZZLE;
510       } else if (util_format_has_stencil(format_desc)) {
511          /* When reading from a stencil texture we have to use plane 1, and
512           * the formats X24S8 and X32_S8X24 have the actual data in the y-channel
513           * but the shader will read the x component so we need to adjust the swizzle. */
514          plane_slice = 1;
515          swizzle = STENCIL_SWIZZLE;
516       } else if (util_format_has_alpha1(pformat)) {
517          swizzle = RGB1_SWIZZLE;
518       }
519    }
520 
521    return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice };
522 }
523 
524 enum pipe_format
d3d12_emulated_vtx_format(enum pipe_format fmt)525 d3d12_emulated_vtx_format(enum pipe_format fmt)
526 {
527    switch (fmt) {
528    case PIPE_FORMAT_R10G10B10A2_SNORM:
529    case PIPE_FORMAT_R10G10B10A2_SSCALED:
530    case PIPE_FORMAT_R10G10B10A2_USCALED:
531    case PIPE_FORMAT_B10G10R10A2_UNORM:
532    case PIPE_FORMAT_B10G10R10A2_SNORM:
533    case PIPE_FORMAT_B10G10R10A2_SSCALED:
534    case PIPE_FORMAT_B10G10R10A2_USCALED:
535       return PIPE_FORMAT_R32_UINT;
536 
537    case PIPE_FORMAT_R8G8B8_SINT:
538       return PIPE_FORMAT_R8G8B8A8_SINT;
539    case PIPE_FORMAT_R8G8B8_UINT:
540       return PIPE_FORMAT_R8G8B8A8_UINT;
541 
542    case PIPE_FORMAT_R16G16B16_SINT:
543       return PIPE_FORMAT_R16G16B16A16_SINT;
544    case PIPE_FORMAT_R16G16B16_UINT:
545       return PIPE_FORMAT_R16G16B16A16_UINT;
546 
547    case PIPE_FORMAT_R8G8B8A8_SSCALED:
548       return PIPE_FORMAT_R8G8B8A8_SINT;
549    case PIPE_FORMAT_R8G8B8A8_USCALED:
550       return PIPE_FORMAT_R8G8B8A8_UINT;
551    case PIPE_FORMAT_R16G16B16A16_SSCALED:
552       return PIPE_FORMAT_R16G16B16A16_SINT;
553    case PIPE_FORMAT_R16G16B16A16_USCALED:
554       return PIPE_FORMAT_R16G16B16A16_UINT;
555 
556    default:
557       return fmt;
558    }
559 }
560 
561 
562 unsigned
d3d12_non_opaque_plane_count(DXGI_FORMAT format)563 d3d12_non_opaque_plane_count(DXGI_FORMAT format)
564 {
565    switch (format) {
566    case DXGI_FORMAT_V208:
567    case DXGI_FORMAT_V408:
568       return 3;
569 
570    case DXGI_FORMAT_NV12:
571    case DXGI_FORMAT_P010:
572    case DXGI_FORMAT_P016:
573    case DXGI_FORMAT_YUY2:
574    case DXGI_FORMAT_Y210:
575    case DXGI_FORMAT_Y216:
576    case DXGI_FORMAT_NV11:
577       return 2;
578 
579    case DXGI_FORMAT_R24G8_TYPELESS:
580    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
581    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
582    case DXGI_FORMAT_D24_UNORM_S8_UINT:
583    case DXGI_FORMAT_R32G8X24_TYPELESS:
584    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
585    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
586    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
587       return 2;
588 
589    default:
590       return 1;
591    }
592 }
593 
594 unsigned
d3d12_get_format_start_plane(enum pipe_format fmt)595 d3d12_get_format_start_plane(enum pipe_format fmt)
596 {
597    const struct util_format_description *desc = util_format_description(fmt);
598    if (util_format_has_stencil(desc) && !util_format_has_depth(desc))
599       return 1;
600 
601    return 0;
602 }
603 
604 unsigned
d3d12_get_format_num_planes(enum pipe_format fmt)605 d3d12_get_format_num_planes(enum pipe_format fmt)
606 {
607    return util_format_is_depth_or_stencil(fmt) ?
608       util_bitcount(util_format_get_mask(fmt)) : 1;
609 }
610 
611 DXGI_FORMAT
d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)612 d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)
613 {
614    switch (profile) {
615       case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
616       case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
617       case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
618       case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
619       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
620       case PIPE_VIDEO_PROFILE_HEVC_MAIN:
621       case PIPE_VIDEO_PROFILE_AV1_MAIN:
622       case PIPE_VIDEO_PROFILE_VP9_PROFILE0:
623          return DXGI_FORMAT_NV12;
624       case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
625       case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
626       case PIPE_VIDEO_PROFILE_VP9_PROFILE2:
627          return DXGI_FORMAT_P010;
628       case PIPE_VIDEO_PROFILE_HEVC_MAIN_444:
629          return DXGI_FORMAT_AYUV;
630       default:
631       {
632          unreachable("Unsupported pipe video profile");
633       } break;
634    }
635 }
636 
637 DXGI_COLOR_SPACE_TYPE
d3d12_convert_from_legacy_color_space(bool rgb,uint32_t bits_per_element,bool studio_rgb,bool p709,bool studio_yuv)638 d3d12_convert_from_legacy_color_space(bool rgb, uint32_t bits_per_element, bool studio_rgb, bool p709, bool studio_yuv)
639 {
640    if (rgb) {
641       if (bits_per_element > 32) {
642          // All 16 bit color channel data is assumed to be linear rather than SRGB
643          return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
644       } else {
645          if (studio_rgb) {
646             return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
647          } else {
648             return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
649          }
650       }
651    } else {
652       if (p709) {
653          if (studio_yuv) {
654             return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
655          } else {
656             return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
657          }
658       } else {
659          if (studio_yuv) {
660             return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
661          } else {
662             return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
663          }
664       }
665    }
666 }
667