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 "pipe/p_format.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   /* Since we report PIPE_CAP_RGB_OVERRIDE_DST_ALPHA_BLEND and other caps, \
86    * we can rely on st/mesa to force the alpha to 1 for these, so we can \
87    * just use RGBA. This is needed to support RGB configs, since some apps \
88    * will only choose RGB (not RGBA) configs. \
89    */ \
90   MAP_FORMAT_X8(R8G8B8, UNORM) \
91   MAP_FORMAT_X8(R8G8B8, SNORM) \
92   MAP_FORMAT_X8(R8G8B8, UINT) \
93   MAP_FORMAT_X8(R8G8B8, SINT) \
94\
95   MAP_FORMAT(B8G8R8X8, UNORM) \
96   MAP_FORMAT(B8G8R8A8, UNORM) \
97\
98   MAP_FORMAT_SRGB(B8G8R8A8) \
99\
100   MAP_FORMAT_INT(R32) \
101   MAP_FORMAT_FLOAT(R32) \
102   MAP_FORMAT_INT(R32G32) \
103   MAP_FORMAT_FLOAT(R32G32) \
104   MAP_FORMAT_INT(R32G32B32) \
105   MAP_FORMAT_FLOAT(R32G32B32) \
106   MAP_FORMAT_INT(R32G32B32A32) \
107   MAP_FORMAT_FLOAT(R32G32B32A32) \
108\
109   MAP_FORMAT_NORM(R16) \
110   MAP_FORMAT_INT(R16) \
111   MAP_FORMAT_FLOAT(R16) \
112\
113   MAP_FORMAT_NORM(R16G16) \
114   MAP_FORMAT_INT(R16G16) \
115   MAP_FORMAT_FLOAT(R16G16) \
116\
117   MAP_FORMAT_NORM(R16G16B16A16) \
118   MAP_FORMAT_INT(R16G16B16A16) \
119   MAP_FORMAT_FLOAT(R16G16B16A16) \
120\
121   MAP_FORMAT_NO_TYPELESS(A8, UNORM) \
122   MAP_EMU_FORMAT_NO_ALPHA(8, UNORM) \
123   MAP_EMU_FORMAT(8, SNORM) \
124   MAP_EMU_FORMAT(8, SINT) \
125   MAP_EMU_FORMAT(8, UINT) \
126   MAP_EMU_FORMAT(16, UNORM) \
127   MAP_EMU_FORMAT(16, SNORM) \
128   MAP_EMU_FORMAT(16, SINT) \
129   MAP_EMU_FORMAT(16, UINT) \
130   MAP_EMU_FORMAT(16, FLOAT) \
131   MAP_EMU_FORMAT(32, SINT) \
132   MAP_EMU_FORMAT(32, UINT) \
133   MAP_EMU_FORMAT(32, FLOAT) \
134\
135   MAP_FORMAT2_NO_TYPELESS(R9G9B9E5, FLOAT, R9G9B9E5, SHAREDEXP) \
136   MAP_FORMAT_NO_TYPELESS(R11G11B10, FLOAT) \
137   MAP_FORMAT(R10G10B10A2, UINT) \
138   MAP_FORMAT(R10G10B10A2, UNORM) \
139\
140   MAP_FORMAT_NO_TYPELESS(B5G6R5, UNORM) \
141   MAP_FORMAT_NO_TYPELESS(B5G5R5A1, UNORM) \
142   MAP_FORMAT2_NO_TYPELESS(B5G5R5X1, UNORM, B5G5R5A1, UNORM) \
143\
144   MAP_FORMAT_NO_TYPELESS(B4G4R4A4, UNORM) \
145\
146   MAP_FORMAT2(DXT1, RGB, BC1, UNORM) \
147   MAP_FORMAT2(DXT1, RGBA, BC1, UNORM) \
148   MAP_FORMAT2(DXT3, RGBA, BC2, UNORM) \
149   MAP_FORMAT2(DXT5, RGBA, BC3, UNORM) \
150\
151   MAP_FORMAT2(DXT1, SRGB, BC1, UNORM_SRGB) \
152   MAP_FORMAT2(DXT1, SRGBA, BC1, UNORM_SRGB) \
153   MAP_FORMAT2(DXT3, SRGBA, BC2, UNORM_SRGB) \
154   MAP_FORMAT2(DXT5, SRGBA, BC3, UNORM_SRGB) \
155\
156   MAP_FORMAT2(RGTC1, UNORM, BC4, UNORM) \
157   MAP_FORMAT2(RGTC1, SNORM, BC4, SNORM) \
158   MAP_FORMAT2(RGTC2, UNORM, BC5, UNORM) \
159   MAP_FORMAT2(RGTC2, SNORM, BC5, SNORM) \
160\
161   MAP_FORMAT2(BPTC, RGBA_UNORM, BC7, UNORM) \
162   MAP_FORMAT2(BPTC, SRGBA, BC7, UNORM_SRGB) \
163   MAP_FORMAT2(BPTC, RGB_FLOAT, BC6H, SF16) \
164   MAP_FORMAT2(BPTC, RGB_UFLOAT, BC6H, UF16) \
165\
166   MAP_FORMAT2(Z32, FLOAT, R32, TYPELESS) \
167   MAP_FORMAT2(Z16, UNORM, R16, TYPELESS) \
168   MAP_FORMAT2(Z24X8, UNORM, R24G8, TYPELESS) \
169   MAP_FORMAT2(X24S8, UINT, R24G8, TYPELESS) \
170\
171   MAP_FORMAT2(Z24_UNORM_S8, UINT, R24G8, TYPELESS) \
172   MAP_FORMAT2(Z32_FLOAT_S8X24, UINT, R32G8X24, TYPELESS) \
173   MAP_FORMAT2(X32_S8X24, UINT, R32G8X24, TYPELESS) \
174\
175   MAP_FORMAT_YUV(NV12)
176
177static 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
198static const DXGI_FORMAT typeless_formats[PIPE_FORMAT_COUNT] = {
199   FORMAT_TABLE()
200};
201
202DXGI_FORMAT
203d3d12_get_format(enum pipe_format format)
204{
205   return formats[format];
206}
207
208DXGI_FORMAT
209d3d12_get_typeless_format(enum pipe_format format)
210{
211   return typeless_formats[format];
212}
213
214enum pipe_format
215d3d12_get_pipe_format(DXGI_FORMAT format)
216{
217   for (unsigned i = 0; i < ARRAY_SIZE(formats); ++i) {
218      if (formats[i] == format) {
219         return (enum pipe_format)i;
220      }
221   }
222   return PIPE_FORMAT_NONE;
223}
224
225enum pipe_format
226d3d12_get_default_pipe_format(DXGI_FORMAT format)
227{
228#define TYPELESS_TO(channels, suffix) \
229   case DXGI_FORMAT_##channels##_TYPELESS: \
230      return PIPE_FORMAT_##channels##_##suffix
231
232   switch (format) {
233      TYPELESS_TO(R8, UNORM);
234      TYPELESS_TO(R8G8, UNORM);
235      TYPELESS_TO(R8G8B8A8, UNORM);
236      TYPELESS_TO(B8G8R8X8, UNORM);
237      TYPELESS_TO(B8G8R8A8, UNORM);
238      TYPELESS_TO(R16, FLOAT);
239      TYPELESS_TO(R16G16, FLOAT);
240      TYPELESS_TO(R16G16B16A16, FLOAT);
241      TYPELESS_TO(R32, FLOAT);
242      TYPELESS_TO(R32G32, FLOAT);
243      TYPELESS_TO(R32G32B32, FLOAT);
244      TYPELESS_TO(R32G32B32A32, FLOAT);
245   case DXGI_FORMAT_BC1_TYPELESS:
246      return PIPE_FORMAT_DXT1_RGBA;
247   case DXGI_FORMAT_BC2_TYPELESS:
248      return PIPE_FORMAT_DXT3_RGBA;
249   case DXGI_FORMAT_BC3_TYPELESS:
250      return PIPE_FORMAT_DXT5_RGBA;
251   case DXGI_FORMAT_BC4_TYPELESS:
252      return PIPE_FORMAT_RGTC1_UNORM;
253   case DXGI_FORMAT_BC5_TYPELESS:
254      return PIPE_FORMAT_RGTC2_UNORM;
255   case DXGI_FORMAT_BC6H_TYPELESS:
256      return PIPE_FORMAT_BPTC_RGB_FLOAT;
257   case DXGI_FORMAT_BC7_TYPELESS:
258      return PIPE_FORMAT_BPTC_RGBA_UNORM;
259   default:
260      return PIPE_FORMAT_NONE;
261   }
262}
263
264DXGI_FORMAT
265d3d12_get_resource_rt_format(enum pipe_format f)
266{
267   switch (f) {
268   case PIPE_FORMAT_Z16_UNORM:
269      return DXGI_FORMAT_D16_UNORM;
270   case PIPE_FORMAT_Z32_FLOAT:
271      return DXGI_FORMAT_D32_FLOAT;
272   case PIPE_FORMAT_Z24X8_UNORM:
273   case PIPE_FORMAT_X24S8_UINT:
274      return DXGI_FORMAT_D24_UNORM_S8_UINT;
275   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
276   case PIPE_FORMAT_X32_S8X24_UINT:
277      return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;
278   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
279      return DXGI_FORMAT_D24_UNORM_S8_UINT;
280   default:
281      return d3d12_get_format(f);
282   }
283}
284
285DXGI_FORMAT
286d3d12_get_resource_srv_format(enum pipe_format f, enum pipe_texture_target target)
287{
288   switch (f) {
289   case PIPE_FORMAT_Z16_UNORM:
290      return DXGI_FORMAT_R16_UNORM;
291   case PIPE_FORMAT_Z32_FLOAT:
292      return DXGI_FORMAT_R32_FLOAT;
293   case PIPE_FORMAT_Z24X8_UNORM:
294   case PIPE_FORMAT_Z24_UNORM_S8_UINT:
295      return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
296   case PIPE_FORMAT_X24S8_UINT:
297      return DXGI_FORMAT_X24_TYPELESS_G8_UINT;
298   case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:
299      return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;
300   case PIPE_FORMAT_X32_S8X24_UINT:
301      return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;
302   case PIPE_FORMAT_A8_UNORM:
303      if (target == PIPE_BUFFER)
304         return DXGI_FORMAT_R8_UNORM; /* A8_UNORM is not supported for buffer SRV */
305      FALLTHROUGH;
306   default:
307      return d3d12_get_format(f);
308   }
309}
310
311#define DEF_SWIZZLE(name, X, Y, Z, W) \
312   static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \
313      { PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \
314        PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE }
315
316struct d3d12_format_info
317d3d12_get_format_info(enum pipe_format resource_format, enum pipe_format pformat, enum pipe_texture_target target)
318{
319   DEF_SWIZZLE(IDENTITY, X, Y, Z, W);
320   DEF_SWIZZLE(RGB1, X, Y, Z, 1);
321   DEF_SWIZZLE(ALPHA, 0, 0, 0, W);
322   DEF_SWIZZLE(BUFFER, 0, 0, 0, X);
323   DEF_SWIZZLE(INTENSITY, X, X, X, X);
324   DEF_SWIZZLE(LUMINANCE, X, X, X, 1);
325   DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y);
326   DEF_SWIZZLE(DEPTH, X, X, X, X);
327   DEF_SWIZZLE(STENCIL, Y, Y, Y, Y);
328
329   const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE;
330   unsigned plane_slice = 0;
331
332   if (pformat == PIPE_FORMAT_DXT1_RGB ||
333       pformat == PIPE_FORMAT_DXT1_SRGB)
334      swizzle = RGB1_SWIZZLE;
335
336   const struct util_format_description
337      *format_desc = util_format_description(pformat);
338   unsigned plane_count = util_format_get_num_planes(resource_format);
339   if (!util_format_is_srgb(pformat)) {
340      if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) {
341         swizzle = BUFFER_SWIZZLE;
342      } else if (plane_count > 1) {
343         for (plane_slice = 0; plane_slice < plane_count; ++plane_slice) {
344            if (util_format_get_plane_format(resource_format, plane_slice) == pformat)
345               break;
346         }
347         assert(plane_slice < plane_count);
348      } else if (pformat == PIPE_FORMAT_A8_UNORM) {
349         /* no need to swizzle, it's natively supported */
350      } else if (util_format_is_intensity(pformat)) {
351         swizzle = INTENSITY_SWIZZLE;
352      } else if (util_format_is_luminance(pformat)) {
353         swizzle = LUMINANCE_SWIZZLE;
354      } else if (util_format_is_luminance_alpha(pformat)) {
355         swizzle = LUMINANCE_ALPHA_SWIZZLE;
356      } else if (util_format_is_alpha(pformat)) {
357         swizzle = ALPHA_SWIZZLE;
358      } else if (util_format_has_depth(format_desc)) {
359         swizzle = DEPTH_SWIZZLE;
360      } else if (util_format_has_stencil(format_desc)) {
361         /* When reading from a stencil texture we have to use plane 1, and
362          * the formats X24S8 and X32_S8X24 have the actual data in the y-channel
363          * but the shader will read the x component so we need to adjust the swizzle. */
364         plane_slice = 1;
365         swizzle = STENCIL_SWIZZLE;
366      } else if (util_format_has_alpha1(pformat)) {
367         swizzle = RGB1_SWIZZLE;
368      }
369   }
370
371   return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice };
372}
373
374enum pipe_format
375d3d12_emulated_vtx_format(enum pipe_format fmt)
376{
377   switch (fmt) {
378   case PIPE_FORMAT_R10G10B10A2_SNORM:
379   case PIPE_FORMAT_R10G10B10A2_SSCALED:
380   case PIPE_FORMAT_R10G10B10A2_USCALED:
381   case PIPE_FORMAT_B10G10R10A2_UNORM:
382   case PIPE_FORMAT_B10G10R10A2_SNORM:
383   case PIPE_FORMAT_B10G10R10A2_SSCALED:
384   case PIPE_FORMAT_B10G10R10A2_USCALED:
385      return PIPE_FORMAT_R32_UINT;
386
387   case PIPE_FORMAT_R8G8B8_SINT:
388      return PIPE_FORMAT_R8G8B8A8_SINT;
389   case PIPE_FORMAT_R8G8B8_UINT:
390      return PIPE_FORMAT_R8G8B8A8_UINT;
391
392   case PIPE_FORMAT_R16G16B16_SINT:
393      return PIPE_FORMAT_R16G16B16A16_SINT;
394   case PIPE_FORMAT_R16G16B16_UINT:
395      return PIPE_FORMAT_R16G16B16A16_UINT;
396
397   case PIPE_FORMAT_R8G8B8A8_SSCALED:
398      return PIPE_FORMAT_R8G8B8A8_SINT;
399   case PIPE_FORMAT_R8G8B8A8_USCALED:
400      return PIPE_FORMAT_R8G8B8A8_UINT;
401   case PIPE_FORMAT_R16G16B16A16_SSCALED:
402      return PIPE_FORMAT_R16G16B16A16_SINT;
403   case PIPE_FORMAT_R16G16B16A16_USCALED:
404      return PIPE_FORMAT_R16G16B16A16_UINT;
405
406   default:
407      return fmt;
408   }
409}
410
411
412unsigned
413d3d12_non_opaque_plane_count(DXGI_FORMAT format)
414{
415   switch (format) {
416   case DXGI_FORMAT_V208:
417   case DXGI_FORMAT_V408:
418      return 3;
419
420   case DXGI_FORMAT_NV12:
421   case DXGI_FORMAT_P010:
422   case DXGI_FORMAT_P016:
423   case DXGI_FORMAT_YUY2:
424   case DXGI_FORMAT_Y210:
425   case DXGI_FORMAT_Y216:
426   case DXGI_FORMAT_NV11:
427      return 2;
428
429   case DXGI_FORMAT_R24G8_TYPELESS:
430   case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:
431   case DXGI_FORMAT_X24_TYPELESS_G8_UINT:
432   case DXGI_FORMAT_D24_UNORM_S8_UINT:
433   case DXGI_FORMAT_R32G8X24_TYPELESS:
434   case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:
435   case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:
436   case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:
437      return 2;
438
439   default:
440      return 1;
441   }
442}
443
444unsigned
445d3d12_get_format_start_plane(enum pipe_format fmt)
446{
447   const struct util_format_description *desc = util_format_description(fmt);
448   if (util_format_has_stencil(desc) && !util_format_has_depth(desc))
449      return 1;
450
451   return 0;
452}
453
454unsigned
455d3d12_get_format_num_planes(enum pipe_format fmt)
456{
457   return util_format_is_depth_or_stencil(fmt) ?
458      util_bitcount(util_format_get_mask(fmt)) : 1;
459}
460
461DXGI_FORMAT
462d3d12_convert_pipe_video_profile_to_dxgi_format(enum pipe_video_profile profile)
463{
464   switch (profile) {
465      case PIPE_VIDEO_PROFILE_MPEG4_AVC_BASELINE:
466      case PIPE_VIDEO_PROFILE_MPEG4_AVC_CONSTRAINED_BASELINE:
467      case PIPE_VIDEO_PROFILE_MPEG4_AVC_MAIN:
468      case PIPE_VIDEO_PROFILE_MPEG4_AVC_EXTENDED:
469      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH:
470         return DXGI_FORMAT_NV12;
471      case PIPE_VIDEO_PROFILE_MPEG4_AVC_HIGH10:
472         return DXGI_FORMAT_P010;
473      default:
474      {
475         unreachable("Unsupported pipe video profile");
476      } break;
477   }
478}
479
480DXGI_COLOR_SPACE_TYPE
481d3d12_convert_from_legacy_color_space(bool rgb, uint32_t bits_per_element, bool studio_rgb, bool p709, bool studio_yuv)
482{
483   if (rgb) {
484      if (bits_per_element > 32) {
485         // All 16 bit color channel data is assumed to be linear rather than SRGB
486         return DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
487      } else {
488         if (studio_rgb) {
489            return DXGI_COLOR_SPACE_RGB_STUDIO_G22_NONE_P709;
490         } else {
491            return DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
492         }
493      }
494   } else {
495      if (p709) {
496         if (studio_yuv) {
497            return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P709;
498         } else {
499            return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P709;
500         }
501      } else {
502         if (studio_yuv) {
503            return DXGI_COLOR_SPACE_YCBCR_STUDIO_G22_LEFT_P601;
504         } else {
505            return DXGI_COLOR_SPACE_YCBCR_FULL_G22_LEFT_P601;
506         }
507      }
508   }
509}
510