Path: blob/21.2-virgl/src/gallium/drivers/d3d12/d3d12_format.c
4570 views
/*1* Copyright © Microsoft Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include "d3d12_format.h"2425#include "pipe/p_format.h"26#include "util/format/u_format.h"27#include "util/u_math.h"28#include "util/compiler.h"2930static const DXGI_FORMAT formats[PIPE_FORMAT_COUNT] = {31#define MAP_FORMAT_NORM(FMT) \32[PIPE_FORMAT_ ## FMT ## _UNORM] = DXGI_FORMAT_ ## FMT ## _UNORM, \33[PIPE_FORMAT_ ## FMT ## _SNORM] = DXGI_FORMAT_ ## FMT ## _SNORM,3435#define MAP_FORMAT_INT(FMT) \36[PIPE_FORMAT_ ## FMT ## _UINT] = DXGI_FORMAT_ ## FMT ## _UINT, \37[PIPE_FORMAT_ ## FMT ## _SINT] = DXGI_FORMAT_ ## FMT ## _SINT,3839#define MAP_FORMAT_SRGB(FMT) \40[PIPE_FORMAT_ ## FMT ## _SRGB] = DXGI_FORMAT_ ## FMT ## _UNORM_SRGB,4142#define MAP_FORMAT_FLOAT(FMT) \43[PIPE_FORMAT_ ## FMT ## _FLOAT] = DXGI_FORMAT_ ## FMT ## _FLOAT,4445#define MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE) \46[PIPE_FORMAT_L ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \47[PIPE_FORMAT_I ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \48[PIPE_FORMAT_L ## BITS ## A ## BITS ## _ ## TYPE] = \49DXGI_FORMAT_R ## BITS ## G ## BITS ## _ ## TYPE,5051#define MAP_EMU_FORMAT(BITS, TYPE) \52[PIPE_FORMAT_A ## BITS ## _ ## TYPE] = DXGI_FORMAT_R ## BITS ## _ ## TYPE, \53MAP_EMU_FORMAT_NO_ALPHA(BITS, TYPE)5455MAP_FORMAT_NORM(R8)56MAP_FORMAT_INT(R8)5758MAP_FORMAT_NORM(R8G8)59MAP_FORMAT_INT(R8G8)6061MAP_FORMAT_NORM(R8G8B8A8)62MAP_FORMAT_INT(R8G8B8A8)63MAP_FORMAT_SRGB(R8G8B8A8)6465[PIPE_FORMAT_B8G8R8X8_UNORM] = DXGI_FORMAT_B8G8R8X8_UNORM,66[PIPE_FORMAT_B8G8R8A8_UNORM] = DXGI_FORMAT_B8G8R8A8_UNORM,6768MAP_FORMAT_SRGB(B8G8R8A8)6970MAP_FORMAT_INT(R32)71MAP_FORMAT_FLOAT(R32)72MAP_FORMAT_INT(R32G32)73MAP_FORMAT_FLOAT(R32G32)74MAP_FORMAT_INT(R32G32B32)75MAP_FORMAT_FLOAT(R32G32B32)76MAP_FORMAT_INT(R32G32B32A32)77MAP_FORMAT_FLOAT(R32G32B32A32)7879MAP_FORMAT_NORM(R16)80MAP_FORMAT_INT(R16)81MAP_FORMAT_FLOAT(R16)8283MAP_FORMAT_NORM(R16G16)84MAP_FORMAT_INT(R16G16)85MAP_FORMAT_FLOAT(R16G16)8687MAP_FORMAT_NORM(R16G16B16A16)88MAP_FORMAT_INT(R16G16B16A16)89MAP_FORMAT_FLOAT(R16G16B16A16)9091[PIPE_FORMAT_A8_UNORM] = DXGI_FORMAT_A8_UNORM,92MAP_EMU_FORMAT_NO_ALPHA(8, UNORM)93MAP_EMU_FORMAT(8, SNORM)94MAP_EMU_FORMAT(8, SINT)95MAP_EMU_FORMAT(8, UINT)96MAP_EMU_FORMAT(16, UNORM)97MAP_EMU_FORMAT(16, SNORM)98MAP_EMU_FORMAT(16, SINT)99MAP_EMU_FORMAT(16, UINT)100MAP_EMU_FORMAT(16, FLOAT)101MAP_EMU_FORMAT(32, SINT)102MAP_EMU_FORMAT(32, UINT)103MAP_EMU_FORMAT(32, FLOAT)104105[PIPE_FORMAT_R9G9B9E5_FLOAT] = DXGI_FORMAT_R9G9B9E5_SHAREDEXP,106[PIPE_FORMAT_R11G11B10_FLOAT] = DXGI_FORMAT_R11G11B10_FLOAT,107[PIPE_FORMAT_R10G10B10A2_UINT] = DXGI_FORMAT_R10G10B10A2_UINT,108[PIPE_FORMAT_R10G10B10A2_UNORM] = DXGI_FORMAT_R10G10B10A2_UNORM,109110[PIPE_FORMAT_DXT1_RGB] = DXGI_FORMAT_BC1_UNORM,111[PIPE_FORMAT_DXT1_RGBA] = DXGI_FORMAT_BC1_UNORM,112[PIPE_FORMAT_DXT3_RGBA] = DXGI_FORMAT_BC2_UNORM,113[PIPE_FORMAT_DXT5_RGBA] = DXGI_FORMAT_BC3_UNORM,114115[PIPE_FORMAT_DXT1_SRGB] = DXGI_FORMAT_BC1_UNORM_SRGB,116[PIPE_FORMAT_DXT1_SRGBA] = DXGI_FORMAT_BC1_UNORM_SRGB,117[PIPE_FORMAT_DXT3_SRGBA] = DXGI_FORMAT_BC2_UNORM_SRGB,118[PIPE_FORMAT_DXT5_SRGBA] = DXGI_FORMAT_BC3_UNORM_SRGB,119120[PIPE_FORMAT_RGTC1_UNORM] = DXGI_FORMAT_BC4_UNORM,121[PIPE_FORMAT_RGTC1_SNORM] = DXGI_FORMAT_BC4_SNORM,122[PIPE_FORMAT_RGTC2_UNORM] = DXGI_FORMAT_BC5_UNORM,123[PIPE_FORMAT_RGTC2_SNORM] = DXGI_FORMAT_BC5_SNORM,124125[PIPE_FORMAT_Z32_FLOAT] = DXGI_FORMAT_R32_TYPELESS,126[PIPE_FORMAT_Z16_UNORM] = DXGI_FORMAT_R16_TYPELESS,127[PIPE_FORMAT_Z24X8_UNORM] = DXGI_FORMAT_R24G8_TYPELESS,128[PIPE_FORMAT_X24S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,129130[PIPE_FORMAT_Z24_UNORM_S8_UINT] = DXGI_FORMAT_R24G8_TYPELESS,131[PIPE_FORMAT_Z32_FLOAT_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,132[PIPE_FORMAT_X32_S8X24_UINT] = DXGI_FORMAT_R32G8X24_TYPELESS,133};134135DXGI_FORMAT136d3d12_get_format(enum pipe_format format)137{138return formats[format];139}140141DXGI_FORMAT142d3d12_get_resource_rt_format(enum pipe_format f)143{144switch (f) {145case PIPE_FORMAT_Z16_UNORM:146return DXGI_FORMAT_D16_UNORM;147case PIPE_FORMAT_Z32_FLOAT:148return DXGI_FORMAT_D32_FLOAT;149case PIPE_FORMAT_Z24X8_UNORM:150case PIPE_FORMAT_X24S8_UINT:151return DXGI_FORMAT_D24_UNORM_S8_UINT;152case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:153case PIPE_FORMAT_X32_S8X24_UINT:154return DXGI_FORMAT_D32_FLOAT_S8X24_UINT;155case PIPE_FORMAT_Z24_UNORM_S8_UINT:156return DXGI_FORMAT_D24_UNORM_S8_UINT;157default:158return d3d12_get_format(f);159}160}161162DXGI_FORMAT163d3d12_get_resource_srv_format(enum pipe_format f, enum pipe_texture_target target)164{165switch (f) {166case PIPE_FORMAT_Z16_UNORM:167return DXGI_FORMAT_R16_UNORM;168case PIPE_FORMAT_Z32_FLOAT:169return DXGI_FORMAT_R32_FLOAT;170case PIPE_FORMAT_Z24X8_UNORM:171case PIPE_FORMAT_Z24_UNORM_S8_UINT:172return DXGI_FORMAT_R24_UNORM_X8_TYPELESS;173case PIPE_FORMAT_X24S8_UINT:174return DXGI_FORMAT_X24_TYPELESS_G8_UINT;175case PIPE_FORMAT_Z32_FLOAT_S8X24_UINT:176return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS;177case PIPE_FORMAT_X32_S8X24_UINT:178return DXGI_FORMAT_X32_TYPELESS_G8X24_UINT;179case PIPE_FORMAT_A8_UNORM:180if (target == PIPE_BUFFER)181return DXGI_FORMAT_R8_UNORM; /* A8_UNORM is not supported for buffer SRV */182FALLTHROUGH;183default:184return d3d12_get_format(f);185}186}187188#define DEF_SWIZZLE(name, X, Y, Z, W) \189static const enum pipe_swizzle name ## _SWIZZLE[PIPE_SWIZZLE_MAX] = \190{ PIPE_SWIZZLE_ ## X, PIPE_SWIZZLE_ ## Y, PIPE_SWIZZLE_ ## Z, PIPE_SWIZZLE_ ## W, \191PIPE_SWIZZLE_0, PIPE_SWIZZLE_1, PIPE_SWIZZLE_NONE }192193struct d3d12_format_info194d3d12_get_format_info(enum pipe_format pformat, enum pipe_texture_target target)195{196DEF_SWIZZLE(IDENTITY, X, Y, Z, W);197DEF_SWIZZLE(RGB1, X, Y, Z, 1);198DEF_SWIZZLE(ALPHA, 0, 0, 0, W);199DEF_SWIZZLE(BUFFER, 0, 0, 0, X);200DEF_SWIZZLE(INTENSITY, X, X, X, X);201DEF_SWIZZLE(LUMINANCE, X, X, X, 1);202DEF_SWIZZLE(LUMINANCE_ALPHA, X, X, X, Y);203DEF_SWIZZLE(DEPTH, X, X, X, X);204DEF_SWIZZLE(STENCIL, Y, Y, Y, Y);205206const enum pipe_swizzle *swizzle = IDENTITY_SWIZZLE;207unsigned plane_slice = 0;208209if (pformat == PIPE_FORMAT_DXT1_RGB ||210pformat == PIPE_FORMAT_DXT1_SRGB)211swizzle = RGB1_SWIZZLE;212213const struct util_format_description214*format_desc = util_format_description(pformat);215if (!util_format_is_srgb(pformat)) {216if (target == PIPE_BUFFER && util_format_is_alpha(pformat)) {217swizzle = BUFFER_SWIZZLE;218} else if (pformat == PIPE_FORMAT_A8_UNORM) {219/* no need to swizzle, it's natively supported */220} else if (util_format_is_intensity(pformat)) {221swizzle = INTENSITY_SWIZZLE;222} else if (util_format_is_luminance(pformat)) {223swizzle = LUMINANCE_SWIZZLE;224} else if (util_format_is_luminance_alpha(pformat)) {225swizzle = LUMINANCE_ALPHA_SWIZZLE;226} else if (util_format_is_alpha(pformat)) {227swizzle = ALPHA_SWIZZLE;228} else if (util_format_has_depth(format_desc)) {229swizzle = DEPTH_SWIZZLE;230} else if (util_format_has_stencil(format_desc)) {231/* When reading from a stencil texture we have to use plane 1, and232* the formats X24S8 and X32_S8X24 have the actual data in the y-channel233* but the shader will read the x component so we need to adjust the swizzle. */234plane_slice = 1;235swizzle = STENCIL_SWIZZLE;236}237}238239return (struct d3d12_format_info) { .swizzle = swizzle, .plane_slice = plane_slice };240}241242enum pipe_format243d3d12_emulated_vtx_format(enum pipe_format fmt)244{245switch (fmt) {246case PIPE_FORMAT_R10G10B10A2_SNORM:247case PIPE_FORMAT_R10G10B10A2_SSCALED:248case PIPE_FORMAT_R10G10B10A2_USCALED:249case PIPE_FORMAT_B10G10R10A2_UNORM:250case PIPE_FORMAT_B10G10R10A2_SNORM:251case PIPE_FORMAT_B10G10R10A2_SSCALED:252case PIPE_FORMAT_B10G10R10A2_USCALED:253return PIPE_FORMAT_R32_UINT;254255case PIPE_FORMAT_R8G8B8_SINT:256return PIPE_FORMAT_R8G8B8A8_SINT;257case PIPE_FORMAT_R8G8B8_UINT:258return PIPE_FORMAT_R8G8B8A8_UINT;259260case PIPE_FORMAT_R16G16B16_SINT:261return PIPE_FORMAT_R16G16B16A16_SINT;262case PIPE_FORMAT_R16G16B16_UINT:263return PIPE_FORMAT_R16G16B16A16_UINT;264265default:266return fmt;267}268}269270271unsigned272d3d12_non_opaque_plane_count(DXGI_FORMAT format)273{274switch (format) {275case DXGI_FORMAT_V208:276case DXGI_FORMAT_V408:277return 3;278279case DXGI_FORMAT_NV12:280case DXGI_FORMAT_P010:281case DXGI_FORMAT_P016:282case DXGI_FORMAT_YUY2:283case DXGI_FORMAT_Y210:284case DXGI_FORMAT_Y216:285case DXGI_FORMAT_NV11:286return 2;287288default:289return 1;290}291}292293unsigned294d3d12_get_format_start_plane(enum pipe_format fmt)295{296const struct util_format_description *desc = util_format_description(fmt);297if (util_format_has_stencil(desc) && !util_format_has_depth(desc))298return 1;299300return 0;301}302303unsigned304d3d12_get_format_num_planes(enum pipe_format fmt)305{306return util_format_is_depth_or_stencil(fmt) ?307util_bitcount(util_format_get_mask(fmt)) : 1;308}309310311