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 "util/format/u_format.h" 28#include "util/u_math.h" 29#include "util/compiler.h" 30 31static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = { 32#define MAP_FORMAT_NORM(FMT) \ 33 [PIPE_FORMAT_ ## FMT ## _UNORM] = DXGI_FORMAT_ ## FMT ## _UNORM, \ 34 [PIPE_FORMAT_ ## FMT ## _SNORM] = DXGI_FORMAT_ ## FMT ## _SNORM, 35 36#define MAP_FORMAT_INT(FMT) \ 37 [PIPE_FORMAT_ ## FMT ## _UINT] = DXGI_FORMAT_ ## FMT ## _UINT, \ 38 [PIPE_FORMAT_ ## FMT ## _SINT] = DXGI_FORMAT_ ## FMT ## _SINT, 39 40#define MAP_FORMAT_SRGB(FMT) \ 41 [PIPE_FORMAT_ ## FMT ## _SRGB] = DXGI_FORMAT_ ## FMT ## _UNORM_SRGB, 42 43#define MAP_FORMAT_FLOAT(FMT) \ 44 [PIPE_FORMAT_ ## FMT ## _FLOAT] = DXGI_FORMAT_ ## FMT ## _FLOAT, 45 46#define MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) \ 47 [PIPE_FORMAT_L ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \ 48 [PIPE_FORMAT_I ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \ 49 [PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \ 50 DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE, 51 52#define MAP_EMU_FORMAT(BITS, TYPE) \ 53 [PIPE_FORMAT_A ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \ 54 MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) 55 56 MAP_FORMAT_NORM(R8) 57 MAP_FORMAT_INT(R8) 58 59 MAP_FORMAT_NORM(R8G8) 60 MAP_FORMAT_INT(R8G8) 61 62 MAP_FORMAT_NORM(R8G8B8A8) 63 MAP_FORMAT_INT(R8G8B8A8) 64 MAP_FORMAT_SRGB(R8G8B8A8) 65 66 [PIPE_FORMAT_B8G8R8X8_UNORM] = DXGI_FORMAT_B8G8R8X8_UNORM, 67 [PIPE_FORMAT_B8G8R8A8_UNORM] = DXGI_FORMAT_B8G8R8A8_UNORM, 68 69 MAP_FORMAT_SRGB(B8G8R8A8) 70 71 MAP_FORMAT_INT(R32) 72 MAP_FORMAT_FLOAT(R32) 73 MAP_FORMAT_INT(R32G32) 74 MAP_FORMAT_FLOAT(R32G32) 75 MAP_FORMAT_INT(R32G32B32) 76 MAP_FORMAT_FLOAT(R32G32B32) 77 MAP_FORMAT_INT(R32G32B32A32) 78 MAP_FORMAT_FLOAT(R32G32B32A32) 79 80 MAP_FORMAT_NORM(R16) 81 MAP_FORMAT_INT(R16) 82 MAP_FORMAT_FLOAT(R16) 83 84 MAP_FORMAT_NORM(R16G16) 85 MAP_FORMAT_INT(R16G16) 86 MAP_FORMAT_FLOAT(R16G16) 87 88 MAP_FORMAT_NORM(R16G16B16A16) 89 MAP_FORMAT_INT(R16G16B16A16) 90 MAP_FORMAT_FLOAT(R16G16B16A16) 91 92 [PIPE_FORMAT_A8_UNORM] = DXGI_FORMAT_A8_UNORM, 93 MAP_EMU_FORMAT_NO_ALPHA(8, UNORM) 94 MAP_EMU_FORMAT(8, SNORM) 95 MAP_EMU_FORMAT(8, SINT) 96 MAP_EMU_FORMAT(8, UINT) 97 MAP_EMU_FORMAT(16, UNORM) 98 MAP_EMU_FORMAT(16, SNORM) 99 MAP_EMU_FORMAT(16, SINT) 100 MAP_EMU_FORMAT(16, UINT) 101 MAP_EMU_FORMAT(16, FLOAT) 102 MAP_EMU_FORMAT(32, SINT) 103 MAP_EMU_FORMAT(32, UINT) 104 MAP_EMU_FORMAT(32, FLOAT) 105 106 [PIPE_FORMAT_R9G9B9E5_FLOAT] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP, 107 [PIPE_FORMAT_R11G11B10_FLOAT] = DXGI_FORMAT_R11G11B10_FLOAT, 108 [PIPE_FORMAT_R10G10B10A2_UINT] = DXGI_FORMAT_R10G10B10A2_UINT, 109 [PIPE_FORMAT_R10G10B10A2_UNORM] = DXGI_FORMAT_R10G10B10A2_UNORM, 110 111 [PIPE_FORMAT_DXT1_RGB] = DXGI_FORMAT_BC1_UNORM, 112 [PIPE_FORMAT_DXT1_RGBA] = DXGI_FORMAT_BC1_UNORM, 113 [PIPE_FORMAT_DXT3_RGBA] = DXGI_FORMAT_BC2_UNORM, 114 [PIPE_FORMAT_DXT5_RGBA] = DXGI_FORMAT_BC3_UNORM, 115 116 [PIPE_FORMAT_DXT1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB, 117 [PIPE_FORMAT_DXT1_SRGBA] = DXGI_FORMAT_BC1_UNORM_SRGB, 118 [PIPE_FORMAT_DXT3_SRGBA] = DXGI_FORMAT_BC2_UNORM_SRGB, 119 [PIPE_FORMAT_DXT5_SRGBA] = DXGI_FORMAT_BC3_UNORM_SRGB, 120 121 [PIPE_FORMAT_RGTC1_UNORM] = DXGI_FORMAT_BC4_UNORM, 122 [PIPE_FORMAT_RGTC1_SNORM] = DXGI_FORMAT_BC4_SNORM, 123 [PIPE_FORMAT_RGTC2_UNORM] = DXGI_FORMAT_BC5_UNORM, 124 [PIPE_FORMAT_RGTC2_SNORM] = DXGI_FORMAT_BC5_SNORM, 125 126 [PIPE_FORMAT_Z32_FLOAT] = DXGI_FORMAT_R32_TYPELESS, 127 [PIPE_FORMAT_Z16_UNORM] = DXGI_FORMAT_R16_TYPELESS, 128 [PIPE_FORMAT_Z24X8_UNORM] = DXGI_FORMAT_R24G8_TYPELESS, 129 [PIPE_FORMAT_X24S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS, 130 131 [PIPE_FORMAT_Z24_UNORM_S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS, 132 [PIPE_FORMAT_Z32_FLOAT_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS, 133 [PIPE_FORMAT_X32_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS, 134}; 135 136DXGI_FORMAT 137d3d12_get_format(enum pipe_format format) 138{ 139 return formats[format]; 140} 141 142DXGI_FORMAT 143d3d12_get_resource_rt_format(enum pipe_format f) 144{ 145 switch (f) { 146 case PIPE_FORMAT_Z16_UNORM: 147 return DXGI_FORMAT_D16_UNORM; 148 case PIPE_FORMAT_Z32_FLOAT: 149 return DXGI_FORMAT_D32_FLOAT; 150 case PIPE_FORMAT_Z24X8_UNORM: 151 case PIPE_FORMAT_X24S8_UINT: 152 return DXGI_FORMAT_D24_UNORM_S8_UINT; 153 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 154 case PIPE_FORMAT_X32_S8X24_UINT: 155 return DXGI_FORMAT_D32_FLOAT_S8X24_UINT; 156 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 157 return DXGI_FORMAT_D24_UNORM_S8_UINT; 158 default: 159 return d3d12_get_format(f); 160 } 161} 162 163DXGI_FORMAT 164d3d12_get_resource_srv_format(enum pipe_format f, enum pipe_texture_target target) 165{ 166 switch (f) { 167 case PIPE_FORMAT_Z16_UNORM: 168 return DXGI_FORMAT_R16_UNORM; 169 case PIPE_FORMAT_Z32_FLOAT: 170 return DXGI_FORMAT_R32_FLOAT; 171 case PIPE_FORMAT_Z24X8_UNORM: 172 case PIPE_FORMAT_Z24_UNORM_S8_UINT: 173 return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; 174 case PIPE_FORMAT_X24S8_UINT: 175 return DXGI_FORMAT_X24_TYPELESS_G8_UINT; 176 case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT: 177 return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; 178 case PIPE_FORMAT_X32_S8X24_UINT: 179 return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT; 180 case PIPE_FORMAT_A8_UNORM: 181 if (target == PIPE_BUFFER) 182 return DXGI_FORMAT_R8_UNORM; /* A8_UNORM is not supported for buffer SRV */ 183 FALLTHROUGH; 184 default: 185 return d3d12_get_format(f); 186 } 187} 188 189#define DEF_SWIZZLE(name, X, Y, Z, W) \ 190 static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \ 191 { PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \ 192 PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE } 193 194struct d3d12_format_info 195d3d12_get_format_info(enum pipe_format pformat, enum pipe_texture_target target) 196{ 197 DEF_SWIZZLE(IDENTITY, X, Y, Z, W); 198 DEF_SWIZZLE(RGB1, X, Y, Z, 1); 199 DEF_SWIZZLE(ALPHA, 0, 0, 0, W); 200 DEF_SWIZZLE(BUFFER, 0, 0, 0, X); 201 DEF_SWIZZLE(INTENSITY, X, X, X, X); 202 DEF_SWIZZLE(LUMINANCE, X, X, X, 1); 203 DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y); 204 DEF_SWIZZLE(DEPTH, X, X, X, X); 205 DEF_SWIZZLE(STENCIL, Y, Y, Y, Y); 206 207 const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE; 208 unsigned plane_slice = 0; 209 210 if (pformat == PIPE_FORMAT_DXT1_RGB || 211 pformat == PIPE_FORMAT_DXT1_SRGB) 212 swizzle = RGB1_SWIZZLE; 213 214 const struct util_format_description 215 *format_desc = util_format_description(pformat); 216 if (!util_format_is_srgb(pformat)) { 217 if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) { 218 swizzle = BUFFER_SWIZZLE; 219 } else if (pformat == PIPE_FORMAT_A8_UNORM) { 220 /* no need to swizzle, it's natively supported */ 221 } else if (util_format_is_intensity(pformat)) { 222 swizzle = INTENSITY_SWIZZLE; 223 } else if (util_format_is_luminance(pformat)) { 224 swizzle = LUMINANCE_SWIZZLE; 225 } else if (util_format_is_luminance_alpha(pformat)) { 226 swizzle = LUMINANCE_ALPHA_SWIZZLE; 227 } else if (util_format_is_alpha(pformat)) { 228 swizzle = ALPHA_SWIZZLE; 229 } else if (util_format_has_depth(format_desc)) { 230 swizzle = DEPTH_SWIZZLE; 231 } else if (util_format_has_stencil(format_desc)) { 232 /* When reading from a stencil texture we have to use plane 1, and 233 * the formats X24S8 and X32_S8X24 have the actual data in the y-channel 234 * but the shader will read the x component so we need to adjust the swizzle. */ 235 plane_slice = 1; 236 swizzle = STENCIL_SWIZZLE; 237 } 238 } 239 240 return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice }; 241} 242 243enum pipe_format 244d3d12_emulated_vtx_format(enum pipe_format fmt) 245{ 246 switch (fmt) { 247 case PIPE_FORMAT_R10G10B10A2_SNORM: 248 case PIPE_FORMAT_R10G10B10A2_SSCALED: 249 case PIPE_FORMAT_R10G10B10A2_USCALED: 250 case PIPE_FORMAT_B10G10R10A2_UNORM: 251 case PIPE_FORMAT_B10G10R10A2_SNORM: 252 case PIPE_FORMAT_B10G10R10A2_SSCALED: 253 case PIPE_FORMAT_B10G10R10A2_USCALED: 254 return PIPE_FORMAT_R32_UINT; 255 256 case PIPE_FORMAT_R8G8B8_SINT: 257 return PIPE_FORMAT_R8G8B8A8_SINT; 258 case PIPE_FORMAT_R8G8B8_UINT: 259 return PIPE_FORMAT_R8G8B8A8_UINT; 260 261 case PIPE_FORMAT_R16G16B16_SINT: 262 return PIPE_FORMAT_R16G16B16A16_SINT; 263 case PIPE_FORMAT_R16G16B16_UINT: 264 return PIPE_FORMAT_R16G16B16A16_UINT; 265 266 default: 267 return fmt; 268 } 269} 270 271 272unsigned 273d3d12_non_opaque_plane_count(DXGI_FORMAT format) 274{ 275 switch (format) { 276 case DXGI_FORMAT_V208: 277 case DXGI_FORMAT_V408: 278 return 3; 279 280 case DXGI_FORMAT_NV12: 281 case DXGI_FORMAT_P010: 282 case DXGI_FORMAT_P016: 283 case DXGI_FORMAT_YUY2: 284 case DXGI_FORMAT_Y210: 285 case DXGI_FORMAT_Y216: 286 case DXGI_FORMAT_NV11: 287 return 2; 288 289 default: 290 return 1; 291 } 292} 293 294unsigned 295d3d12_get_format_start_plane(enum pipe_format fmt) 296{ 297 const struct util_format_description *desc = util_format_description(fmt); 298 if (util_format_has_stencil(desc) && !util_format_has_depth(desc)) 299 return 1; 300 301 return 0; 302} 303 304unsigned 305d3d12_get_format_num_planes(enum pipe_format fmt) 306{ 307 return util_format_is_depth_or_stencil(fmt) ? 308 util_bitcount(util_format_get_mask(fmt)) : 1; 309} 310