1/* 2 * Copyright © 2015 Intel 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 "anv_private.h" 25#include "drm-uapi/drm_fourcc.h" 26#include "vk_enum_defines.h" 27#include "vk_enum_to_str.h" 28#include "vk_format.h" 29#include "vk_util.h" 30 31/* 32 * gcc-4 and earlier don't allow compound literals where a constant 33 * is required in -std=c99/gnu99 mode, so we can't use ISL_SWIZZLE() 34 * here. -std=c89/gnu89 would allow it, but we depend on c99 features 35 * so using -std=c89/gnu89 is not an option. Starting from gcc-5 36 * compound literals can also be considered constant in -std=c99/gnu99 37 * mode. 38 */ 39#define _ISL_SWIZZLE(r, g, b, a) { \ 40 ISL_CHANNEL_SELECT_##r, \ 41 ISL_CHANNEL_SELECT_##g, \ 42 ISL_CHANNEL_SELECT_##b, \ 43 ISL_CHANNEL_SELECT_##a, \ 44} 45 46#define RGBA _ISL_SWIZZLE(RED, GREEN, BLUE, ALPHA) 47#define BGRA _ISL_SWIZZLE(BLUE, GREEN, RED, ALPHA) 48#define RGB1 _ISL_SWIZZLE(RED, GREEN, BLUE, ONE) 49 50#define swiz_fmt1(__vk_fmt, __hw_fmt, __swizzle) \ 51 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 52 .planes = { \ 53 { .isl_format = __hw_fmt, .swizzle = __swizzle, \ 54 .denominator_scales = { 1, 1, }, \ 55 .aspect = VK_IMAGE_ASPECT_COLOR_BIT, \ 56 }, \ 57 }, \ 58 .vk_format = __vk_fmt, \ 59 .n_planes = 1, \ 60 } 61 62#define fmt1(__vk_fmt, __hw_fmt) \ 63 swiz_fmt1(__vk_fmt, __hw_fmt, RGBA) 64 65#define d_fmt(__vk_fmt, __hw_fmt) \ 66 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 67 .planes = { \ 68 { .isl_format = __hw_fmt, .swizzle = RGBA, \ 69 .denominator_scales = { 1, 1, }, \ 70 .aspect = VK_IMAGE_ASPECT_DEPTH_BIT, \ 71 }, \ 72 }, \ 73 .vk_format = __vk_fmt, \ 74 .n_planes = 1, \ 75 } 76 77#define s_fmt(__vk_fmt, __hw_fmt) \ 78 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 79 .planes = { \ 80 { .isl_format = __hw_fmt, .swizzle = RGBA, \ 81 .denominator_scales = { 1, 1, }, \ 82 .aspect = VK_IMAGE_ASPECT_STENCIL_BIT, \ 83 }, \ 84 }, \ 85 .vk_format = __vk_fmt, \ 86 .n_planes = 1, \ 87 } 88 89#define ds_fmt2(__vk_fmt, __fmt1, __fmt2) \ 90 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 91 .planes = { \ 92 { .isl_format = __fmt1, .swizzle = RGBA, \ 93 .denominator_scales = { 1, 1, }, \ 94 .aspect = VK_IMAGE_ASPECT_DEPTH_BIT, \ 95 }, \ 96 { .isl_format = __fmt2, .swizzle = RGBA, \ 97 .denominator_scales = { 1, 1, }, \ 98 .aspect = VK_IMAGE_ASPECT_STENCIL_BIT, \ 99 }, \ 100 }, \ 101 .vk_format = __vk_fmt, \ 102 .n_planes = 2, \ 103 } 104 105#define fmt_unsupported(__vk_fmt) \ 106 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 107 .planes = { \ 108 { .isl_format = ISL_FORMAT_UNSUPPORTED, }, \ 109 }, \ 110 .vk_format = VK_FORMAT_UNDEFINED, \ 111 } 112 113#define y_plane(__plane, __hw_fmt, __swizzle, __ycbcr_swizzle, dhs, dvs) \ 114 { .isl_format = __hw_fmt, \ 115 .swizzle = __swizzle, \ 116 .ycbcr_swizzle = __ycbcr_swizzle, \ 117 .denominator_scales = { dhs, dvs, }, \ 118 .has_chroma = false, \ 119 .aspect = VK_IMAGE_ASPECT_PLANE_0_BIT, /* Y plane is always plane 0 */ \ 120 } 121 122#define chroma_plane(__plane, __hw_fmt, __swizzle, __ycbcr_swizzle, dhs, dvs) \ 123 { .isl_format = __hw_fmt, \ 124 .swizzle = __swizzle, \ 125 .ycbcr_swizzle = __ycbcr_swizzle, \ 126 .denominator_scales = { dhs, dvs, }, \ 127 .has_chroma = true, \ 128 .aspect = VK_IMAGE_ASPECT_PLANE_ ## __plane ## _BIT, \ 129 } 130 131#define ycbcr_fmt(__vk_fmt, __n_planes, ...) \ 132 [VK_ENUM_OFFSET(__vk_fmt)] = { \ 133 .planes = { \ 134 __VA_ARGS__, \ 135 }, \ 136 .vk_format = __vk_fmt, \ 137 .n_planes = __n_planes, \ 138 .can_ycbcr = true, \ 139 } 140 141/* HINT: For array formats, the ISL name should match the VK name. For 142 * packed formats, they should have the channels in reverse order from each 143 * other. The reason for this is that, for packed formats, the ISL (and 144 * bspec) names are in LSB -> MSB order while VK formats are MSB -> LSB. 145 */ 146static const struct anv_format main_formats[] = { 147 fmt_unsupported(VK_FORMAT_UNDEFINED), 148 fmt_unsupported(VK_FORMAT_R4G4_UNORM_PACK8), 149 fmt1(VK_FORMAT_R4G4B4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM), 150 swiz_fmt1(VK_FORMAT_B4G4R4A4_UNORM_PACK16, ISL_FORMAT_A4B4G4R4_UNORM, BGRA), 151 fmt1(VK_FORMAT_R5G6B5_UNORM_PACK16, ISL_FORMAT_B5G6R5_UNORM), 152 fmt_unsupported(VK_FORMAT_B5G6R5_UNORM_PACK16), 153 fmt1(VK_FORMAT_R5G5B5A1_UNORM_PACK16, ISL_FORMAT_A1B5G5R5_UNORM), 154 fmt_unsupported(VK_FORMAT_B5G5R5A1_UNORM_PACK16), 155 fmt1(VK_FORMAT_A1R5G5B5_UNORM_PACK16, ISL_FORMAT_B5G5R5A1_UNORM), 156 fmt1(VK_FORMAT_R8_UNORM, ISL_FORMAT_R8_UNORM), 157 fmt1(VK_FORMAT_R8_SNORM, ISL_FORMAT_R8_SNORM), 158 fmt1(VK_FORMAT_R8_USCALED, ISL_FORMAT_R8_USCALED), 159 fmt1(VK_FORMAT_R8_SSCALED, ISL_FORMAT_R8_SSCALED), 160 fmt1(VK_FORMAT_R8_UINT, ISL_FORMAT_R8_UINT), 161 fmt1(VK_FORMAT_R8_SINT, ISL_FORMAT_R8_SINT), 162 swiz_fmt1(VK_FORMAT_R8_SRGB, ISL_FORMAT_L8_UNORM_SRGB, 163 _ISL_SWIZZLE(RED, ZERO, ZERO, ONE)), 164 fmt1(VK_FORMAT_R8G8_UNORM, ISL_FORMAT_R8G8_UNORM), 165 fmt1(VK_FORMAT_R8G8_SNORM, ISL_FORMAT_R8G8_SNORM), 166 fmt1(VK_FORMAT_R8G8_USCALED, ISL_FORMAT_R8G8_USCALED), 167 fmt1(VK_FORMAT_R8G8_SSCALED, ISL_FORMAT_R8G8_SSCALED), 168 fmt1(VK_FORMAT_R8G8_UINT, ISL_FORMAT_R8G8_UINT), 169 fmt1(VK_FORMAT_R8G8_SINT, ISL_FORMAT_R8G8_SINT), 170 fmt_unsupported(VK_FORMAT_R8G8_SRGB), /* L8A8_UNORM_SRGB */ 171 fmt1(VK_FORMAT_R8G8B8_UNORM, ISL_FORMAT_R8G8B8_UNORM), 172 fmt1(VK_FORMAT_R8G8B8_SNORM, ISL_FORMAT_R8G8B8_SNORM), 173 fmt1(VK_FORMAT_R8G8B8_USCALED, ISL_FORMAT_R8G8B8_USCALED), 174 fmt1(VK_FORMAT_R8G8B8_SSCALED, ISL_FORMAT_R8G8B8_SSCALED), 175 fmt1(VK_FORMAT_R8G8B8_UINT, ISL_FORMAT_R8G8B8_UINT), 176 fmt1(VK_FORMAT_R8G8B8_SINT, ISL_FORMAT_R8G8B8_SINT), 177 fmt1(VK_FORMAT_R8G8B8_SRGB, ISL_FORMAT_R8G8B8_UNORM_SRGB), 178 fmt1(VK_FORMAT_R8G8B8A8_UNORM, ISL_FORMAT_R8G8B8A8_UNORM), 179 fmt1(VK_FORMAT_R8G8B8A8_SNORM, ISL_FORMAT_R8G8B8A8_SNORM), 180 fmt1(VK_FORMAT_R8G8B8A8_USCALED, ISL_FORMAT_R8G8B8A8_USCALED), 181 fmt1(VK_FORMAT_R8G8B8A8_SSCALED, ISL_FORMAT_R8G8B8A8_SSCALED), 182 fmt1(VK_FORMAT_R8G8B8A8_UINT, ISL_FORMAT_R8G8B8A8_UINT), 183 fmt1(VK_FORMAT_R8G8B8A8_SINT, ISL_FORMAT_R8G8B8A8_SINT), 184 fmt1(VK_FORMAT_R8G8B8A8_SRGB, ISL_FORMAT_R8G8B8A8_UNORM_SRGB), 185 fmt1(VK_FORMAT_A8B8G8R8_UNORM_PACK32, ISL_FORMAT_R8G8B8A8_UNORM), 186 fmt1(VK_FORMAT_A8B8G8R8_SNORM_PACK32, ISL_FORMAT_R8G8B8A8_SNORM), 187 fmt1(VK_FORMAT_A8B8G8R8_USCALED_PACK32, ISL_FORMAT_R8G8B8A8_USCALED), 188 fmt1(VK_FORMAT_A8B8G8R8_SSCALED_PACK32, ISL_FORMAT_R8G8B8A8_SSCALED), 189 fmt1(VK_FORMAT_A8B8G8R8_UINT_PACK32, ISL_FORMAT_R8G8B8A8_UINT), 190 fmt1(VK_FORMAT_A8B8G8R8_SINT_PACK32, ISL_FORMAT_R8G8B8A8_SINT), 191 fmt1(VK_FORMAT_A8B8G8R8_SRGB_PACK32, ISL_FORMAT_R8G8B8A8_UNORM_SRGB), 192 fmt1(VK_FORMAT_A2R10G10B10_UNORM_PACK32, ISL_FORMAT_B10G10R10A2_UNORM), 193 fmt1(VK_FORMAT_A2R10G10B10_SNORM_PACK32, ISL_FORMAT_B10G10R10A2_SNORM), 194 fmt1(VK_FORMAT_A2R10G10B10_USCALED_PACK32, ISL_FORMAT_B10G10R10A2_USCALED), 195 fmt1(VK_FORMAT_A2R10G10B10_SSCALED_PACK32, ISL_FORMAT_B10G10R10A2_SSCALED), 196 fmt1(VK_FORMAT_A2R10G10B10_UINT_PACK32, ISL_FORMAT_B10G10R10A2_UINT), 197 fmt1(VK_FORMAT_A2R10G10B10_SINT_PACK32, ISL_FORMAT_B10G10R10A2_SINT), 198 fmt1(VK_FORMAT_A2B10G10R10_UNORM_PACK32, ISL_FORMAT_R10G10B10A2_UNORM), 199 fmt1(VK_FORMAT_A2B10G10R10_SNORM_PACK32, ISL_FORMAT_R10G10B10A2_SNORM), 200 fmt1(VK_FORMAT_A2B10G10R10_USCALED_PACK32, ISL_FORMAT_R10G10B10A2_USCALED), 201 fmt1(VK_FORMAT_A2B10G10R10_SSCALED_PACK32, ISL_FORMAT_R10G10B10A2_SSCALED), 202 fmt1(VK_FORMAT_A2B10G10R10_UINT_PACK32, ISL_FORMAT_R10G10B10A2_UINT), 203 fmt1(VK_FORMAT_A2B10G10R10_SINT_PACK32, ISL_FORMAT_R10G10B10A2_SINT), 204 fmt1(VK_FORMAT_R16_UNORM, ISL_FORMAT_R16_UNORM), 205 fmt1(VK_FORMAT_R16_SNORM, ISL_FORMAT_R16_SNORM), 206 fmt1(VK_FORMAT_R16_USCALED, ISL_FORMAT_R16_USCALED), 207 fmt1(VK_FORMAT_R16_SSCALED, ISL_FORMAT_R16_SSCALED), 208 fmt1(VK_FORMAT_R16_UINT, ISL_FORMAT_R16_UINT), 209 fmt1(VK_FORMAT_R16_SINT, ISL_FORMAT_R16_SINT), 210 fmt1(VK_FORMAT_R16_SFLOAT, ISL_FORMAT_R16_FLOAT), 211 fmt1(VK_FORMAT_R16G16_UNORM, ISL_FORMAT_R16G16_UNORM), 212 fmt1(VK_FORMAT_R16G16_SNORM, ISL_FORMAT_R16G16_SNORM), 213 fmt1(VK_FORMAT_R16G16_USCALED, ISL_FORMAT_R16G16_USCALED), 214 fmt1(VK_FORMAT_R16G16_SSCALED, ISL_FORMAT_R16G16_SSCALED), 215 fmt1(VK_FORMAT_R16G16_UINT, ISL_FORMAT_R16G16_UINT), 216 fmt1(VK_FORMAT_R16G16_SINT, ISL_FORMAT_R16G16_SINT), 217 fmt1(VK_FORMAT_R16G16_SFLOAT, ISL_FORMAT_R16G16_FLOAT), 218 fmt1(VK_FORMAT_R16G16B16_UNORM, ISL_FORMAT_R16G16B16_UNORM), 219 fmt1(VK_FORMAT_R16G16B16_SNORM, ISL_FORMAT_R16G16B16_SNORM), 220 fmt1(VK_FORMAT_R16G16B16_USCALED, ISL_FORMAT_R16G16B16_USCALED), 221 fmt1(VK_FORMAT_R16G16B16_SSCALED, ISL_FORMAT_R16G16B16_SSCALED), 222 fmt1(VK_FORMAT_R16G16B16_UINT, ISL_FORMAT_R16G16B16_UINT), 223 fmt1(VK_FORMAT_R16G16B16_SINT, ISL_FORMAT_R16G16B16_SINT), 224 fmt1(VK_FORMAT_R16G16B16_SFLOAT, ISL_FORMAT_R16G16B16_FLOAT), 225 fmt1(VK_FORMAT_R16G16B16A16_UNORM, ISL_FORMAT_R16G16B16A16_UNORM), 226 fmt1(VK_FORMAT_R16G16B16A16_SNORM, ISL_FORMAT_R16G16B16A16_SNORM), 227 fmt1(VK_FORMAT_R16G16B16A16_USCALED, ISL_FORMAT_R16G16B16A16_USCALED), 228 fmt1(VK_FORMAT_R16G16B16A16_SSCALED, ISL_FORMAT_R16G16B16A16_SSCALED), 229 fmt1(VK_FORMAT_R16G16B16A16_UINT, ISL_FORMAT_R16G16B16A16_UINT), 230 fmt1(VK_FORMAT_R16G16B16A16_SINT, ISL_FORMAT_R16G16B16A16_SINT), 231 fmt1(VK_FORMAT_R16G16B16A16_SFLOAT, ISL_FORMAT_R16G16B16A16_FLOAT), 232 fmt1(VK_FORMAT_R32_UINT, ISL_FORMAT_R32_UINT), 233 fmt1(VK_FORMAT_R32_SINT, ISL_FORMAT_R32_SINT), 234 fmt1(VK_FORMAT_R32_SFLOAT, ISL_FORMAT_R32_FLOAT), 235 fmt1(VK_FORMAT_R32G32_UINT, ISL_FORMAT_R32G32_UINT), 236 fmt1(VK_FORMAT_R32G32_SINT, ISL_FORMAT_R32G32_SINT), 237 fmt1(VK_FORMAT_R32G32_SFLOAT, ISL_FORMAT_R32G32_FLOAT), 238 fmt1(VK_FORMAT_R32G32B32_UINT, ISL_FORMAT_R32G32B32_UINT), 239 fmt1(VK_FORMAT_R32G32B32_SINT, ISL_FORMAT_R32G32B32_SINT), 240 fmt1(VK_FORMAT_R32G32B32_SFLOAT, ISL_FORMAT_R32G32B32_FLOAT), 241 fmt1(VK_FORMAT_R32G32B32A32_UINT, ISL_FORMAT_R32G32B32A32_UINT), 242 fmt1(VK_FORMAT_R32G32B32A32_SINT, ISL_FORMAT_R32G32B32A32_SINT), 243 fmt1(VK_FORMAT_R32G32B32A32_SFLOAT, ISL_FORMAT_R32G32B32A32_FLOAT), 244 fmt1(VK_FORMAT_R64_UINT, ISL_FORMAT_R64_PASSTHRU), 245 fmt1(VK_FORMAT_R64_SINT, ISL_FORMAT_R64_PASSTHRU), 246 fmt1(VK_FORMAT_R64_SFLOAT, ISL_FORMAT_R64_PASSTHRU), 247 fmt1(VK_FORMAT_R64G64_UINT, ISL_FORMAT_R64G64_PASSTHRU), 248 fmt1(VK_FORMAT_R64G64_SINT, ISL_FORMAT_R64G64_PASSTHRU), 249 fmt1(VK_FORMAT_R64G64_SFLOAT, ISL_FORMAT_R64G64_PASSTHRU), 250 fmt1(VK_FORMAT_R64G64B64_UINT, ISL_FORMAT_R64G64B64_PASSTHRU), 251 fmt1(VK_FORMAT_R64G64B64_SINT, ISL_FORMAT_R64G64B64_PASSTHRU), 252 fmt1(VK_FORMAT_R64G64B64_SFLOAT, ISL_FORMAT_R64G64B64_PASSTHRU), 253 fmt1(VK_FORMAT_R64G64B64A64_UINT, ISL_FORMAT_R64G64B64A64_PASSTHRU), 254 fmt1(VK_FORMAT_R64G64B64A64_SINT, ISL_FORMAT_R64G64B64A64_PASSTHRU), 255 fmt1(VK_FORMAT_R64G64B64A64_SFLOAT, ISL_FORMAT_R64G64B64A64_PASSTHRU), 256 fmt1(VK_FORMAT_B10G11R11_UFLOAT_PACK32, ISL_FORMAT_R11G11B10_FLOAT), 257 fmt1(VK_FORMAT_E5B9G9R9_UFLOAT_PACK32, ISL_FORMAT_R9G9B9E5_SHAREDEXP), 258 259 d_fmt(VK_FORMAT_D16_UNORM, ISL_FORMAT_R16_UNORM), 260 d_fmt(VK_FORMAT_X8_D24_UNORM_PACK32, ISL_FORMAT_R24_UNORM_X8_TYPELESS), 261 d_fmt(VK_FORMAT_D32_SFLOAT, ISL_FORMAT_R32_FLOAT), 262 s_fmt(VK_FORMAT_S8_UINT, ISL_FORMAT_R8_UINT), 263 fmt_unsupported(VK_FORMAT_D16_UNORM_S8_UINT), 264 ds_fmt2(VK_FORMAT_D24_UNORM_S8_UINT, ISL_FORMAT_R24_UNORM_X8_TYPELESS, ISL_FORMAT_R8_UINT), 265 ds_fmt2(VK_FORMAT_D32_SFLOAT_S8_UINT, ISL_FORMAT_R32_FLOAT, ISL_FORMAT_R8_UINT), 266 267 swiz_fmt1(VK_FORMAT_BC1_RGB_UNORM_BLOCK, ISL_FORMAT_BC1_UNORM, RGB1), 268 swiz_fmt1(VK_FORMAT_BC1_RGB_SRGB_BLOCK, ISL_FORMAT_BC1_UNORM_SRGB, RGB1), 269 fmt1(VK_FORMAT_BC1_RGBA_UNORM_BLOCK, ISL_FORMAT_BC1_UNORM), 270 fmt1(VK_FORMAT_BC1_RGBA_SRGB_BLOCK, ISL_FORMAT_BC1_UNORM_SRGB), 271 fmt1(VK_FORMAT_BC2_UNORM_BLOCK, ISL_FORMAT_BC2_UNORM), 272 fmt1(VK_FORMAT_BC2_SRGB_BLOCK, ISL_FORMAT_BC2_UNORM_SRGB), 273 fmt1(VK_FORMAT_BC3_UNORM_BLOCK, ISL_FORMAT_BC3_UNORM), 274 fmt1(VK_FORMAT_BC3_SRGB_BLOCK, ISL_FORMAT_BC3_UNORM_SRGB), 275 fmt1(VK_FORMAT_BC4_UNORM_BLOCK, ISL_FORMAT_BC4_UNORM), 276 fmt1(VK_FORMAT_BC4_SNORM_BLOCK, ISL_FORMAT_BC4_SNORM), 277 fmt1(VK_FORMAT_BC5_UNORM_BLOCK, ISL_FORMAT_BC5_UNORM), 278 fmt1(VK_FORMAT_BC5_SNORM_BLOCK, ISL_FORMAT_BC5_SNORM), 279 fmt1(VK_FORMAT_BC6H_UFLOAT_BLOCK, ISL_FORMAT_BC6H_UF16), 280 fmt1(VK_FORMAT_BC6H_SFLOAT_BLOCK, ISL_FORMAT_BC6H_SF16), 281 fmt1(VK_FORMAT_BC7_UNORM_BLOCK, ISL_FORMAT_BC7_UNORM), 282 fmt1(VK_FORMAT_BC7_SRGB_BLOCK, ISL_FORMAT_BC7_UNORM_SRGB), 283 fmt1(VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK, ISL_FORMAT_ETC2_RGB8), 284 fmt1(VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK, ISL_FORMAT_ETC2_SRGB8), 285 fmt1(VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK, ISL_FORMAT_ETC2_RGB8_PTA), 286 fmt1(VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK, ISL_FORMAT_ETC2_SRGB8_PTA), 287 fmt1(VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK, ISL_FORMAT_ETC2_EAC_RGBA8), 288 fmt1(VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK, ISL_FORMAT_ETC2_EAC_SRGB8_A8), 289 fmt1(VK_FORMAT_EAC_R11_UNORM_BLOCK, ISL_FORMAT_EAC_R11), 290 fmt1(VK_FORMAT_EAC_R11_SNORM_BLOCK, ISL_FORMAT_EAC_SIGNED_R11), 291 fmt1(VK_FORMAT_EAC_R11G11_UNORM_BLOCK, ISL_FORMAT_EAC_RG11), 292 fmt1(VK_FORMAT_EAC_R11G11_SNORM_BLOCK, ISL_FORMAT_EAC_SIGNED_RG11), 293 fmt1(VK_FORMAT_ASTC_4x4_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_4X4_U8SRGB), 294 fmt1(VK_FORMAT_ASTC_5x4_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_5X4_U8SRGB), 295 fmt1(VK_FORMAT_ASTC_5x5_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_5X5_U8SRGB), 296 fmt1(VK_FORMAT_ASTC_6x5_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_6X5_U8SRGB), 297 fmt1(VK_FORMAT_ASTC_6x6_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_6X6_U8SRGB), 298 fmt1(VK_FORMAT_ASTC_8x5_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X5_U8SRGB), 299 fmt1(VK_FORMAT_ASTC_8x6_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X6_U8SRGB), 300 fmt1(VK_FORMAT_ASTC_8x8_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X8_U8SRGB), 301 fmt1(VK_FORMAT_ASTC_10x5_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X5_U8SRGB), 302 fmt1(VK_FORMAT_ASTC_10x6_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X6_U8SRGB), 303 fmt1(VK_FORMAT_ASTC_10x8_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X8_U8SRGB), 304 fmt1(VK_FORMAT_ASTC_10x10_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X10_U8SRGB), 305 fmt1(VK_FORMAT_ASTC_12x10_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_12X10_U8SRGB), 306 fmt1(VK_FORMAT_ASTC_12x12_SRGB_BLOCK, ISL_FORMAT_ASTC_LDR_2D_12X12_U8SRGB), 307 fmt1(VK_FORMAT_ASTC_4x4_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_4X4_FLT16), 308 fmt1(VK_FORMAT_ASTC_5x4_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_5X4_FLT16), 309 fmt1(VK_FORMAT_ASTC_5x5_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_5X5_FLT16), 310 fmt1(VK_FORMAT_ASTC_6x5_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_6X5_FLT16), 311 fmt1(VK_FORMAT_ASTC_6x6_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_6X6_FLT16), 312 fmt1(VK_FORMAT_ASTC_8x5_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X5_FLT16), 313 fmt1(VK_FORMAT_ASTC_8x6_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X6_FLT16), 314 fmt1(VK_FORMAT_ASTC_8x8_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_8X8_FLT16), 315 fmt1(VK_FORMAT_ASTC_10x5_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X5_FLT16), 316 fmt1(VK_FORMAT_ASTC_10x6_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X6_FLT16), 317 fmt1(VK_FORMAT_ASTC_10x8_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X8_FLT16), 318 fmt1(VK_FORMAT_ASTC_10x10_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_10X10_FLT16), 319 fmt1(VK_FORMAT_ASTC_12x10_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_12X10_FLT16), 320 fmt1(VK_FORMAT_ASTC_12x12_UNORM_BLOCK, ISL_FORMAT_ASTC_LDR_2D_12X12_FLT16), 321 fmt_unsupported(VK_FORMAT_B8G8R8_UNORM), 322 fmt_unsupported(VK_FORMAT_B8G8R8_SNORM), 323 fmt_unsupported(VK_FORMAT_B8G8R8_USCALED), 324 fmt_unsupported(VK_FORMAT_B8G8R8_SSCALED), 325 fmt_unsupported(VK_FORMAT_B8G8R8_UINT), 326 fmt_unsupported(VK_FORMAT_B8G8R8_SINT), 327 fmt_unsupported(VK_FORMAT_B8G8R8_SRGB), 328 fmt1(VK_FORMAT_B8G8R8A8_UNORM, ISL_FORMAT_B8G8R8A8_UNORM), 329 fmt_unsupported(VK_FORMAT_B8G8R8A8_SNORM), 330 fmt_unsupported(VK_FORMAT_B8G8R8A8_USCALED), 331 fmt_unsupported(VK_FORMAT_B8G8R8A8_SSCALED), 332 fmt_unsupported(VK_FORMAT_B8G8R8A8_UINT), 333 fmt_unsupported(VK_FORMAT_B8G8R8A8_SINT), 334 fmt1(VK_FORMAT_B8G8R8A8_SRGB, ISL_FORMAT_B8G8R8A8_UNORM_SRGB), 335}; 336 337static const struct anv_format _4444_formats[] = { 338 fmt1(VK_FORMAT_A4R4G4B4_UNORM_PACK16_EXT, ISL_FORMAT_B4G4R4A4_UNORM), 339 fmt_unsupported(VK_FORMAT_A4B4G4R4_UNORM_PACK16_EXT), 340}; 341 342static const struct anv_format ycbcr_formats[] = { 343 ycbcr_fmt(VK_FORMAT_G8B8G8R8_422_UNORM, 1, 344 y_plane(0, ISL_FORMAT_YCRCB_SWAPUV, RGBA, _ISL_SWIZZLE(BLUE, GREEN, RED, ZERO), 1, 1)), 345 ycbcr_fmt(VK_FORMAT_B8G8R8G8_422_UNORM, 1, 346 y_plane(0, ISL_FORMAT_YCRCB_SWAPUVY, RGBA, _ISL_SWIZZLE(BLUE, GREEN, RED, ZERO), 1, 1)), 347 ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM, 3, 348 y_plane(0, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 349 chroma_plane(1, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 2), 350 chroma_plane(2, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 2)), 351 ycbcr_fmt(VK_FORMAT_G8_B8R8_2PLANE_420_UNORM, 2, 352 y_plane(0, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 353 chroma_plane(1, ISL_FORMAT_R8G8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 2)), 354 ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_422_UNORM, 3, 355 y_plane(0, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 356 chroma_plane(1, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 1), 357 chroma_plane(2, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 1)), 358 ycbcr_fmt(VK_FORMAT_G8_B8R8_2PLANE_422_UNORM, 2, 359 y_plane(0, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 360 chroma_plane(1, ISL_FORMAT_R8G8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 1)), 361 ycbcr_fmt(VK_FORMAT_G8_B8_R8_3PLANE_444_UNORM, 3, 362 y_plane(0, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 363 chroma_plane(1, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 1, 1), 364 chroma_plane(2, ISL_FORMAT_R8_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 1, 1)), 365 366 fmt_unsupported(VK_FORMAT_R10X6_UNORM_PACK16), 367 fmt_unsupported(VK_FORMAT_R10X6G10X6_UNORM_2PACK16), 368 fmt_unsupported(VK_FORMAT_R10X6G10X6B10X6A10X6_UNORM_4PACK16), 369 fmt_unsupported(VK_FORMAT_G10X6B10X6G10X6R10X6_422_UNORM_4PACK16), 370 fmt_unsupported(VK_FORMAT_B10X6G10X6R10X6G10X6_422_UNORM_4PACK16), 371 fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_420_UNORM_3PACK16), 372 fmt_unsupported(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_420_UNORM_3PACK16), 373 fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_422_UNORM_3PACK16), 374 fmt_unsupported(VK_FORMAT_G10X6_B10X6R10X6_2PLANE_422_UNORM_3PACK16), 375 fmt_unsupported(VK_FORMAT_G10X6_B10X6_R10X6_3PLANE_444_UNORM_3PACK16), 376 fmt_unsupported(VK_FORMAT_R12X4_UNORM_PACK16), 377 fmt_unsupported(VK_FORMAT_R12X4G12X4_UNORM_2PACK16), 378 fmt_unsupported(VK_FORMAT_R12X4G12X4B12X4A12X4_UNORM_4PACK16), 379 fmt_unsupported(VK_FORMAT_G12X4B12X4G12X4R12X4_422_UNORM_4PACK16), 380 fmt_unsupported(VK_FORMAT_B12X4G12X4R12X4G12X4_422_UNORM_4PACK16), 381 fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_420_UNORM_3PACK16), 382 fmt_unsupported(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_420_UNORM_3PACK16), 383 fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_422_UNORM_3PACK16), 384 fmt_unsupported(VK_FORMAT_G12X4_B12X4R12X4_2PLANE_422_UNORM_3PACK16), 385 fmt_unsupported(VK_FORMAT_G12X4_B12X4_R12X4_3PLANE_444_UNORM_3PACK16), 386 /* TODO: it is possible to enable the following 2 formats, but that 387 * requires further refactoring of how we handle multiplanar formats. 388 */ 389 fmt_unsupported(VK_FORMAT_G16B16G16R16_422_UNORM), 390 fmt_unsupported(VK_FORMAT_B16G16R16G16_422_UNORM), 391 392 ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_420_UNORM, 3, 393 y_plane(0, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 394 chroma_plane(1, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 2), 395 chroma_plane(2, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 2)), 396 ycbcr_fmt(VK_FORMAT_G16_B16R16_2PLANE_420_UNORM, 2, 397 y_plane(0, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 398 chroma_plane(1, ISL_FORMAT_R16G16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 2)), 399 ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_422_UNORM, 3, 400 y_plane(0, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 401 chroma_plane(1, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 2, 1), 402 chroma_plane(2, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 2, 1)), 403 ycbcr_fmt(VK_FORMAT_G16_B16R16_2PLANE_422_UNORM, 2, 404 y_plane(0, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 405 chroma_plane(1, ISL_FORMAT_R16G16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, RED, ZERO, ZERO), 2, 1)), 406 ycbcr_fmt(VK_FORMAT_G16_B16_R16_3PLANE_444_UNORM, 3, 407 y_plane(0, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(GREEN, ZERO, ZERO, ZERO), 1, 1), 408 chroma_plane(1, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(BLUE, ZERO, ZERO, ZERO), 1, 1), 409 chroma_plane(2, ISL_FORMAT_R16_UNORM, RGBA, _ISL_SWIZZLE(RED, ZERO, ZERO, ZERO), 1, 1)), 410}; 411 412#undef _fmt 413#undef swiz_fmt1 414#undef fmt1 415#undef fmt 416 417static const struct { 418 const struct anv_format *formats; 419 uint32_t n_formats; 420} anv_formats[] = { 421 [0] = { .formats = main_formats, 422 .n_formats = ARRAY_SIZE(main_formats), }, 423 [_VK_EXT_4444_formats_number] = { .formats = _4444_formats, 424 .n_formats = ARRAY_SIZE(_4444_formats), }, 425 [_VK_KHR_sampler_ycbcr_conversion_number] = { .formats = ycbcr_formats, 426 .n_formats = ARRAY_SIZE(ycbcr_formats), }, 427}; 428 429const struct anv_format * 430anv_get_format(VkFormat vk_format) 431{ 432 uint32_t enum_offset = VK_ENUM_OFFSET(vk_format); 433 uint32_t ext_number = VK_ENUM_EXTENSION(vk_format); 434 435 if (ext_number >= ARRAY_SIZE(anv_formats) || 436 enum_offset >= anv_formats[ext_number].n_formats) 437 return NULL; 438 439 const struct anv_format *format = 440 &anv_formats[ext_number].formats[enum_offset]; 441 if (format->planes[0].isl_format == ISL_FORMAT_UNSUPPORTED) 442 return NULL; 443 444 return format; 445} 446 447/** Return true if any format plane has non-power-of-two bits-per-block. */ 448static bool 449anv_format_has_npot_plane(const struct anv_format *anv_format) { 450 for (uint32_t i = 0; i < anv_format->n_planes; ++i) { 451 const struct isl_format_layout *isl_layout = 452 isl_format_get_layout(anv_format->planes[i].isl_format); 453 454 if (!util_is_power_of_two_or_zero(isl_layout->bpb)) 455 return true; 456 } 457 458 return false; 459} 460 461/** 462 * Exactly one bit must be set in \a aspect. 463 * 464 * If tiling is VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, then return the 465 * requested anv_format_plane without checking for compatibility with modifiers. 466 * It is the caller's responsibility to verify that the the returned 467 * anv_format_plane is compatible with a particular modifier. (Observe that 468 * this function has no parameter for the DRM format modifier, and therefore 469 * _cannot_ check for compatibility). 470 */ 471struct anv_format_plane 472anv_get_format_plane(const struct intel_device_info *devinfo, 473 VkFormat vk_format, uint32_t plane, 474 VkImageTiling tiling) 475{ 476 const struct anv_format *format = anv_get_format(vk_format); 477 const struct anv_format_plane unsupported = { 478 .isl_format = ISL_FORMAT_UNSUPPORTED, 479 }; 480 481 if (format == NULL) 482 return unsupported; 483 484 assert(plane < format->n_planes); 485 struct anv_format_plane plane_format = format->planes[plane]; 486 if (plane_format.isl_format == ISL_FORMAT_UNSUPPORTED) 487 return unsupported; 488 489 if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 490 return plane_format; 491 492 if (vk_format_is_depth_or_stencil(vk_format)) 493 return plane_format; 494 495 const struct isl_format_layout *isl_layout = 496 isl_format_get_layout(plane_format.isl_format); 497 498 /* On Ivy Bridge we don't even have enough 24 and 48-bit formats that we 499 * can reliably do texture upload with BLORP so just don't claim support 500 * for any of them. 501 */ 502 if (devinfo->verx10 == 70 && 503 (isl_layout->bpb == 24 || isl_layout->bpb == 48)) 504 return unsupported; 505 506 if (tiling == VK_IMAGE_TILING_OPTIMAL && 507 !util_is_power_of_two_or_zero(isl_layout->bpb)) { 508 /* Tiled formats *must* be power-of-two because we need up upload 509 * them with the render pipeline. For 3-channel formats, we fix 510 * this by switching them over to RGBX or RGBA formats under the 511 * hood. 512 */ 513 enum isl_format rgbx = isl_format_rgb_to_rgbx(plane_format.isl_format); 514 if (rgbx != ISL_FORMAT_UNSUPPORTED && 515 isl_format_supports_rendering(devinfo, rgbx)) { 516 plane_format.isl_format = rgbx; 517 } else { 518 plane_format.isl_format = 519 isl_format_rgb_to_rgba(plane_format.isl_format); 520 plane_format.swizzle = ISL_SWIZZLE(RED, GREEN, BLUE, ONE); 521 } 522 } 523 524 /* The B4G4R4A4 format isn't available prior to Broadwell so we have to fall 525 * back to a format with a more complex swizzle. 526 */ 527 if (vk_format == VK_FORMAT_B4G4R4A4_UNORM_PACK16 && devinfo->ver < 8) { 528 plane_format.isl_format = ISL_FORMAT_B4G4R4A4_UNORM; 529 plane_format.swizzle = ISL_SWIZZLE(GREEN, RED, ALPHA, BLUE); 530 } 531 532 return plane_format; 533} 534 535struct anv_format_plane 536anv_get_format_aspect(const struct intel_device_info *devinfo, 537 VkFormat vk_format, 538 VkImageAspectFlagBits aspect, VkImageTiling tiling) 539{ 540 const uint32_t plane = 541 anv_aspect_to_plane(vk_format_aspects(vk_format), aspect); 542 return anv_get_format_plane(devinfo, vk_format, plane, tiling); 543} 544 545// Format capabilities 546 547VkFormatFeatureFlags2KHR 548anv_get_image_format_features2(const struct intel_device_info *devinfo, 549 VkFormat vk_format, 550 const struct anv_format *anv_format, 551 VkImageTiling vk_tiling, 552 const struct isl_drm_modifier_info *isl_mod_info) 553{ 554 VkFormatFeatureFlags2KHR flags = 0; 555 556 if (anv_format == NULL) 557 return 0; 558 559 assert((isl_mod_info != NULL) == 560 (vk_tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)); 561 562 const VkImageAspectFlags aspects = vk_format_aspects(vk_format); 563 564 if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 565 if (vk_tiling == VK_IMAGE_TILING_LINEAR || 566 vk_tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 567 return 0; 568 569 flags |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR | 570 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR | 571 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR | 572 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR | 573 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | 574 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR; 575 576 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 577 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR; 578 579 if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && devinfo->ver >= 9) 580 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR; 581 582 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 583 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT_KHR; 584 585 return flags; 586 } 587 588 assert(aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 589 const struct anv_format_plane plane_format = 590 anv_get_format_plane(devinfo, vk_format, 0, vk_tiling); 591 592 if (plane_format.isl_format == ISL_FORMAT_UNSUPPORTED) 593 return 0; 594 595 struct anv_format_plane base_plane_format = plane_format; 596 if (vk_tiling != VK_IMAGE_TILING_LINEAR) { 597 base_plane_format = anv_get_format_plane(devinfo, vk_format, 0, 598 VK_IMAGE_TILING_LINEAR); 599 } 600 601 enum isl_format base_isl_format = base_plane_format.isl_format; 602 603 /* ASTC textures must be in Y-tiled memory, and we reject compressed formats 604 * with modifiers. 605 */ 606 if (vk_tiling != VK_IMAGE_TILING_OPTIMAL && 607 isl_format_get_layout(plane_format.isl_format)->txc == ISL_TXC_ASTC) 608 return 0; 609 610 if (isl_format_supports_sampling(devinfo, plane_format.isl_format)) { 611 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR; 612 613 if (devinfo->ver >= 9) 614 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT_KHR; 615 616 if (isl_format_supports_filtering(devinfo, plane_format.isl_format)) 617 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT_KHR; 618 } 619 620 /* We can render to swizzled formats. However, if the alpha channel is 621 * moved, then blending won't work correctly. The PRM tells us 622 * straight-up not to render to such a surface. 623 */ 624 if (isl_format_supports_rendering(devinfo, plane_format.isl_format) && 625 plane_format.swizzle.a == ISL_CHANNEL_SELECT_ALPHA) { 626 flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR; 627 628 if (isl_format_supports_alpha_blending(devinfo, plane_format.isl_format)) 629 flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR; 630 } 631 632 /* Load/store is determined based on base format. This prevents RGB 633 * formats from showing up as load/store capable. 634 */ 635 if (isl_format_supports_typed_reads(devinfo, base_isl_format)) 636 flags |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT_KHR; 637 if (isl_format_supports_typed_writes(devinfo, base_isl_format)) 638 flags |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR; 639 640 /* Keep this old behavior on VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR. 641 * When KHR_format_features2 is enabled, applications should only rely on 642 * it for the list of shader storage extended formats [1]. Before that, 643 * this applies to all VkFormats. 644 * 645 * [1] : https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#features-shaderStorageImageExtendedFormats 646 */ 647 if (flags & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT_KHR) 648 flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR; 649 650 if (base_isl_format == ISL_FORMAT_R32_SINT || 651 base_isl_format == ISL_FORMAT_R32_UINT || 652 base_isl_format == ISL_FORMAT_R32_FLOAT) 653 flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR; 654 655 if (flags) { 656 flags |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR | 657 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT_KHR | 658 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT_KHR; 659 660 /* Blit destination requires rendering support. */ 661 if (isl_format_supports_rendering(devinfo, plane_format.isl_format)) 662 flags |= VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR; 663 } 664 665 /* XXX: We handle 3-channel formats by switching them out for RGBX or 666 * RGBA formats behind-the-scenes. This works fine for textures 667 * because the upload process will fill in the extra channel. 668 * We could also support it for render targets, but it will take 669 * substantially more work and we have enough RGBX formats to handle 670 * what most clients will want. 671 */ 672 if (vk_tiling == VK_IMAGE_TILING_OPTIMAL && 673 base_isl_format != ISL_FORMAT_UNSUPPORTED && 674 !util_is_power_of_two_or_zero(isl_format_layouts[base_isl_format].bpb) && 675 isl_format_rgb_to_rgbx(base_isl_format) == ISL_FORMAT_UNSUPPORTED) { 676 flags &= ~VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR; 677 flags &= ~VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR; 678 } 679 680 if (anv_format->can_ycbcr) { 681 /* The sampler doesn't have support for mid point when it handles YUV on 682 * its own. 683 */ 684 if (isl_format_is_yuv(anv_format->planes[0].isl_format)) { 685 /* TODO: We've disabled linear implicit reconstruction with the 686 * sampler. The failures show a slightly out of range values on the 687 * bottom left of the sampled image. 688 */ 689 flags |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR; 690 } else { 691 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT_KHR | 692 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT_KHR | 693 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT_KHR; 694 } 695 696 /* We can support cosited chroma locations when handle planes with our 697 * own shader snippets. 698 */ 699 for (unsigned p = 0; p < anv_format->n_planes; p++) { 700 if (anv_format->planes[p].denominator_scales[0] > 1 || 701 anv_format->planes[p].denominator_scales[1] > 1) { 702 flags |= VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT_KHR; 703 break; 704 } 705 } 706 707 if (anv_format->n_planes > 1) 708 flags |= VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR; 709 710 const VkFormatFeatureFlags2KHR disallowed_ycbcr_image_features = 711 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT_KHR | 712 VK_FORMAT_FEATURE_2_BLIT_DST_BIT_KHR | 713 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR | 714 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT_KHR | 715 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR; 716 717 flags &= ~disallowed_ycbcr_image_features; 718 } 719 720 if (vk_tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 721 if (!isl_drm_modifier_get_score(devinfo, isl_mod_info->modifier)) 722 return 0; 723 724 /* Try to restrict the supported formats to those in drm_fourcc.h. The 725 * VK_EXT_image_drm_format_modifier does not require this (after all, two 726 * Vulkan apps could share an image by exchanging its VkFormat instead of 727 * a DRM_FORMAT), but there exist no users of such non-drm_fourcc formats 728 * yet. And the restriction shrinks our test surface. 729 */ 730 const struct isl_format_layout *isl_layout = 731 isl_format_get_layout(plane_format.isl_format); 732 733 switch (isl_layout->colorspace) { 734 case ISL_COLORSPACE_LINEAR: 735 case ISL_COLORSPACE_SRGB: 736 /* Each DRM_FORMAT that we support uses unorm (if the DRM format name 737 * has no type suffix) or sfloat (if it has suffix F). No format 738 * contains mixed types. (as of 2021-06-14) 739 */ 740 if (isl_layout->uniform_channel_type != ISL_UNORM && 741 isl_layout->uniform_channel_type != ISL_SFLOAT) 742 return 0; 743 break; 744 case ISL_COLORSPACE_YUV: 745 anv_finishme("support YUV colorspace with DRM format modifiers"); 746 return 0; 747 case ISL_COLORSPACE_NONE: 748 return 0; 749 } 750 751 /* We could support compressed formats if we wanted to. */ 752 if (isl_format_is_compressed(plane_format.isl_format)) 753 return 0; 754 755 /* No non-power-of-two fourcc formats exist. 756 * 757 * Even if non-power-of-two fourcc formats existed, we could support them 758 * only with DRM_FORMAT_MOD_LINEAR. Tiled formats must be power-of-two 759 * because we implement transfers with the render pipeline. 760 */ 761 if (anv_format_has_npot_plane(anv_format)) 762 return 0; 763 764 if (anv_format->n_planes > 1) { 765 /* For simplicity, keep DISJOINT disabled for multi-planar format. */ 766 flags &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR; 767 768 /* VK_ANDROID_external_memory_android_hardware_buffer in Virtio-GPU 769 * Venus driver layers on top of VK_EXT_image_drm_format_modifier of 770 * the host Vulkan driver, and VK_FORMAT_G8_B8R8_2PLANE_420_UNORM is 771 * required to support camera/media interop in Android. 772 */ 773 if (vk_format != VK_FORMAT_G8_B8R8_2PLANE_420_UNORM) { 774 anv_finishme("support more multi-planar formats with DRM modifiers"); 775 return 0; 776 } 777 778 /* Currently there is no way to properly map memory planes to format 779 * planes and aux planes due to the lack of defined ABI for external 780 * multi-planar images. 781 */ 782 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 783 return 0; 784 } 785 } 786 787 if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E && 788 !isl_format_supports_ccs_e(devinfo, plane_format.isl_format)) { 789 return 0; 790 } 791 792 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 793 /* Rejection DISJOINT for consistency with the GL driver. In 794 * eglCreateImage, we require that the dma_buf for the primary surface 795 * and the dma_buf for its aux surface refer to the same bo. 796 */ 797 flags &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR; 798 799 /* When the hardware accesses a storage image, it bypasses the aux 800 * surface. We could support storage access on images with aux 801 * modifiers by resolving the aux surface prior to the storage access. 802 */ 803 flags &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR; 804 flags &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT_KHR; 805 } 806 } 807 808 return flags; 809} 810 811static VkFormatFeatureFlags2KHR 812get_buffer_format_features2(const struct intel_device_info *devinfo, 813 VkFormat vk_format, 814 const struct anv_format *anv_format) 815{ 816 VkFormatFeatureFlags2KHR flags = 0; 817 818 if (anv_format == NULL) 819 return 0; 820 821 const enum isl_format isl_format = anv_format->planes[0].isl_format; 822 823 if (isl_format == ISL_FORMAT_UNSUPPORTED) 824 return 0; 825 826 if (anv_format->n_planes > 1) 827 return 0; 828 829 if (anv_format->can_ycbcr) 830 return 0; 831 832 if (vk_format_is_depth_or_stencil(vk_format)) 833 return 0; 834 835 if (isl_format_supports_sampling(devinfo, isl_format) && 836 !isl_format_is_compressed(isl_format)) 837 flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT_KHR; 838 839 if (isl_format_supports_vertex_fetch(devinfo, isl_format)) 840 flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT_KHR; 841 842 if (isl_is_storage_image_format(isl_format)) 843 flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT_KHR; 844 845 if (isl_format == ISL_FORMAT_R32_SINT || isl_format == ISL_FORMAT_R32_UINT) 846 flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT_KHR; 847 848 return flags; 849} 850 851static VkFormatFeatureFlags 852features2_to_features(VkFormatFeatureFlags2KHR features2) 853{ 854 return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 855} 856 857static void 858get_drm_format_modifier_properties_list(const struct anv_physical_device *physical_device, 859 VkFormat vk_format, 860 VkDrmFormatModifierPropertiesListEXT *list) 861{ 862 const struct intel_device_info *devinfo = &physical_device->info; 863 const struct anv_format *anv_format = anv_get_format(vk_format); 864 865 VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties, 866 &list->drmFormatModifierCount); 867 868 isl_drm_modifier_info_for_each(isl_mod_info) { 869 VkFormatFeatureFlags2KHR features2 = 870 anv_get_image_format_features2(devinfo, vk_format, anv_format, 871 VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 872 isl_mod_info); 873 VkFormatFeatureFlags features = features2_to_features(features2); 874 if (!features) 875 continue; 876 877 uint32_t planes = anv_format->n_planes; 878 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) 879 ++planes; 880 881 vk_outarray_append(&out, out_props) { 882 *out_props = (VkDrmFormatModifierPropertiesEXT) { 883 .drmFormatModifier = isl_mod_info->modifier, 884 .drmFormatModifierPlaneCount = planes, 885 .drmFormatModifierTilingFeatures = features, 886 }; 887 }; 888 } 889} 890 891static void 892get_drm_format_modifier_properties_list_2(const struct anv_physical_device *physical_device, 893 VkFormat vk_format, 894 VkDrmFormatModifierPropertiesList2EXT *list) 895{ 896 const struct intel_device_info *devinfo = &physical_device->info; 897 const struct anv_format *anv_format = anv_get_format(vk_format); 898 899 VK_OUTARRAY_MAKE(out, list->pDrmFormatModifierProperties, 900 &list->drmFormatModifierCount); 901 902 isl_drm_modifier_info_for_each(isl_mod_info) { 903 VkFormatFeatureFlags2KHR features2 = 904 anv_get_image_format_features2(devinfo, vk_format, anv_format, 905 VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 906 isl_mod_info); 907 if (!features2) 908 continue; 909 910 uint32_t planes = anv_format->n_planes; 911 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) 912 ++planes; 913 914 vk_outarray_append(&out, out_props) { 915 *out_props = (VkDrmFormatModifierProperties2EXT) { 916 .drmFormatModifier = isl_mod_info->modifier, 917 .drmFormatModifierPlaneCount = planes, 918 .drmFormatModifierTilingFeatures = features2, 919 }; 920 }; 921 } 922} 923 924void anv_GetPhysicalDeviceFormatProperties2( 925 VkPhysicalDevice physicalDevice, 926 VkFormat vk_format, 927 VkFormatProperties2* pFormatProperties) 928{ 929 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 930 const struct intel_device_info *devinfo = &physical_device->info; 931 const struct anv_format *anv_format = anv_get_format(vk_format); 932 933 assert(pFormatProperties->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); 934 935 VkFormatFeatureFlags2KHR linear2, optimal2, buffer2; 936 linear2 = anv_get_image_format_features2(devinfo, vk_format, anv_format, 937 VK_IMAGE_TILING_LINEAR, NULL); 938 optimal2 = anv_get_image_format_features2(devinfo, vk_format, anv_format, 939 VK_IMAGE_TILING_OPTIMAL, NULL); 940 buffer2 = get_buffer_format_features2(devinfo, vk_format, anv_format); 941 942 pFormatProperties->formatProperties = (VkFormatProperties) { 943 .linearTilingFeatures = features2_to_features(linear2), 944 .optimalTilingFeatures = features2_to_features(optimal2), 945 .bufferFeatures = features2_to_features(buffer2), 946 }; 947 948 vk_foreach_struct(ext, pFormatProperties->pNext) { 949 /* Use unsigned since some cases are not in the VkStructureType enum. */ 950 switch ((unsigned)ext->sType) { 951 case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: 952 get_drm_format_modifier_properties_list(physical_device, vk_format, 953 (void *)ext); 954 break; 955 956 case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: 957 get_drm_format_modifier_properties_list_2(physical_device, vk_format, 958 (void *)ext); 959 break; 960 961 case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3_KHR: { 962 VkFormatProperties3KHR *props = (VkFormatProperties3KHR *)ext; 963 props->linearTilingFeatures = linear2; 964 props->optimalTilingFeatures = optimal2; 965 props->bufferFeatures = buffer2; 966 break; 967 } 968 default: 969 anv_debug_ignored_stype(ext->sType); 970 break; 971 } 972 } 973} 974 975static VkResult 976anv_get_image_format_properties( 977 struct anv_physical_device *physical_device, 978 const VkPhysicalDeviceImageFormatInfo2 *info, 979 VkImageFormatProperties *pImageFormatProperties, 980 VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties) 981{ 982 VkFormatFeatureFlags2KHR format_feature_flags; 983 VkExtent3D maxExtent; 984 uint32_t maxMipLevels; 985 uint32_t maxArraySize; 986 VkSampleCountFlags sampleCounts; 987 const struct intel_device_info *devinfo = &physical_device->info; 988 const struct anv_format *format = anv_get_format(info->format); 989 const struct isl_drm_modifier_info *isl_mod_info = NULL; 990 const VkImageFormatListCreateInfo *format_list_info = 991 vk_find_struct_const(info->pNext, IMAGE_FORMAT_LIST_CREATE_INFO); 992 993 if (format == NULL) 994 goto unsupported; 995 996 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 997 const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *vk_mod_info = 998 vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); 999 1000 isl_mod_info = isl_drm_modifier_get_info(vk_mod_info->drmFormatModifier); 1001 if (isl_mod_info == NULL) 1002 goto unsupported; 1003 } 1004 1005 assert(format->vk_format == info->format); 1006 format_feature_flags = anv_get_image_format_features2(devinfo, info->format, 1007 format, info->tiling, 1008 isl_mod_info); 1009 1010 /* Remove the VkFormatFeatureFlags that are incompatible with any declared 1011 * image view format. (Removals are more likely to occur when a DRM format 1012 * modifier is present). 1013 */ 1014 if ((info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && format_list_info) { 1015 for (uint32_t i = 0; i < format_list_info->viewFormatCount; ++i) { 1016 VkFormat vk_view_format = format_list_info->pViewFormats[i]; 1017 const struct anv_format *anv_view_format = anv_get_format(vk_view_format); 1018 VkFormatFeatureFlags2KHR view_format_features = 1019 anv_get_image_format_features2(devinfo, vk_view_format, 1020 anv_view_format, 1021 info->tiling, 1022 isl_mod_info); 1023 format_feature_flags &= view_format_features; 1024 } 1025 } 1026 1027 if (!format_feature_flags) 1028 goto unsupported; 1029 1030 switch (info->type) { 1031 default: 1032 unreachable("bad VkImageType"); 1033 case VK_IMAGE_TYPE_1D: 1034 maxExtent.width = 16384; 1035 maxExtent.height = 1; 1036 maxExtent.depth = 1; 1037 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1038 maxArraySize = 2048; 1039 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1040 break; 1041 case VK_IMAGE_TYPE_2D: 1042 /* FINISHME: Does this really differ for cube maps? The documentation 1043 * for RENDER_SURFACE_STATE suggests so. 1044 */ 1045 maxExtent.width = 16384; 1046 maxExtent.height = 16384; 1047 maxExtent.depth = 1; 1048 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1049 maxArraySize = 2048; 1050 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1051 break; 1052 case VK_IMAGE_TYPE_3D: 1053 maxExtent.width = 2048; 1054 maxExtent.height = 2048; 1055 maxExtent.depth = 2048; 1056 /* Prior to SKL, the mipmaps for 3D surfaces are laid out in a way 1057 * that make it impossible to represent in the way that 1058 * VkSubresourceLayout expects. Since we can't tell users how to make 1059 * sense of them, don't report them as available. 1060 */ 1061 if (devinfo->ver < 9 && info->tiling == VK_IMAGE_TILING_LINEAR) 1062 maxMipLevels = 1; 1063 else 1064 maxMipLevels = 12; /* log2(maxWidth) + 1 */ 1065 maxArraySize = 1; 1066 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1067 break; 1068 } 1069 1070 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1071 /* We support modifiers only for "simple" (that is, non-array 1072 * non-mipmapped single-sample) 2D images. 1073 */ 1074 if (info->type != VK_IMAGE_TYPE_2D) { 1075 vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1076 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT " 1077 "requires VK_IMAGE_TYPE_2D"); 1078 goto unsupported; 1079 } 1080 1081 maxArraySize = 1; 1082 maxMipLevels = 1; 1083 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1084 1085 if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E && 1086 !anv_formats_ccs_e_compatible(devinfo, info->flags, info->format, 1087 info->tiling, format_list_info)) { 1088 goto unsupported; 1089 } 1090 } 1091 1092 /* Our hardware doesn't support 1D compressed textures. 1093 * From the SKL PRM, RENDER_SURFACE_STATE::SurfaceFormat: 1094 * * This field cannot be a compressed (BC*, DXT*, FXT*, ETC*, EAC*) format 1095 * if the Surface Type is SURFTYPE_1D. 1096 * * This field cannot be ASTC format if the Surface Type is SURFTYPE_1D. 1097 */ 1098 if (info->type == VK_IMAGE_TYPE_1D && 1099 isl_format_is_compressed(format->planes[0].isl_format)) { 1100 goto unsupported; 1101 } 1102 1103 if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 1104 info->type == VK_IMAGE_TYPE_2D && 1105 (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR | 1106 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR)) && 1107 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 1108 !(info->usage & VK_IMAGE_USAGE_STORAGE_BIT)) { 1109 sampleCounts = isl_device_get_sample_counts(&physical_device->isl_dev); 1110 } 1111 1112 if (info->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 1113 VK_IMAGE_USAGE_TRANSFER_DST_BIT)) { 1114 /* Accept transfers on anything we can sample from or renderer to. */ 1115 if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR | 1116 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR | 1117 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR))) { 1118 goto unsupported; 1119 } 1120 } 1121 1122 if (info->usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 1123 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT_KHR)) { 1124 goto unsupported; 1125 } 1126 } 1127 1128 if (info->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1129 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT_KHR)) { 1130 goto unsupported; 1131 } 1132 } 1133 1134 if (info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 1135 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT_KHR)) { 1136 goto unsupported; 1137 } 1138 } 1139 1140 if (info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 1141 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT_KHR)) { 1142 goto unsupported; 1143 } 1144 } 1145 1146 if (info->flags & VK_IMAGE_CREATE_DISJOINT_BIT) { 1147 /* From the Vulkan 1.2.149 spec, VkImageCreateInfo: 1148 * 1149 * If format is a multi-planar format, and if imageCreateFormatFeatures 1150 * (as defined in Image Creation Limits) does not contain 1151 * VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR, then flags must not contain 1152 * VK_IMAGE_CREATE_DISJOINT_BIT. 1153 */ 1154 if (format->n_planes > 1 && 1155 !(format_feature_flags & VK_FORMAT_FEATURE_2_DISJOINT_BIT_KHR)) { 1156 goto unsupported; 1157 } 1158 1159 /* From the Vulkan 1.2.149 spec, VkImageCreateInfo: 1160 * 1161 * If format is not a multi-planar format, and flags does not include 1162 * VK_IMAGE_CREATE_ALIAS_BIT, flags must not contain 1163 * VK_IMAGE_CREATE_DISJOINT_BIT. 1164 */ 1165 if (format->n_planes == 1 && 1166 !(info->flags & VK_IMAGE_CREATE_ALIAS_BIT)) { 1167 goto unsupported; 1168 } 1169 1170 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && 1171 isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 1172 /* Rejection DISJOINT for consistency with the GL driver. In 1173 * eglCreateImage, we require that the dma_buf for the primary surface 1174 * and the dma_buf for its aux surface refer to the same bo. 1175 */ 1176 goto unsupported; 1177 } 1178 } 1179 1180 if (info->flags & VK_IMAGE_CREATE_ALIAS_BIT) { 1181 /* Reject aliasing of images with non-linear DRM format modifiers because: 1182 * 1183 * 1. For modifiers with compression, we store aux tracking state in 1184 * ANV_IMAGE_MEMORY_BINDING_PRIVATE, which is not aliasable because it's 1185 * not client-bound. 1186 * 1187 * 2. For tiled modifiers without compression, we may attempt to compress 1188 * them behind the scenes, in which case both the aux tracking state 1189 * and the CCS data are bound to ANV_IMAGE_MEMORY_BINDING_PRIVATE. 1190 */ 1191 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && 1192 isl_mod_info->modifier != DRM_FORMAT_MOD_LINEAR) { 1193 goto unsupported; 1194 } 1195 } 1196 1197 if (info->usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { 1198 /* Nothing to check. */ 1199 } 1200 1201 if (info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 1202 /* Ignore this flag because it was removed from the 1203 * provisional_I_20150910 header. 1204 */ 1205 } 1206 1207 /* From the bspec section entitled "Surface Layout and Tiling", 1208 * pre-gfx9 has a 2 GB limitation of the size in bytes, 1209 * gfx9 and gfx10 have a 256 GB limitation and gfx11+ 1210 * has a 16 TB limitation. 1211 */ 1212 uint64_t maxResourceSize = 0; 1213 if (devinfo->ver < 9) 1214 maxResourceSize = (uint64_t) 1 << 31; 1215 else if (devinfo->ver < 11) 1216 maxResourceSize = (uint64_t) 1 << 38; 1217 else 1218 maxResourceSize = (uint64_t) 1 << 44; 1219 1220 *pImageFormatProperties = (VkImageFormatProperties) { 1221 .maxExtent = maxExtent, 1222 .maxMipLevels = maxMipLevels, 1223 .maxArrayLayers = maxArraySize, 1224 .sampleCounts = sampleCounts, 1225 1226 /* FINISHME: Accurately calculate 1227 * VkImageFormatProperties::maxResourceSize. 1228 */ 1229 .maxResourceSize = maxResourceSize, 1230 }; 1231 1232 if (pYcbcrImageFormatProperties) { 1233 pYcbcrImageFormatProperties->combinedImageSamplerDescriptorCount = 1234 format->n_planes; 1235 } 1236 1237 return VK_SUCCESS; 1238 1239unsupported: 1240 *pImageFormatProperties = (VkImageFormatProperties) { 1241 .maxExtent = { 0, 0, 0 }, 1242 .maxMipLevels = 0, 1243 .maxArrayLayers = 0, 1244 .sampleCounts = 0, 1245 .maxResourceSize = 0, 1246 }; 1247 1248 return VK_ERROR_FORMAT_NOT_SUPPORTED; 1249} 1250 1251VkResult anv_GetPhysicalDeviceImageFormatProperties( 1252 VkPhysicalDevice physicalDevice, 1253 VkFormat format, 1254 VkImageType type, 1255 VkImageTiling tiling, 1256 VkImageUsageFlags usage, 1257 VkImageCreateFlags createFlags, 1258 VkImageFormatProperties* pImageFormatProperties) 1259{ 1260 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1261 1262 const VkPhysicalDeviceImageFormatInfo2 info = { 1263 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 1264 .pNext = NULL, 1265 .format = format, 1266 .type = type, 1267 .tiling = tiling, 1268 .usage = usage, 1269 .flags = createFlags, 1270 }; 1271 1272 return anv_get_image_format_properties(physical_device, &info, 1273 pImageFormatProperties, NULL); 1274} 1275 1276 1277/* Supports opaque fd but not dma_buf. */ 1278static const VkExternalMemoryProperties opaque_fd_only_props = { 1279 .externalMemoryFeatures = 1280 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1281 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1282 .exportFromImportedHandleTypes = 1283 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, 1284 .compatibleHandleTypes = 1285 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, 1286}; 1287 1288/* Supports opaque fd and dma_buf. */ 1289static const VkExternalMemoryProperties opaque_fd_dma_buf_props = { 1290 .externalMemoryFeatures = 1291 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1292 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1293 .exportFromImportedHandleTypes = 1294 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 1295 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 1296 .compatibleHandleTypes = 1297 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 1298 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 1299}; 1300 1301static const VkExternalMemoryProperties userptr_props = { 1302 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1303 .exportFromImportedHandleTypes = 0, 1304 .compatibleHandleTypes = 1305 VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, 1306}; 1307 1308static const VkExternalMemoryProperties android_buffer_props = { 1309 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1310 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1311 .exportFromImportedHandleTypes = 1312 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1313 .compatibleHandleTypes = 1314 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1315}; 1316 1317 1318static const VkExternalMemoryProperties android_image_props = { 1319 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1320 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | 1321 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT, 1322 .exportFromImportedHandleTypes = 1323 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1324 .compatibleHandleTypes = 1325 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1326}; 1327 1328VkResult anv_GetPhysicalDeviceImageFormatProperties2( 1329 VkPhysicalDevice physicalDevice, 1330 const VkPhysicalDeviceImageFormatInfo2* base_info, 1331 VkImageFormatProperties2* base_props) 1332{ 1333 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1334 const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 1335 VkExternalImageFormatProperties *external_props = NULL; 1336 VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 1337 VkAndroidHardwareBufferUsageANDROID *android_usage = NULL; 1338 VkResult result; 1339 1340 /* Extract input structs */ 1341 vk_foreach_struct_const(s, base_info->pNext) { 1342 switch (s->sType) { 1343 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 1344 external_info = (const void *) s; 1345 break; 1346 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: 1347 /* anv_get_image_format_properties will handle this */ 1348 break; 1349 case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO_EXT: 1350 /* Ignore but don't warn */ 1351 break; 1352 default: 1353 anv_debug_ignored_stype(s->sType); 1354 break; 1355 } 1356 } 1357 1358 /* Extract output structs */ 1359 vk_foreach_struct(s, base_props->pNext) { 1360 switch (s->sType) { 1361 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 1362 external_props = (void *) s; 1363 break; 1364 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 1365 ycbcr_props = (void *) s; 1366 break; 1367 case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID: 1368 android_usage = (void *) s; 1369 break; 1370 default: 1371 anv_debug_ignored_stype(s->sType); 1372 break; 1373 } 1374 } 1375 1376 result = anv_get_image_format_properties(physical_device, base_info, 1377 &base_props->imageFormatProperties, ycbcr_props); 1378 if (result != VK_SUCCESS) 1379 goto fail; 1380 1381 bool ahw_supported = 1382 physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer; 1383 1384 if (ahw_supported && android_usage) { 1385 android_usage->androidHardwareBufferUsage = 1386 anv_ahw_usage_from_vk_usage(base_info->flags, 1387 base_info->usage); 1388 1389 /* Limit maxArrayLayers to 1 for AHardwareBuffer based images for now. */ 1390 base_props->imageFormatProperties.maxArrayLayers = 1; 1391 } 1392 1393 /* From the Vulkan 1.0.42 spec: 1394 * 1395 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 1396 * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 1397 * present and VkExternalImageFormatProperties will be ignored. 1398 */ 1399 if (external_info && external_info->handleType != 0) { 1400 /* Does there exist a method for app and driver to explicitly communicate 1401 * to each other the image's memory layout? 1402 */ 1403 bool tiling_has_explicit_layout; 1404 1405 switch (base_info->tiling) { 1406 default: 1407 unreachable("bad VkImageTiling"); 1408 case VK_IMAGE_TILING_LINEAR: 1409 /* The app can query the image's memory layout with 1410 * vkGetImageSubresourceLayout. 1411 */ 1412 tiling_has_explicit_layout = true; 1413 break; 1414 case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: 1415 /* The app can provide the image's memory layout with 1416 * VkImageDrmFormatModifierExplicitCreateInfoEXT; 1417 * or the app can query it with vkGetImageSubresourceLayout. 1418 */ 1419 tiling_has_explicit_layout = true; 1420 break; 1421 case VK_IMAGE_TILING_OPTIMAL: 1422 /* The app can neither query nor provide the image's memory layout. */ 1423 tiling_has_explicit_layout = false; 1424 break; 1425 } 1426 1427 /* Compatibility between tiling and external memory handles 1428 * -------------------------------------------------------- 1429 * When importing or exporting an image, there must exist a method that 1430 * enables the app and driver to agree on the image's memory layout. If no 1431 * method exists, then we reject image creation here. 1432 * 1433 * If the memory handle requires matching 1434 * VkPhysicalDeviceIDPropertiesKHR::driverUUID and ::deviceUUID, then the 1435 * match-requirement guarantees that all users of the image agree on the 1436 * image's memory layout. 1437 * 1438 * If the memory handle does not require matching 1439 * VkPhysicalDeviceIDPropertiesKHR::driverUUID nor ::deviceUUID, then we 1440 * require that the app and driver be able to explicitly communicate to 1441 * each other the image's memory layout. 1442 * 1443 * (For restrictions on driverUUID and deviceUUID, see the Vulkan 1.2.149 1444 * spec, Table 73 "External memory handle types"). 1445 */ 1446 switch (external_info->handleType) { 1447 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 1448 if (external_props) { 1449 if (tiling_has_explicit_layout) { 1450 /* With an explicit memory layout, we don't care which type of fd 1451 * the image belongs too. Both OPAQUE_FD and DMA_BUF are 1452 * interchangeable here. 1453 */ 1454 external_props->externalMemoryProperties = opaque_fd_dma_buf_props; 1455 } else { 1456 /* With an implicit memory layout, we must rely on deviceUUID 1457 * and driverUUID to determine the layout. Therefore DMA_BUF is 1458 * incompatible here. 1459 */ 1460 external_props->externalMemoryProperties = opaque_fd_only_props; 1461 } 1462 } 1463 break; 1464 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1465 /* This memory handle has no restrictions on driverUUID nor deviceUUID, 1466 * and therefore requires explicit memory layout. 1467 */ 1468 if (!tiling_has_explicit_layout) { 1469 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1470 "VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT " 1471 "requires VK_IMAGE_TILING_LINEAR or " 1472 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT"); 1473 goto fail; 1474 } 1475 1476 /* With an explicit memory layout, we don't care which type of fd 1477 * the image belongs too. Both OPAQUE_FD and DMA_BUF are 1478 * interchangeable here. 1479 */ 1480 if (external_props) 1481 external_props->externalMemoryProperties = opaque_fd_dma_buf_props; 1482 break; 1483 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1484 /* This memory handle has no restrictions on driverUUID nor deviceUUID, 1485 * and therefore requires explicit memory layout. 1486 */ 1487 if (!tiling_has_explicit_layout) { 1488 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1489 "VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT " 1490 "requires VK_IMAGE_TILING_LINEAR or " 1491 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT"); 1492 goto fail; 1493 } 1494 1495 if (external_props) 1496 external_props->externalMemoryProperties = userptr_props; 1497 break; 1498 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 1499 /* This memory handle is magic. The Vulkan spec says it has no 1500 * requirements regarding deviceUUID nor driverUUID, but Android still 1501 * requires support for VK_IMAGE_TILING_OPTIMAL. Android systems 1502 * communicate the image's memory layout through backdoor channels. 1503 */ 1504 if (ahw_supported && external_props) { 1505 external_props->externalMemoryProperties = android_image_props; 1506 break; 1507 } 1508 FALLTHROUGH; /* If ahw not supported */ 1509 default: 1510 /* From the Vulkan 1.0.42 spec: 1511 * 1512 * If handleType is not compatible with the [parameters] specified 1513 * in VkPhysicalDeviceImageFormatInfo2, then 1514 * vkGetPhysicalDeviceImageFormatProperties2 returns 1515 * VK_ERROR_FORMAT_NOT_SUPPORTED. 1516 */ 1517 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1518 "unsupported VkExternalMemoryTypeFlagBits 0x%x", 1519 external_info->handleType); 1520 goto fail; 1521 } 1522 } 1523 1524 return VK_SUCCESS; 1525 1526 fail: 1527 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 1528 /* From the Vulkan 1.0.42 spec: 1529 * 1530 * If the combination of parameters to 1531 * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 1532 * the implementation for use in vkCreateImage, then all members of 1533 * imageFormatProperties will be filled with zero. 1534 */ 1535 base_props->imageFormatProperties = (VkImageFormatProperties) {}; 1536 } 1537 1538 return result; 1539} 1540 1541void anv_GetPhysicalDeviceSparseImageFormatProperties( 1542 VkPhysicalDevice physicalDevice, 1543 VkFormat format, 1544 VkImageType type, 1545 uint32_t samples, 1546 VkImageUsageFlags usage, 1547 VkImageTiling tiling, 1548 uint32_t* pNumProperties, 1549 VkSparseImageFormatProperties* pProperties) 1550{ 1551 /* Sparse images are not yet supported. */ 1552 *pNumProperties = 0; 1553} 1554 1555void anv_GetPhysicalDeviceSparseImageFormatProperties2( 1556 VkPhysicalDevice physicalDevice, 1557 const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, 1558 uint32_t* pPropertyCount, 1559 VkSparseImageFormatProperties2* pProperties) 1560{ 1561 /* Sparse images are not yet supported. */ 1562 *pPropertyCount = 0; 1563} 1564 1565void anv_GetPhysicalDeviceExternalBufferProperties( 1566 VkPhysicalDevice physicalDevice, 1567 const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, 1568 VkExternalBufferProperties* pExternalBufferProperties) 1569{ 1570 /* The Vulkan 1.0.42 spec says "handleType must be a valid 1571 * VkExternalMemoryHandleTypeFlagBits value" in 1572 * VkPhysicalDeviceExternalBufferInfo. This differs from 1573 * VkPhysicalDeviceExternalImageFormatInfo, which surprisingly permits 1574 * handleType == 0. 1575 */ 1576 assert(pExternalBufferInfo->handleType != 0); 1577 1578 /* All of the current flags are for sparse which we don't support yet. 1579 * Even when we do support it, doing sparse on external memory sounds 1580 * sketchy. Also, just disallowing flags is the safe option. 1581 */ 1582 if (pExternalBufferInfo->flags) 1583 goto unsupported; 1584 1585 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1586 1587 switch (pExternalBufferInfo->handleType) { 1588 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 1589 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1590 pExternalBufferProperties->externalMemoryProperties = opaque_fd_dma_buf_props; 1591 return; 1592 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1593 pExternalBufferProperties->externalMemoryProperties = userptr_props; 1594 return; 1595 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 1596 if (physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer) { 1597 pExternalBufferProperties->externalMemoryProperties = android_buffer_props; 1598 return; 1599 } 1600 FALLTHROUGH; /* If ahw not supported */ 1601 default: 1602 goto unsupported; 1603 } 1604 1605 unsupported: 1606 /* From the Vulkan 1.1.113 spec: 1607 * 1608 * compatibleHandleTypes must include at least handleType. 1609 */ 1610 pExternalBufferProperties->externalMemoryProperties = 1611 (VkExternalMemoryProperties) { 1612 .compatibleHandleTypes = pExternalBufferInfo->handleType, 1613 }; 1614} 1615 1616VkResult anv_CreateSamplerYcbcrConversion( 1617 VkDevice _device, 1618 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, 1619 const VkAllocationCallbacks* pAllocator, 1620 VkSamplerYcbcrConversion* pYcbcrConversion) 1621{ 1622 ANV_FROM_HANDLE(anv_device, device, _device); 1623 struct anv_ycbcr_conversion *conversion; 1624 1625 /* Search for VkExternalFormatANDROID and resolve the format. */ 1626 struct anv_format *ext_format = NULL; 1627 const VkExternalFormatANDROID *ext_info = 1628 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID); 1629 1630 uint64_t format = ext_info ? ext_info->externalFormat : 0; 1631 if (format) { 1632 assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); 1633 ext_format = (struct anv_format *) (uintptr_t) format; 1634 } 1635 1636 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO); 1637 1638 conversion = vk_object_zalloc(&device->vk, pAllocator, sizeof(*conversion), 1639 VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION); 1640 if (!conversion) 1641 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1642 1643 conversion->format = anv_get_format(pCreateInfo->format); 1644 conversion->ycbcr_model = pCreateInfo->ycbcrModel; 1645 conversion->ycbcr_range = pCreateInfo->ycbcrRange; 1646 1647 /* The Vulkan 1.1.95 spec says "When creating an external format conversion, 1648 * the value of components if ignored." 1649 */ 1650 if (!ext_format) { 1651 conversion->mapping[0] = pCreateInfo->components.r; 1652 conversion->mapping[1] = pCreateInfo->components.g; 1653 conversion->mapping[2] = pCreateInfo->components.b; 1654 conversion->mapping[3] = pCreateInfo->components.a; 1655 } 1656 1657 conversion->chroma_offsets[0] = pCreateInfo->xChromaOffset; 1658 conversion->chroma_offsets[1] = pCreateInfo->yChromaOffset; 1659 conversion->chroma_filter = pCreateInfo->chromaFilter; 1660 1661 /* Setup external format. */ 1662 if (ext_format) 1663 conversion->format = ext_format; 1664 1665 bool has_chroma_subsampled = false; 1666 for (uint32_t p = 0; p < conversion->format->n_planes; p++) { 1667 if (conversion->format->planes[p].has_chroma && 1668 (conversion->format->planes[p].denominator_scales[0] > 1 || 1669 conversion->format->planes[p].denominator_scales[1] > 1)) 1670 has_chroma_subsampled = true; 1671 } 1672 conversion->chroma_reconstruction = has_chroma_subsampled && 1673 (conversion->chroma_offsets[0] == VK_CHROMA_LOCATION_COSITED_EVEN || 1674 conversion->chroma_offsets[1] == VK_CHROMA_LOCATION_COSITED_EVEN); 1675 1676 *pYcbcrConversion = anv_ycbcr_conversion_to_handle(conversion); 1677 1678 return VK_SUCCESS; 1679} 1680 1681void anv_DestroySamplerYcbcrConversion( 1682 VkDevice _device, 1683 VkSamplerYcbcrConversion YcbcrConversion, 1684 const VkAllocationCallbacks* pAllocator) 1685{ 1686 ANV_FROM_HANDLE(anv_device, device, _device); 1687 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, YcbcrConversion); 1688 1689 if (!conversion) 1690 return; 1691 1692 vk_object_free(&device->vk, pAllocator, conversion); 1693} 1694