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
177 static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {
178 FORMAT_TABLE()
179 };
180
181 #undef MAP_FORMAT
182 #undef MAP_FORMAT2
183 #undef MAP_FORMAT_CUSTOM_TYPELESS
184 #undef MAP_FORMAT2_CUSTOM_TYPELESS
185
186 #define MAP_FORMAT(BITS, TYPE) \
187 [PIPE_FORMAT_ ## BITS ## _ ## TYPE] = DXGI_FORMAT_ ## BITS ## _TYPELESS,
188
189 #define MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPE2) \
190 [PIPE_FORMAT_ ## BITS1 ## _ ## TYPE1] = DXGI_FORMAT_ ## BITS2 ## _TYPELESS,
191
192 #define MAP_FORMAT_CUSTOM_TYPELESS(BITS1, TYPE, BITS2) \
193 MAP_FORMAT2(BITS1, TYPE, BITS2, TYPELESS)
194
195 #define MAP_FORMAT2_CUSTOM_TYPELESS(BITS1, TYPE1, BITS2, TYPE2) \
196 MAP_FORMAT2(BITS1, TYPE1, BITS2, TYPELESS)
197
198 static const DXGI_FORMAT typeless_formats[PIPE_FORMAT_COUNT] = {
199 FORMAT_TABLE()
200 };
201
202 DXGI_FORMAT
d3d12_get_format(enum pipe_format format)203 d3d12_get_format(enum pipe_format format)
204 {
205 return formats[format];
206 }
207
208 DXGI_FORMAT
d3d12_get_typeless_format(enum pipe_format format)209 d3d12_get_typeless_format(enum pipe_format format)
210 {
211 return typeless_formats[format];
212 }
213
214 const DXGI_FORMAT cast_table_8bit[] = {
215 DXGI_FORMAT_R8_UINT,
216 DXGI_FORMAT_R8_UNORM,
217 DXGI_FORMAT_R8_SINT,
218 DXGI_FORMAT_R8_SNORM,
219 DXGI_FORMAT_A8_UNORM,
220 };
221
222 const DXGI_FORMAT cast_table_16bit[] = {
223 DXGI_FORMAT_R8G8_UINT,
224 DXGI_FORMAT_R8G8_UNORM,
225 DXGI_FORMAT_R8G8_SINT,
226 DXGI_FORMAT_R8G8_SNORM,
227 DXGI_FORMAT_R16_UINT,
228 DXGI_FORMAT_R16_UNORM,
229 DXGI_FORMAT_R16_SINT,
230 DXGI_FORMAT_R16_SNORM,
231 DXGI_FORMAT_R16_FLOAT,
232 };
233
234 const DXGI_FORMAT cast_table_32bit[] = {
235 DXGI_FORMAT_R8G8B8A8_UINT,
236 DXGI_FORMAT_R8G8B8A8_UNORM,
237 DXGI_FORMAT_R8G8B8A8_UNORM_SRGB,
238 DXGI_FORMAT_R8G8B8A8_SINT,
239 DXGI_FORMAT_R8G8B8A8_SNORM,
240 DXGI_FORMAT_B8G8R8A8_UNORM,
241 DXGI_FORMAT_B8G8R8A8_UNORM_SRGB,
242 DXGI_FORMAT_B8G8R8X8_UNORM,
243 DXGI_FORMAT_B8G8R8X8_UNORM_SRGB,
244 DXGI_FORMAT_R16G16_UINT,
245 DXGI_FORMAT_R16G16_UNORM,
246 DXGI_FORMAT_R16G16_SINT,
247 DXGI_FORMAT_R16G16_SNORM,
248 DXGI_FORMAT_R16G16_FLOAT,
249 DXGI_FORMAT_R32_UINT,
250 DXGI_FORMAT_R32_SINT,
251 DXGI_FORMAT_R32_FLOAT,
252 DXGI_FORMAT_D32_FLOAT,
253 DXGI_FORMAT_R11G11B10_FLOAT,
254 DXGI_FORMAT_R10G10B10A2_UINT,
255 DXGI_FORMAT_R10G10B10A2_UNORM,
256 DXGI_FORMAT_R9G9B9E5_SHAREDEXP,
257 };
258
259 const DXGI_FORMAT cast_table_64bit[] = {
260 DXGI_FORMAT_R16G16B16A16_UINT,
261 DXGI_FORMAT_R16G16B16A16_UNORM,
262 DXGI_FORMAT_R16G16B16A16_SINT,
263 DXGI_FORMAT_R16G16B16A16_SNORM,
264 DXGI_FORMAT_R16G16B16A16_FLOAT,
265 DXGI_FORMAT_R32G32_UINT,
266 DXGI_FORMAT_R32G32_SINT,
267 DXGI_FORMAT_R32G32_FLOAT,
268 };
269
270 const DXGI_FORMAT cast_table_96bit[] = {
271 DXGI_FORMAT_R32G32B32_UINT,
272 DXGI_FORMAT_R32G32B32_SINT,
273 DXGI_FORMAT_R32G32B32_FLOAT,
274 };
275
276 const DXGI_FORMAT cast_table_128bit[] = {
277 DXGI_FORMAT_R32G32B32A32_UINT,
278 DXGI_FORMAT_R32G32B32A32_SINT,
279 DXGI_FORMAT_R32G32B32A32_FLOAT,
280 };
281
282 const DXGI_FORMAT cast_table_bc1[] = {
283 DXGI_FORMAT_BC1_UNORM,
284 DXGI_FORMAT_BC1_UNORM_SRGB,
285 };
286
287 const DXGI_FORMAT cast_table_bc2[] = {
288 DXGI_FORMAT_BC2_UNORM,
289 DXGI_FORMAT_BC2_UNORM_SRGB,
290 };
291
292 const DXGI_FORMAT cast_table_bc3[] = {
293 DXGI_FORMAT_BC3_UNORM,
294 DXGI_FORMAT_BC3_UNORM_SRGB,
295 };
296
297 const DXGI_FORMAT cast_table_bc4[] = {
298 DXGI_FORMAT_BC4_SNORM,
299 DXGI_FORMAT_BC4_UNORM,
300 };
301
302 const DXGI_FORMAT cast_table_bc5[] = {
303 DXGI_FORMAT_BC5_SNORM,
304 DXGI_FORMAT_BC5_UNORM,
305 };
306
307 const DXGI_FORMAT cast_table_bc6[] = {
308 DXGI_FORMAT_BC6H_SF16,
309 DXGI_FORMAT_BC6H_UF16,
310 };
311
312 const DXGI_FORMAT cast_table_bc7[] = {
313 DXGI_FORMAT_BC7_UNORM,
314 DXGI_FORMAT_BC7_UNORM_SRGB,
315 };
316
317 const DXGI_FORMAT *
d3d12_get_format_cast_list(enum pipe_format format,uint32_t * num_formats)318 d3d12_get_format_cast_list(enum pipe_format format, uint32_t *num_formats)
319 {
320 const struct util_format_description *format_desc = util_format_description(format);
321 if (util_format_has_depth(format_desc) || util_format_has_stencil(format_desc) || util_format_is_yuv(format))
322 return NULL;
323
324 #define RET(table) *num_formats = ARRAY_SIZE(table); return table;
325 switch (format) {
326 case PIPE_FORMAT_DXT1_RGB:
327 case PIPE_FORMAT_DXT1_SRGB:
328 case PIPE_FORMAT_DXT1_RGBA:
329 case PIPE_FORMAT_DXT1_SRGBA:
330 RET(cast_table_bc1);
331 case PIPE_FORMAT_DXT3_RGBA:
332 case PIPE_FORMAT_DXT3_SRGBA:
333 RET(cast_table_bc2);
334 case PIPE_FORMAT_DXT5_RGBA:
335 case PIPE_FORMAT_DXT5_SRGBA:
336 RET(cast_table_bc3);
337 case PIPE_FORMAT_RGTC1_SNORM:
338 case PIPE_FORMAT_RGTC1_UNORM:
339 RET(cast_table_bc4);
340 case PIPE_FORMAT_RGTC2_SNORM:
341 case PIPE_FORMAT_RGTC2_UNORM:
342 RET(cast_table_bc5);
343 case PIPE_FORMAT_BPTC_RGBA_UNORM:
344 case PIPE_FORMAT_BPTC_SRGBA:
345 RET(cast_table_bc7);
346 case PIPE_FORMAT_BPTC_RGB_UFLOAT:
347 case PIPE_FORMAT_BPTC_RGB_FLOAT:
348 RET(cast_table_bc6);
349 default:
350 break;
351 }
352 switch (util_format_get_blocksizebits(format)) {
353 case 8: RET(cast_table_8bit);
354 case 16: RET(cast_table_16bit);
355 case 32: RET(cast_table_32bit);
356 case 64: RET(cast_table_64bit);
357 case 96: RET(cast_table_96bit);
358 case 128: RET(cast_table_128bit);
359 }
360 return NULL;
361 }
362
363 enum pipe_format
d3d12_get_pipe_format(DXGI_FORMAT format)364 d3d12_get_pipe_format(DXGI_FORMAT format)
365 {
366 for (unsigned i = 0; i < ARRAY_SIZE(formats); ++i) {
367 if (formats[i] == format) {
368 return (enum pipe_format)i;
369 }
370 }
371 return PIPE_FORMAT_NONE;
372 }
373
374 enum pipe_format
d3d12_get_default_pipe_format(DXGI_FORMAT format)375 d3d12_get_default_pipe_format(DXGI_FORMAT format)
376 {
377 #define TYPELESS_TO(channels, suffix) \
378 case DXGI_FORMAT_##channels##_TYPELESS: \
379 return PIPE_FORMAT_##channels##_##suffix
380
381 switch (format) {
382 TYPELESS_TO(R8, UNORM);
383 TYPELESS_TO(R8G8, UNORM);
384 TYPELESS_TO(R8G8B8A8, UNORM);
385 TYPELESS_TO(B8G8R8X8, UNORM);
386 TYPELESS_TO(B8G8R8A8, UNORM);
387 TYPELESS_TO(R16, FLOAT);
388 TYPELESS_TO(R16G16, FLOAT);
389 TYPELESS_TO(R16G16B16A16, FLOAT);
390 TYPELESS_TO(R32, FLOAT);
391 TYPELESS_TO(R32G32, FLOAT);
392 TYPELESS_TO(R32G32B32, FLOAT);
393 TYPELESS_TO(R32G32B32A32, FLOAT);
394 case DXGI_FORMAT_BC1_TYPELESS:
395 return PIPE_FORMAT_DXT1_RGBA;
396 case DXGI_FORMAT_BC2_TYPELESS:
397 return PIPE_FORMAT_DXT3_RGBA;
398 case DXGI_FORMAT_BC3_TYPELESS:
399 return PIPE_FORMAT_DXT5_RGBA;
400 case DXGI_FORMAT_BC4_TYPELESS:
401 return PIPE_FORMAT_RGTC1_UNORM;
402 case DXGI_FORMAT_BC5_TYPELESS:
403 return PIPE_FORMAT_RGTC2_UNORM;
404 case DXGI_FORMAT_BC6H_TYPELESS:
405 return PIPE_FORMAT_BPTC_RGB_FLOAT;
406 case DXGI_FORMAT_BC7_TYPELESS:
407 return PIPE_FORMAT_BPTC_RGBA_UNORM;
408 default:
409 return PIPE_FORMAT_NONE;
410 }
411 }
412
413 DXGI_FORMAT
d3d12_get_resource_rt_format(enum pipe_format f)414 d3d12_get_resource_rt_format(enum pipe_format f)
415 {
416 switch (f) {
417 case PIPE_FORMAT_Z16_UNORM:
418 return DXGI_FORMAT_D16_UNORM;
419 case PIPE_FORMAT_Z32_FLOAT:
420 return DXGI_FORMAT_D32_FLOAT;
421 case PIPE_FORMAT_Z24X8_UNORM:
422 case PIPE_FORMAT_X24S8_UINT:
423 return DXGI_FORMAT_D24_UNORM_S8_UINT;
424 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
425 case PIPE_FORMAT_X32_S8X24_UINT:
426 return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
427 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
428 return DXGI_FORMAT_D24_UNORM_S8_UINT;
429 default:
430 return d3d12_get_format(f);
431 }
432 }
433
434 DXGI_FORMAT
d3d12_get_resource_srv_format(enum pipe_format f,enum pipe_texture_target target)435 d3d12_get_resource_srv_format(enum pipe_format f, enum pipe_texture_target target)
436 {
437 switch (f) {
438 case PIPE_FORMAT_Z16_UNORM:
439 return DXGI_FORMAT_R16_UNORM;
440 case PIPE_FORMAT_Z32_FLOAT:
441 return DXGI_FORMAT_R32_FLOAT;
442 case PIPE_FORMAT_Z24X8_UNORM:
443 case PIPE_FORMAT_Z24_UNORM_S8_UINT:
444 return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
445 case PIPE_FORMAT_X24S8_UINT:
446 return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
447 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
448 return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
449 case PIPE_FORMAT_X32_S8X24_UINT:
450 return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
451 case PIPE_FORMAT_A8_UNORM:
452 if (target == PIPE_BUFFER)
453 return DXGI_FORMAT_R8_UNORM; /* A8_UNORM is not supported for buffer SRV */
454 FALLTHROUGH;
455 default:
456 return d3d12_get_format(f);
457 }
458 }
459
460 #define DEF_SWIZZLE(name, X, Y, Z, W) \
461 static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \
462 { PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \
463 PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE }
464
465 struct d3d12_format_info
d3d12_get_format_info(enum pipe_format resource_format,enum pipe_format pformat,enum pipe_texture_target target)466 d3d12_get_format_info(enum pipe_format resource_format, enum pipe_format pformat, enum pipe_texture_target target)
467 {
468 DEF_SWIZZLE(IDENTITY, X, Y, Z, W);
469 DEF_SWIZZLE(RGB1, X, Y, Z, 1);
470 DEF_SWIZZLE(ALPHA, 0, 0, 0, W);
471 DEF_SWIZZLE(BUFFER, 0, 0, 0, X);
472 DEF_SWIZZLE(INTENSITY, X, X, X, X);
473 DEF_SWIZZLE(LUMINANCE, X, X, X, 1);
474 DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y);
475 DEF_SWIZZLE(DEPTH, X, X, X, X);
476 DEF_SWIZZLE(STENCIL, Y, Y, Y, Y);
477
478 const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE;
479 unsigned plane_slice = 0;
480
481 if (pformat == PIPE_FORMAT_DXT1_RGB ||
482 pformat == PIPE_FORMAT_DXT1_SRGB)
483 swizzle = RGB1_SWIZZLE;
484
485 const struct util_format_description
486 *format_desc = util_format_description(pformat);
487 unsigned plane_count = util_format_get_num_planes(resource_format);
488 if (!util_format_is_srgb(pformat)) {
489 if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) {
490 swizzle = BUFFER_SWIZZLE;
491 } else if (plane_count > 1) {
492 for (plane_slice = 0; plane_slice < plane_count; ++plane_slice) {
493 if (util_format_get_plane_format(resource_format, plane_slice) == pformat)
494 break;
495 }
496 assert(plane_slice < plane_count);
497 } else if (pformat == PIPE_FORMAT_A8_UNORM) {
498 /* no need to swizzle, it's natively supported */
499 } else if (util_format_is_intensity(pformat)) {
500 swizzle = INTENSITY_SWIZZLE;
501 } else if (util_format_is_luminance(pformat)) {
502 swizzle = LUMINANCE_SWIZZLE;
503 } else if (util_format_is_luminance_alpha(pformat)) {
504 swizzle = LUMINANCE_ALPHA_SWIZZLE;
505 } else if (util_format_is_alpha(pformat)) {
506 swizzle = ALPHA_SWIZZLE;
507 } else if (util_format_has_depth(format_desc)) {
508 swizzle = DEPTH_SWIZZLE;
509 } else if (util_format_has_stencil(format_desc)) {
510 /* When reading from a stencil texture we have to use plane 1, and
511 * the formats X24S8 and X32_S8X24 have the actual data in the y-channel
512 * but the shader will read the x component so we need to adjust the swizzle. */
513 plane_slice = 1;
514 swizzle = STENCIL_SWIZZLE;
515 } else if (util_format_has_alpha1(pformat)) {
516 swizzle = RGB1_SWIZZLE;
517 }
518 }
519
520 return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice };
521 }
522
523 enum pipe_format
d3d12_emulated_vtx_format(enum pipe_format fmt)524 d3d12_emulated_vtx_format(enum pipe_format fmt)
525 {
526 switch (fmt) {
527 case PIPE_FORMAT_R10G10B10A2_SNORM:
528 case PIPE_FORMAT_R10G10B10A2_SSCALED:
529 case PIPE_FORMAT_R10G10B10A2_USCALED:
530 case PIPE_FORMAT_B10G10R10A2_UNORM:
531 case PIPE_FORMAT_B10G10R10A2_SNORM:
532 case PIPE_FORMAT_B10G10R10A2_SSCALED:
533 case PIPE_FORMAT_B10G10R10A2_USCALED:
534 return PIPE_FORMAT_R32_UINT;
535
536 case PIPE_FORMAT_R8G8B8_SINT:
537 return PIPE_FORMAT_R8G8B8A8_SINT;
538 case PIPE_FORMAT_R8G8B8_UINT:
539 return PIPE_FORMAT_R8G8B8A8_UINT;
540
541 case PIPE_FORMAT_R16G16B16_SINT:
542 return PIPE_FORMAT_R16G16B16A16_SINT;
543 case PIPE_FORMAT_R16G16B16_UINT:
544 return PIPE_FORMAT_R16G16B16A16_UINT;
545
546 case PIPE_FORMAT_R8G8B8A8_SSCALED:
547 return PIPE_FORMAT_R8G8B8A8_SINT;
548 case PIPE_FORMAT_R8G8B8A8_USCALED:
549 return PIPE_FORMAT_R8G8B8A8_UINT;
550 case PIPE_FORMAT_R16G16B16A16_SSCALED:
551 return PIPE_FORMAT_R16G16B16A16_SINT;
552 case PIPE_FORMAT_R16G16B16A16_USCALED:
553 return PIPE_FORMAT_R16G16B16A16_UINT;
554
555 default:
556 return fmt;
557 }
558 }
559
560
561 unsigned
d3d12_non_opaque_plane_count(DXGI_FORMAT format)562 d3d12_non_opaque_plane_count(DXGI_FORMAT format)
563 {
564 switch (format) {
565 case DXGI_FORMAT_V208:
566 case DXGI_FORMAT_V408:
567 return 3;
568
569 case DXGI_FORMAT_NV12:
570 case DXGI_FORMAT_P010:
571 case DXGI_FORMAT_P016:
572 case DXGI_FORMAT_YUY2:
573 case DXGI_FORMAT_Y210:
574 case DXGI_FORMAT_Y216:
575 case DXGI_FORMAT_NV11:
576 return 2;
577
578 case DXGI_FORMAT_R24G8_TYPELESS:
579 case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
580 case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
581 case DXGI_FORMAT_D24_UNORM_S8_UINT:
582 case DXGI_FORMAT_R32G8X24_TYPELESS:
583 case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
584 case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
585 case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
586 return 2;
587
588 default:
589 return 1;
590 }
591 }
592
593 unsigned
d3d12_get_format_start_plane(enum pipe_format fmt)594 d3d12_get_format_start_plane(enum pipe_format fmt)
595 {
596 const struct util_format_description *desc = util_format_description(fmt);
597 if (util_format_has_stencil(desc) && !util_format_has_depth(desc))
598 return 1;
599
600 return 0;
601 }
602
603 unsigned
d3d12_get_format_num_planes(enum pipe_format fmt)604 d3d12_get_format_num_planes(enum pipe_format fmt)
605 {
606 return util_format_is_depth_or_stencil(fmt) ?
607 util_bitcount(util_format_get_mask(fmt)) : 1;
608 }
609
610 DXGI_FORMAT
d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)611 d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)
612 {
613 switch (profile) {
614 case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
615 case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
616 case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
617 case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
618 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
619 case PIPE_VIDEO_PROFILE_HEVC_MAIN:
620 case PIPE_VIDEO_PROFILE_AV1_MAIN:
621 case PIPE_VIDEO_PROFILE_VP9_PROFILE0:
622 return DXGI_FORMAT_NV12;
623 case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
624 case PIPE_VIDEO_PROFILE_HEVC_MAIN_10:
625 case PIPE_VIDEO_PROFILE_VP9_PROFILE2:
626 return DXGI_FORMAT_P010;
627 default:
628 {
629 unreachable("Unsupported pipe video profile");
630 } break;
631 }
632 }
633
634 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)635 d3d12_convert_from_legacy_color_space(bool rgb, uint32_t bits_per_element, bool studio_rgb, bool p709, bool studio_yuv)
636 {
637 if (rgb) {
638 if (bits_per_element > 32) {
639 // All 16 bit color channel data is assumed to be linear rather than SRGB
640 return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
641 } else {
642 if (studio_rgb) {
643 return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
644 } else {
645 return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
646 }
647 }
648 } else {
649 if (p709) {
650 if (studio_yuv) {
651 return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
652 } else {
653 return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
654 }
655 } else {
656 if (studio_yuv) {
657 return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
658 } else {
659 return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
660 }
661 }
662 }
663 }
664