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 swiz_fmt1(VK_FORMAT_B5G6R5_UNORM_PACK16, ISL_FORMAT_B5G6R5_UNORM, BGRA), 153 fmt1(VK_FORMAT_R5G5B5A1_UNORM_PACK16, ISL_FORMAT_A1B5G5R5_UNORM), 154 swiz_fmt1(VK_FORMAT_B5G5R5A1_UNORM_PACK16, ISL_FORMAT_A1B5G5R5_UNORM, BGRA), 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, ISL_FORMAT_B4G4R4A4_UNORM), 339 fmt_unsupported(VK_FORMAT_A4B4G4R4_UNORM_PACK16), 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 547VkFormatFeatureFlags2 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 VkFormatFeatureFlags2 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 | 570 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | 571 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | 572 VK_FORMAT_FEATURE_2_BLIT_DST_BIT | 573 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 574 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 575 576 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 577 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 578 579 if ((aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && devinfo->ver >= 9) 580 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT; 581 582 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 583 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT; 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 if (isl_format_supports_sampling(devinfo, plane_format.isl_format)) { 604 /* ASTC textures must be in Y-tiled memory, and we reject compressed 605 * formats with modifiers. We do however interpret ASTC textures with 606 * uncompressed formats during data transfers. 607 */ 608 if (vk_tiling != VK_IMAGE_TILING_OPTIMAL && 609 isl_format_get_layout(plane_format.isl_format)->txc == ISL_TXC_ASTC) 610 return VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 611 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 612 613 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; 614 615 if (devinfo->ver >= 9) 616 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT; 617 618 if (isl_format_supports_filtering(devinfo, plane_format.isl_format)) 619 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 620 } 621 622 /* We can render to swizzled formats. However, if the alpha channel is 623 * moved, then blending won't work correctly. The PRM tells us 624 * straight-up not to render to such a surface. 625 */ 626 if (isl_format_supports_rendering(devinfo, plane_format.isl_format) && 627 plane_format.swizzle.a == ISL_CHANNEL_SELECT_ALPHA) { 628 flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; 629 630 /* While we can render to swizzled formats, they don't blend correctly 631 * if there are blend constants involved. The swizzle just remaps the 632 * output of the shader to different channels in the texture. It 633 * doesn't change the interpretation of the constant blend factors in 634 * COLOR_CALC_STATE. 635 */ 636 if (isl_format_supports_alpha_blending(devinfo, plane_format.isl_format) && 637 isl_swizzle_is_identity(plane_format.swizzle)) 638 flags |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT; 639 } 640 641 /* Load/store is determined based on base format. This prevents RGB 642 * formats from showing up as load/store capable. 643 */ 644 if (isl_format_supports_typed_reads(devinfo, base_isl_format)) 645 flags |= VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT; 646 if (isl_format_supports_typed_writes(devinfo, base_isl_format)) 647 flags |= VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 648 649 /* Keep this old behavior on VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT. 650 * When KHR_format_features2 is enabled, applications should only rely on 651 * it for the list of shader storage extended formats [1]. Before that, 652 * this applies to all VkFormats. 653 * 654 * [1] : https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#features-shaderStorageImageExtendedFormats 655 */ 656 if (flags & VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT) 657 flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 658 659 if (base_isl_format == ISL_FORMAT_R32_SINT || 660 base_isl_format == ISL_FORMAT_R32_UINT || 661 base_isl_format == ISL_FORMAT_R32_FLOAT) 662 flags |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; 663 664 if (flags) { 665 flags |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | 666 VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 667 VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 668 669 /* Blit destination requires rendering support. */ 670 if (isl_format_supports_rendering(devinfo, plane_format.isl_format)) 671 flags |= VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 672 } 673 674 /* XXX: We handle 3-channel formats by switching them out for RGBX or 675 * RGBA formats behind-the-scenes. This works fine for textures 676 * because the upload process will fill in the extra channel. 677 * We could also support it for render targets, but it will take 678 * substantially more work and we have enough RGBX formats to handle 679 * what most clients will want. 680 */ 681 if (vk_tiling == VK_IMAGE_TILING_OPTIMAL && 682 base_isl_format != ISL_FORMAT_UNSUPPORTED && 683 !util_is_power_of_two_or_zero(isl_format_layouts[base_isl_format].bpb) && 684 isl_format_rgb_to_rgbx(base_isl_format) == ISL_FORMAT_UNSUPPORTED) { 685 flags &= ~VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT; 686 flags &= ~VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 687 } 688 689 if (anv_format->can_ycbcr) { 690 /* The sampler doesn't have support for mid point when it handles YUV on 691 * its own. 692 */ 693 if (isl_format_is_yuv(anv_format->planes[0].isl_format)) { 694 /* TODO: We've disabled linear implicit reconstruction with the 695 * sampler. The failures show a slightly out of range values on the 696 * bottom left of the sampled image. 697 */ 698 flags |= VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT; 699 } else { 700 flags |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT | 701 VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT | 702 VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_SEPARATE_RECONSTRUCTION_FILTER_BIT; 703 } 704 705 /* We can support cosited chroma locations when handle planes with our 706 * own shader snippets. 707 */ 708 for (unsigned p = 0; p < anv_format->n_planes; p++) { 709 if (anv_format->planes[p].denominator_scales[0] > 1 || 710 anv_format->planes[p].denominator_scales[1] > 1) { 711 flags |= VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT; 712 break; 713 } 714 } 715 716 if (anv_format->n_planes > 1) 717 flags |= VK_FORMAT_FEATURE_2_DISJOINT_BIT; 718 719 const VkFormatFeatureFlags2 disallowed_ycbcr_image_features = 720 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | 721 VK_FORMAT_FEATURE_2_BLIT_DST_BIT | 722 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | 723 VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT | 724 VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 725 726 flags &= ~disallowed_ycbcr_image_features; 727 } 728 729 if (vk_tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 730 if (!isl_drm_modifier_get_score(devinfo, isl_mod_info->modifier)) 731 return 0; 732 733 /* Try to restrict the supported formats to those in drm_fourcc.h. The 734 * VK_EXT_image_drm_format_modifier does not require this (after all, two 735 * Vulkan apps could share an image by exchanging its VkFormat instead of 736 * a DRM_FORMAT), but there exist no users of such non-drm_fourcc formats 737 * yet. And the restriction shrinks our test surface. 738 */ 739 const struct isl_format_layout *isl_layout = 740 isl_format_get_layout(plane_format.isl_format); 741 742 switch (isl_layout->colorspace) { 743 case ISL_COLORSPACE_LINEAR: 744 case ISL_COLORSPACE_SRGB: 745 /* Each DRM_FORMAT that we support uses unorm (if the DRM format name 746 * has no type suffix) or sfloat (if it has suffix F). No format 747 * contains mixed types. (as of 2021-06-14) 748 */ 749 if (isl_layout->uniform_channel_type != ISL_UNORM && 750 isl_layout->uniform_channel_type != ISL_SFLOAT) 751 return 0; 752 break; 753 case ISL_COLORSPACE_YUV: 754 anv_finishme("support YUV colorspace with DRM format modifiers"); 755 return 0; 756 case ISL_COLORSPACE_NONE: 757 return 0; 758 } 759 760 /* We could support compressed formats if we wanted to. */ 761 if (isl_format_is_compressed(plane_format.isl_format)) 762 return 0; 763 764 /* No non-power-of-two fourcc formats exist. 765 * 766 * Even if non-power-of-two fourcc formats existed, we could support them 767 * only with DRM_FORMAT_MOD_LINEAR. Tiled formats must be power-of-two 768 * because we implement transfers with the render pipeline. 769 */ 770 if (anv_format_has_npot_plane(anv_format)) 771 return 0; 772 773 if (anv_format->n_planes > 1) { 774 /* For simplicity, keep DISJOINT disabled for multi-planar format. */ 775 flags &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT; 776 777 /* VK_ANDROID_external_memory_android_hardware_buffer in Virtio-GPU 778 * Venus driver layers on top of VK_EXT_image_drm_format_modifier of 779 * the host Vulkan driver, and both VK_FORMAT_G8_B8R8_2PLANE_420_UNORM 780 * and VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM and required to support 781 * camera/media interop in Android. 782 */ 783 if (vk_format != VK_FORMAT_G8_B8R8_2PLANE_420_UNORM && 784 vk_format != VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM) { 785 anv_finishme("support more multi-planar formats with DRM modifiers"); 786 return 0; 787 } 788 789 /* Currently there is no way to properly map memory planes to format 790 * planes and aux planes due to the lack of defined ABI for external 791 * multi-planar images. 792 */ 793 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 794 return 0; 795 } 796 } 797 798 if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E && 799 !isl_format_supports_ccs_e(devinfo, plane_format.isl_format)) { 800 return 0; 801 } 802 803 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 804 /* Rejection DISJOINT for consistency with the GL driver. In 805 * eglCreateImage, we require that the dma_buf for the primary surface 806 * and the dma_buf for its aux surface refer to the same bo. 807 */ 808 flags &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT; 809 810 /* When the hardware accesses a storage image, it bypasses the aux 811 * surface. We could support storage access on images with aux 812 * modifiers by resolving the aux surface prior to the storage access. 813 */ 814 flags &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 815 flags &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; 816 } 817 } 818 819 if (devinfo->has_coarse_pixel_primitive_and_cb && 820 vk_format == VK_FORMAT_R8_UINT && 821 vk_tiling == VK_IMAGE_TILING_OPTIMAL) 822 flags |= VK_FORMAT_FEATURE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; 823 824 return flags; 825} 826 827static VkFormatFeatureFlags2 828get_buffer_format_features2(const struct intel_device_info *devinfo, 829 VkFormat vk_format, 830 const struct anv_format *anv_format) 831{ 832 VkFormatFeatureFlags2 flags = 0; 833 834 if (anv_format == NULL) 835 return 0; 836 837 const enum isl_format isl_format = anv_format->planes[0].isl_format; 838 839 if (isl_format == ISL_FORMAT_UNSUPPORTED) 840 return 0; 841 842 if (anv_format->n_planes > 1) 843 return 0; 844 845 if (anv_format->can_ycbcr) 846 return 0; 847 848 if (vk_format_is_depth_or_stencil(vk_format)) 849 return 0; 850 851 if (isl_format_supports_sampling(devinfo, isl_format) && 852 !isl_format_is_compressed(isl_format)) 853 flags |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT; 854 855 if (isl_format_supports_vertex_fetch(devinfo, isl_format)) 856 flags |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT; 857 858 if (isl_is_storage_image_format(isl_format)) 859 flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT; 860 861 if (isl_format == ISL_FORMAT_R32_SINT || isl_format == ISL_FORMAT_R32_UINT) 862 flags |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 863 864 return flags; 865} 866 867static VkFormatFeatureFlags 868features2_to_features(VkFormatFeatureFlags2 features2) 869{ 870 return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 871} 872 873static void 874get_drm_format_modifier_properties_list(const struct anv_physical_device *physical_device, 875 VkFormat vk_format, 876 VkDrmFormatModifierPropertiesListEXT *list) 877{ 878 const struct intel_device_info *devinfo = &physical_device->info; 879 const struct anv_format *anv_format = anv_get_format(vk_format); 880 881 VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, 882 list->pDrmFormatModifierProperties, 883 &list->drmFormatModifierCount); 884 885 isl_drm_modifier_info_for_each(isl_mod_info) { 886 VkFormatFeatureFlags2 features2 = 887 anv_get_image_format_features2(devinfo, vk_format, anv_format, 888 VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 889 isl_mod_info); 890 VkFormatFeatureFlags features = features2_to_features(features2); 891 if (!features) 892 continue; 893 894 uint32_t planes = anv_format->n_planes; 895 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) 896 ++planes; 897 898 vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, out_props) { 899 *out_props = (VkDrmFormatModifierPropertiesEXT) { 900 .drmFormatModifier = isl_mod_info->modifier, 901 .drmFormatModifierPlaneCount = planes, 902 .drmFormatModifierTilingFeatures = features, 903 }; 904 }; 905 } 906} 907 908static void 909get_drm_format_modifier_properties_list_2(const struct anv_physical_device *physical_device, 910 VkFormat vk_format, 911 VkDrmFormatModifierPropertiesList2EXT *list) 912{ 913 const struct intel_device_info *devinfo = &physical_device->info; 914 const struct anv_format *anv_format = anv_get_format(vk_format); 915 916 VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out, 917 list->pDrmFormatModifierProperties, 918 &list->drmFormatModifierCount); 919 920 isl_drm_modifier_info_for_each(isl_mod_info) { 921 VkFormatFeatureFlags2 features2 = 922 anv_get_image_format_features2(devinfo, vk_format, anv_format, 923 VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 924 isl_mod_info); 925 if (!features2) 926 continue; 927 928 uint32_t planes = anv_format->n_planes; 929 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) 930 ++planes; 931 932 vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, out_props) { 933 *out_props = (VkDrmFormatModifierProperties2EXT) { 934 .drmFormatModifier = isl_mod_info->modifier, 935 .drmFormatModifierPlaneCount = planes, 936 .drmFormatModifierTilingFeatures = features2, 937 }; 938 }; 939 } 940} 941 942void anv_GetPhysicalDeviceFormatProperties2( 943 VkPhysicalDevice physicalDevice, 944 VkFormat vk_format, 945 VkFormatProperties2* pFormatProperties) 946{ 947 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 948 const struct intel_device_info *devinfo = &physical_device->info; 949 const struct anv_format *anv_format = anv_get_format(vk_format); 950 951 assert(pFormatProperties->sType == VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2); 952 953 VkFormatFeatureFlags2 linear2, optimal2, buffer2; 954 linear2 = anv_get_image_format_features2(devinfo, vk_format, anv_format, 955 VK_IMAGE_TILING_LINEAR, NULL); 956 optimal2 = anv_get_image_format_features2(devinfo, vk_format, anv_format, 957 VK_IMAGE_TILING_OPTIMAL, NULL); 958 buffer2 = get_buffer_format_features2(devinfo, vk_format, anv_format); 959 960 pFormatProperties->formatProperties = (VkFormatProperties) { 961 .linearTilingFeatures = features2_to_features(linear2), 962 .optimalTilingFeatures = features2_to_features(optimal2), 963 .bufferFeatures = features2_to_features(buffer2), 964 }; 965 966 vk_foreach_struct(ext, pFormatProperties->pNext) { 967 /* Use unsigned since some cases are not in the VkStructureType enum. */ 968 switch ((unsigned)ext->sType) { 969 case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT: 970 get_drm_format_modifier_properties_list(physical_device, vk_format, 971 (void *)ext); 972 break; 973 974 case VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT: 975 get_drm_format_modifier_properties_list_2(physical_device, vk_format, 976 (void *)ext); 977 break; 978 979 case VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_3: { 980 VkFormatProperties3 *props = (VkFormatProperties3 *)ext; 981 props->linearTilingFeatures = linear2; 982 props->optimalTilingFeatures = optimal2; 983 props->bufferFeatures = buffer2; 984 break; 985 } 986 default: 987 anv_debug_ignored_stype(ext->sType); 988 break; 989 } 990 } 991} 992 993static VkResult 994anv_get_image_format_properties( 995 struct anv_physical_device *physical_device, 996 const VkPhysicalDeviceImageFormatInfo2 *info, 997 VkImageFormatProperties *pImageFormatProperties, 998 VkSamplerYcbcrConversionImageFormatProperties *pYcbcrImageFormatProperties) 999{ 1000 VkFormatFeatureFlags2 format_feature_flags; 1001 VkExtent3D maxExtent; 1002 uint32_t maxMipLevels; 1003 uint32_t maxArraySize; 1004 VkSampleCountFlags sampleCounts; 1005 const struct intel_device_info *devinfo = &physical_device->info; 1006 const struct anv_format *format = anv_get_format(info->format); 1007 const struct isl_drm_modifier_info *isl_mod_info = NULL; 1008 const VkImageFormatListCreateInfo *format_list_info = 1009 vk_find_struct_const(info->pNext, IMAGE_FORMAT_LIST_CREATE_INFO); 1010 1011 if (format == NULL) 1012 goto unsupported; 1013 1014 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1015 const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *vk_mod_info = 1016 vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); 1017 1018 isl_mod_info = isl_drm_modifier_get_info(vk_mod_info->drmFormatModifier); 1019 if (isl_mod_info == NULL) 1020 goto unsupported; 1021 } 1022 1023 assert(format->vk_format == info->format); 1024 format_feature_flags = anv_get_image_format_features2(devinfo, info->format, 1025 format, info->tiling, 1026 isl_mod_info); 1027 1028 /* Remove the VkFormatFeatureFlags that are incompatible with any declared 1029 * image view format. (Removals are more likely to occur when a DRM format 1030 * modifier is present). 1031 */ 1032 if ((info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && format_list_info) { 1033 for (uint32_t i = 0; i < format_list_info->viewFormatCount; ++i) { 1034 VkFormat vk_view_format = format_list_info->pViewFormats[i]; 1035 const struct anv_format *anv_view_format = anv_get_format(vk_view_format); 1036 VkFormatFeatureFlags2 view_format_features = 1037 anv_get_image_format_features2(devinfo, vk_view_format, 1038 anv_view_format, 1039 info->tiling, 1040 isl_mod_info); 1041 format_feature_flags &= view_format_features; 1042 } 1043 } 1044 1045 if (!format_feature_flags) 1046 goto unsupported; 1047 1048 switch (info->type) { 1049 default: 1050 unreachable("bad VkImageType"); 1051 case VK_IMAGE_TYPE_1D: 1052 maxExtent.width = 16384; 1053 maxExtent.height = 1; 1054 maxExtent.depth = 1; 1055 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1056 maxArraySize = 2048; 1057 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1058 break; 1059 case VK_IMAGE_TYPE_2D: 1060 /* FINISHME: Does this really differ for cube maps? The documentation 1061 * for RENDER_SURFACE_STATE suggests so. 1062 */ 1063 maxExtent.width = 16384; 1064 maxExtent.height = 16384; 1065 maxExtent.depth = 1; 1066 maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1067 maxArraySize = 2048; 1068 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1069 break; 1070 case VK_IMAGE_TYPE_3D: 1071 maxExtent.width = 2048; 1072 maxExtent.height = 2048; 1073 maxExtent.depth = 2048; 1074 /* Prior to SKL, the mipmaps for 3D surfaces are laid out in a way 1075 * that make it impossible to represent in the way that 1076 * VkSubresourceLayout expects. Since we can't tell users how to make 1077 * sense of them, don't report them as available. 1078 */ 1079 if (devinfo->ver < 9 && info->tiling == VK_IMAGE_TILING_LINEAR) 1080 maxMipLevels = 1; 1081 else 1082 maxMipLevels = 12; /* log2(maxWidth) + 1 */ 1083 maxArraySize = 1; 1084 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1085 break; 1086 } 1087 1088 /* From the Vulkan 1.2.199 spec: 1089 * 1090 * "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image can be 1091 * created with usage flags that are not supported for the format the 1092 * image is created with but are supported for at least one format a 1093 * VkImageView created from the image can have." 1094 * 1095 * If VK_IMAGE_CREATE_EXTENDED_USAGE_BIT is set, views can be created with 1096 * different usage than the image so we can't always filter on usage. 1097 * There is one exception to this below for storage. 1098 */ 1099 const VkImageUsageFlags image_usage = info->usage; 1100 VkImageUsageFlags view_usage = image_usage; 1101 if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) 1102 view_usage = 0; 1103 1104 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1105 /* We support modifiers only for "simple" (that is, non-array 1106 * non-mipmapped single-sample) 2D images. 1107 */ 1108 if (info->type != VK_IMAGE_TYPE_2D) { 1109 vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1110 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT " 1111 "requires VK_IMAGE_TYPE_2D"); 1112 goto unsupported; 1113 } 1114 1115 maxArraySize = 1; 1116 maxMipLevels = 1; 1117 sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1118 1119 if (isl_mod_info->aux_usage == ISL_AUX_USAGE_CCS_E && 1120 !anv_formats_ccs_e_compatible(devinfo, info->flags, info->format, 1121 info->tiling, image_usage, 1122 format_list_info)) { 1123 goto unsupported; 1124 } 1125 } 1126 1127 /* Our hardware doesn't support 1D compressed textures. 1128 * From the SKL PRM, RENDER_SURFACE_STATE::SurfaceFormat: 1129 * * This field cannot be a compressed (BC*, DXT*, FXT*, ETC*, EAC*) format 1130 * if the Surface Type is SURFTYPE_1D. 1131 * * This field cannot be ASTC format if the Surface Type is SURFTYPE_1D. 1132 */ 1133 if (info->type == VK_IMAGE_TYPE_1D && 1134 isl_format_is_compressed(format->planes[0].isl_format)) { 1135 goto unsupported; 1136 } 1137 1138 if (info->tiling == VK_IMAGE_TILING_OPTIMAL && 1139 info->type == VK_IMAGE_TYPE_2D && 1140 (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | 1141 VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) && 1142 !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 1143 !(image_usage & VK_IMAGE_USAGE_STORAGE_BIT) && 1144 isl_format_supports_multisampling(devinfo, format->planes[0].isl_format)) { 1145 sampleCounts = isl_device_get_sample_counts(&physical_device->isl_dev); 1146 } 1147 1148 if (view_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 1149 if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 1150 VK_FORMAT_FEATURE_2_BLIT_SRC_BIT))) { 1151 goto unsupported; 1152 } 1153 } 1154 1155 if (view_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { 1156 if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT | 1157 VK_FORMAT_FEATURE_2_BLIT_DST_BIT))) { 1158 goto unsupported; 1159 } 1160 } 1161 1162 if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 1163 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) { 1164 goto unsupported; 1165 } 1166 } 1167 1168 if (image_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1169 /* Non-power-of-two formats can never be used as storage images. We 1170 * only check plane 0 because there are no YCbCr formats with 1171 * non-power-of-two planes. 1172 */ 1173 const struct isl_format_layout *isl_layout = 1174 isl_format_get_layout(format->planes[0].isl_format); 1175 if (!util_is_power_of_two_or_zero(isl_layout->bpb)) 1176 goto unsupported; 1177 } 1178 1179 if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1180 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) { 1181 goto unsupported; 1182 } 1183 } 1184 1185 if (view_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 1186 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) { 1187 goto unsupported; 1188 } 1189 } 1190 1191 if (view_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 1192 if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) { 1193 goto unsupported; 1194 } 1195 } 1196 1197 if (info->flags & VK_IMAGE_CREATE_DISJOINT_BIT) { 1198 /* From the Vulkan 1.2.149 spec, VkImageCreateInfo: 1199 * 1200 * If format is a multi-planar format, and if imageCreateFormatFeatures 1201 * (as defined in Image Creation Limits) does not contain 1202 * VK_FORMAT_FEATURE_2_DISJOINT_BIT, then flags must not contain 1203 * VK_IMAGE_CREATE_DISJOINT_BIT. 1204 */ 1205 if (format->n_planes > 1 && 1206 !(format_feature_flags & VK_FORMAT_FEATURE_2_DISJOINT_BIT)) { 1207 goto unsupported; 1208 } 1209 1210 /* From the Vulkan 1.2.149 spec, VkImageCreateInfo: 1211 * 1212 * If format is not a multi-planar format, and flags does not include 1213 * VK_IMAGE_CREATE_ALIAS_BIT, flags must not contain 1214 * VK_IMAGE_CREATE_DISJOINT_BIT. 1215 */ 1216 if (format->n_planes == 1 && 1217 !(info->flags & VK_IMAGE_CREATE_ALIAS_BIT)) { 1218 goto unsupported; 1219 } 1220 1221 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && 1222 isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 1223 /* Rejection DISJOINT for consistency with the GL driver. In 1224 * eglCreateImage, we require that the dma_buf for the primary surface 1225 * and the dma_buf for its aux surface refer to the same bo. 1226 */ 1227 goto unsupported; 1228 } 1229 } 1230 1231 if (info->flags & VK_IMAGE_CREATE_ALIAS_BIT) { 1232 /* Reject aliasing of images with non-linear DRM format modifiers because: 1233 * 1234 * 1. For modifiers with compression, we store aux tracking state in 1235 * ANV_IMAGE_MEMORY_BINDING_PRIVATE, which is not aliasable because it's 1236 * not client-bound. 1237 * 1238 * 2. For tiled modifiers without compression, we may attempt to compress 1239 * them behind the scenes, in which case both the aux tracking state 1240 * and the CCS data are bound to ANV_IMAGE_MEMORY_BINDING_PRIVATE. 1241 */ 1242 if (info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && 1243 isl_mod_info->modifier != DRM_FORMAT_MOD_LINEAR) { 1244 goto unsupported; 1245 } 1246 } 1247 1248 if (image_usage & VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT) { 1249 /* Nothing to check. */ 1250 } 1251 1252 if (image_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 1253 /* Ignore this flag because it was removed from the 1254 * provisional_I_20150910 header. 1255 */ 1256 } 1257 1258 /* From the bspec section entitled "Surface Layout and Tiling", 1259 * pre-gfx9 has a 2 GB limitation of the size in bytes, 1260 * gfx9 and gfx10 have a 256 GB limitation and gfx11+ 1261 * has a 16 TB limitation. 1262 */ 1263 uint64_t maxResourceSize = 0; 1264 if (devinfo->ver < 9) 1265 maxResourceSize = (uint64_t) 1 << 31; 1266 else if (devinfo->ver < 11) 1267 maxResourceSize = (uint64_t) 1 << 38; 1268 else 1269 maxResourceSize = (uint64_t) 1 << 44; 1270 1271 *pImageFormatProperties = (VkImageFormatProperties) { 1272 .maxExtent = maxExtent, 1273 .maxMipLevels = maxMipLevels, 1274 .maxArrayLayers = maxArraySize, 1275 .sampleCounts = sampleCounts, 1276 1277 /* FINISHME: Accurately calculate 1278 * VkImageFormatProperties::maxResourceSize. 1279 */ 1280 .maxResourceSize = maxResourceSize, 1281 }; 1282 1283 if (pYcbcrImageFormatProperties) { 1284 pYcbcrImageFormatProperties->combinedImageSamplerDescriptorCount = 1285 format->n_planes; 1286 } 1287 1288 return VK_SUCCESS; 1289 1290unsupported: 1291 *pImageFormatProperties = (VkImageFormatProperties) { 1292 .maxExtent = { 0, 0, 0 }, 1293 .maxMipLevels = 0, 1294 .maxArrayLayers = 0, 1295 .sampleCounts = 0, 1296 .maxResourceSize = 0, 1297 }; 1298 1299 return VK_ERROR_FORMAT_NOT_SUPPORTED; 1300} 1301 1302VkResult anv_GetPhysicalDeviceImageFormatProperties( 1303 VkPhysicalDevice physicalDevice, 1304 VkFormat format, 1305 VkImageType type, 1306 VkImageTiling tiling, 1307 VkImageUsageFlags usage, 1308 VkImageCreateFlags createFlags, 1309 VkImageFormatProperties* pImageFormatProperties) 1310{ 1311 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1312 1313 const VkPhysicalDeviceImageFormatInfo2 info = { 1314 .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 1315 .pNext = NULL, 1316 .format = format, 1317 .type = type, 1318 .tiling = tiling, 1319 .usage = usage, 1320 .flags = createFlags, 1321 }; 1322 1323 return anv_get_image_format_properties(physical_device, &info, 1324 pImageFormatProperties, NULL); 1325} 1326 1327 1328/* Supports opaque fd but not dma_buf. */ 1329static const VkExternalMemoryProperties opaque_fd_only_props = { 1330 .externalMemoryFeatures = 1331 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1332 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1333 .exportFromImportedHandleTypes = 1334 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, 1335 .compatibleHandleTypes = 1336 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT, 1337}; 1338 1339/* Supports opaque fd and dma_buf. */ 1340static const VkExternalMemoryProperties opaque_fd_dma_buf_props = { 1341 .externalMemoryFeatures = 1342 VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1343 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1344 .exportFromImportedHandleTypes = 1345 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 1346 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 1347 .compatibleHandleTypes = 1348 VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 1349 VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT, 1350}; 1351 1352static const VkExternalMemoryProperties userptr_props = { 1353 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1354 .exportFromImportedHandleTypes = 0, 1355 .compatibleHandleTypes = 1356 VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT, 1357}; 1358 1359static const VkExternalMemoryProperties android_buffer_props = { 1360 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1361 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT, 1362 .exportFromImportedHandleTypes = 1363 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1364 .compatibleHandleTypes = 1365 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1366}; 1367 1368 1369static const VkExternalMemoryProperties android_image_props = { 1370 .externalMemoryFeatures = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | 1371 VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT | 1372 VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT, 1373 .exportFromImportedHandleTypes = 1374 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1375 .compatibleHandleTypes = 1376 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID, 1377}; 1378 1379VkResult anv_GetPhysicalDeviceImageFormatProperties2( 1380 VkPhysicalDevice physicalDevice, 1381 const VkPhysicalDeviceImageFormatInfo2* base_info, 1382 VkImageFormatProperties2* base_props) 1383{ 1384 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1385 const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 1386 VkExternalImageFormatProperties *external_props = NULL; 1387 VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 1388 VkAndroidHardwareBufferUsageANDROID *android_usage = NULL; 1389 VkResult result; 1390 1391 /* Extract input structs */ 1392 vk_foreach_struct_const(s, base_info->pNext) { 1393 switch (s->sType) { 1394 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 1395 external_info = (const void *) s; 1396 break; 1397 case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT: 1398 case VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO: 1399 /* anv_get_image_format_properties will handle these */ 1400 break; 1401 case VK_STRUCTURE_TYPE_IMAGE_STENCIL_USAGE_CREATE_INFO: 1402 /* Ignore but don't warn */ 1403 break; 1404 default: 1405 anv_debug_ignored_stype(s->sType); 1406 break; 1407 } 1408 } 1409 1410 /* Extract output structs */ 1411 vk_foreach_struct(s, base_props->pNext) { 1412 switch (s->sType) { 1413 case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 1414 external_props = (void *) s; 1415 break; 1416 case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 1417 ycbcr_props = (void *) s; 1418 break; 1419 case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID: 1420 android_usage = (void *) s; 1421 break; 1422 default: 1423 anv_debug_ignored_stype(s->sType); 1424 break; 1425 } 1426 } 1427 1428 result = anv_get_image_format_properties(physical_device, base_info, 1429 &base_props->imageFormatProperties, ycbcr_props); 1430 if (result != VK_SUCCESS) 1431 goto fail; 1432 1433 bool ahw_supported = 1434 physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer; 1435 1436 if (ahw_supported && android_usage) { 1437 android_usage->androidHardwareBufferUsage = 1438 anv_ahw_usage_from_vk_usage(base_info->flags, 1439 base_info->usage); 1440 1441 /* Limit maxArrayLayers to 1 for AHardwareBuffer based images for now. */ 1442 base_props->imageFormatProperties.maxArrayLayers = 1; 1443 } 1444 1445 /* From the Vulkan 1.0.42 spec: 1446 * 1447 * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 1448 * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 1449 * present and VkExternalImageFormatProperties will be ignored. 1450 */ 1451 if (external_info && external_info->handleType != 0) { 1452 /* Does there exist a method for app and driver to explicitly communicate 1453 * to each other the image's memory layout? 1454 */ 1455 bool tiling_has_explicit_layout; 1456 1457 switch (base_info->tiling) { 1458 default: 1459 unreachable("bad VkImageTiling"); 1460 case VK_IMAGE_TILING_LINEAR: 1461 /* The app can query the image's memory layout with 1462 * vkGetImageSubresourceLayout. 1463 */ 1464 tiling_has_explicit_layout = true; 1465 break; 1466 case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: 1467 /* The app can provide the image's memory layout with 1468 * VkImageDrmFormatModifierExplicitCreateInfoEXT; 1469 * or the app can query it with vkGetImageSubresourceLayout. 1470 */ 1471 tiling_has_explicit_layout = true; 1472 break; 1473 case VK_IMAGE_TILING_OPTIMAL: 1474 /* The app can neither query nor provide the image's memory layout. */ 1475 tiling_has_explicit_layout = false; 1476 break; 1477 } 1478 1479 /* Compatibility between tiling and external memory handles 1480 * -------------------------------------------------------- 1481 * When importing or exporting an image, there must exist a method that 1482 * enables the app and driver to agree on the image's memory layout. If no 1483 * method exists, then we reject image creation here. 1484 * 1485 * If the memory handle requires matching 1486 * VkPhysicalDeviceIDProperties::driverUUID and ::deviceUUID, then the 1487 * match-requirement guarantees that all users of the image agree on the 1488 * image's memory layout. 1489 * 1490 * If the memory handle does not require matching 1491 * VkPhysicalDeviceIDProperties::driverUUID nor ::deviceUUID, then we 1492 * require that the app and driver be able to explicitly communicate to 1493 * each other the image's memory layout. 1494 * 1495 * (For restrictions on driverUUID and deviceUUID, see the Vulkan 1.2.149 1496 * spec, Table 73 "External memory handle types"). 1497 */ 1498 switch (external_info->handleType) { 1499 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 1500 if (external_props) { 1501 if (tiling_has_explicit_layout) { 1502 /* With an explicit memory layout, we don't care which type of fd 1503 * the image belongs too. Both OPAQUE_FD and DMA_BUF are 1504 * interchangeable here. 1505 */ 1506 external_props->externalMemoryProperties = opaque_fd_dma_buf_props; 1507 } else { 1508 /* With an implicit memory layout, we must rely on deviceUUID 1509 * and driverUUID to determine the layout. Therefore DMA_BUF is 1510 * incompatible here. 1511 */ 1512 external_props->externalMemoryProperties = opaque_fd_only_props; 1513 } 1514 } 1515 break; 1516 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1517 /* This memory handle has no restrictions on driverUUID nor deviceUUID, 1518 * and therefore requires explicit memory layout. 1519 */ 1520 if (!tiling_has_explicit_layout) { 1521 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1522 "VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT " 1523 "requires VK_IMAGE_TILING_LINEAR or " 1524 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT"); 1525 goto fail; 1526 } 1527 1528 /* With an explicit memory layout, we don't care which type of fd 1529 * the image belongs too. Both OPAQUE_FD and DMA_BUF are 1530 * interchangeable here. 1531 */ 1532 if (external_props) 1533 external_props->externalMemoryProperties = opaque_fd_dma_buf_props; 1534 break; 1535 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1536 /* This memory handle has no restrictions on driverUUID nor deviceUUID, 1537 * and therefore requires explicit memory layout. 1538 */ 1539 if (!tiling_has_explicit_layout) { 1540 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1541 "VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT " 1542 "requires VK_IMAGE_TILING_LINEAR or " 1543 "VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT"); 1544 goto fail; 1545 } 1546 1547 if (external_props) 1548 external_props->externalMemoryProperties = userptr_props; 1549 break; 1550 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 1551 /* This memory handle is magic. The Vulkan spec says it has no 1552 * requirements regarding deviceUUID nor driverUUID, but Android still 1553 * requires support for VK_IMAGE_TILING_OPTIMAL. Android systems 1554 * communicate the image's memory layout through backdoor channels. 1555 */ 1556 if (ahw_supported && external_props) { 1557 external_props->externalMemoryProperties = android_image_props; 1558 break; 1559 } 1560 FALLTHROUGH; /* If ahw not supported */ 1561 default: 1562 /* From the Vulkan 1.0.42 spec: 1563 * 1564 * If handleType is not compatible with the [parameters] specified 1565 * in VkPhysicalDeviceImageFormatInfo2, then 1566 * vkGetPhysicalDeviceImageFormatProperties2 returns 1567 * VK_ERROR_FORMAT_NOT_SUPPORTED. 1568 */ 1569 result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1570 "unsupported VkExternalMemoryTypeFlagBits 0x%x", 1571 external_info->handleType); 1572 goto fail; 1573 } 1574 } 1575 1576 return VK_SUCCESS; 1577 1578 fail: 1579 if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 1580 /* From the Vulkan 1.0.42 spec: 1581 * 1582 * If the combination of parameters to 1583 * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 1584 * the implementation for use in vkCreateImage, then all members of 1585 * imageFormatProperties will be filled with zero. 1586 */ 1587 base_props->imageFormatProperties = (VkImageFormatProperties) {}; 1588 } 1589 1590 return result; 1591} 1592 1593void anv_GetPhysicalDeviceSparseImageFormatProperties( 1594 VkPhysicalDevice physicalDevice, 1595 VkFormat format, 1596 VkImageType type, 1597 uint32_t samples, 1598 VkImageUsageFlags usage, 1599 VkImageTiling tiling, 1600 uint32_t* pNumProperties, 1601 VkSparseImageFormatProperties* pProperties) 1602{ 1603 /* Sparse images are not yet supported. */ 1604 *pNumProperties = 0; 1605} 1606 1607void anv_GetPhysicalDeviceSparseImageFormatProperties2( 1608 VkPhysicalDevice physicalDevice, 1609 const VkPhysicalDeviceSparseImageFormatInfo2* pFormatInfo, 1610 uint32_t* pPropertyCount, 1611 VkSparseImageFormatProperties2* pProperties) 1612{ 1613 /* Sparse images are not yet supported. */ 1614 *pPropertyCount = 0; 1615} 1616 1617void anv_GetPhysicalDeviceExternalBufferProperties( 1618 VkPhysicalDevice physicalDevice, 1619 const VkPhysicalDeviceExternalBufferInfo* pExternalBufferInfo, 1620 VkExternalBufferProperties* pExternalBufferProperties) 1621{ 1622 /* The Vulkan 1.0.42 spec says "handleType must be a valid 1623 * VkExternalMemoryHandleTypeFlagBits value" in 1624 * VkPhysicalDeviceExternalBufferInfo. This differs from 1625 * VkPhysicalDeviceExternalImageFormatInfo, which surprisingly permits 1626 * handleType == 0. 1627 */ 1628 assert(pExternalBufferInfo->handleType != 0); 1629 1630 /* All of the current flags are for sparse which we don't support yet. 1631 * Even when we do support it, doing sparse on external memory sounds 1632 * sketchy. Also, just disallowing flags is the safe option. 1633 */ 1634 if (pExternalBufferInfo->flags) 1635 goto unsupported; 1636 1637 ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); 1638 1639 switch (pExternalBufferInfo->handleType) { 1640 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 1641 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1642 pExternalBufferProperties->externalMemoryProperties = opaque_fd_dma_buf_props; 1643 return; 1644 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1645 pExternalBufferProperties->externalMemoryProperties = userptr_props; 1646 return; 1647 case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 1648 if (physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer) { 1649 pExternalBufferProperties->externalMemoryProperties = android_buffer_props; 1650 return; 1651 } 1652 FALLTHROUGH; /* If ahw not supported */ 1653 default: 1654 goto unsupported; 1655 } 1656 1657 unsupported: 1658 /* From the Vulkan 1.1.113 spec: 1659 * 1660 * compatibleHandleTypes must include at least handleType. 1661 */ 1662 pExternalBufferProperties->externalMemoryProperties = 1663 (VkExternalMemoryProperties) { 1664 .compatibleHandleTypes = pExternalBufferInfo->handleType, 1665 }; 1666} 1667 1668VkResult anv_CreateSamplerYcbcrConversion( 1669 VkDevice _device, 1670 const VkSamplerYcbcrConversionCreateInfo* pCreateInfo, 1671 const VkAllocationCallbacks* pAllocator, 1672 VkSamplerYcbcrConversion* pYcbcrConversion) 1673{ 1674 ANV_FROM_HANDLE(anv_device, device, _device); 1675 struct anv_ycbcr_conversion *conversion; 1676 1677 /* Search for VkExternalFormatANDROID and resolve the format. */ 1678 struct anv_format *ext_format = NULL; 1679 const VkExternalFormatANDROID *ext_info = 1680 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID); 1681 1682 uint64_t format = ext_info ? ext_info->externalFormat : 0; 1683 if (format) { 1684 assert(pCreateInfo->format == VK_FORMAT_UNDEFINED); 1685 ext_format = (struct anv_format *) (uintptr_t) format; 1686 } 1687 1688 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_CREATE_INFO); 1689 1690 conversion = vk_object_zalloc(&device->vk, pAllocator, sizeof(*conversion), 1691 VK_OBJECT_TYPE_SAMPLER_YCBCR_CONVERSION); 1692 if (!conversion) 1693 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1694 1695 conversion->format = anv_get_format(pCreateInfo->format); 1696 conversion->ycbcr_model = pCreateInfo->ycbcrModel; 1697 conversion->ycbcr_range = pCreateInfo->ycbcrRange; 1698 1699 /* The Vulkan 1.1.95 spec says "When creating an external format conversion, 1700 * the value of components if ignored." 1701 */ 1702 if (!ext_format) { 1703 conversion->mapping[0] = pCreateInfo->components.r; 1704 conversion->mapping[1] = pCreateInfo->components.g; 1705 conversion->mapping[2] = pCreateInfo->components.b; 1706 conversion->mapping[3] = pCreateInfo->components.a; 1707 } 1708 1709 conversion->chroma_offsets[0] = pCreateInfo->xChromaOffset; 1710 conversion->chroma_offsets[1] = pCreateInfo->yChromaOffset; 1711 conversion->chroma_filter = pCreateInfo->chromaFilter; 1712 1713 /* Setup external format. */ 1714 if (ext_format) 1715 conversion->format = ext_format; 1716 1717 bool has_chroma_subsampled = false; 1718 for (uint32_t p = 0; p < conversion->format->n_planes; p++) { 1719 if (conversion->format->planes[p].has_chroma && 1720 (conversion->format->planes[p].denominator_scales[0] > 1 || 1721 conversion->format->planes[p].denominator_scales[1] > 1)) 1722 has_chroma_subsampled = true; 1723 } 1724 conversion->chroma_reconstruction = has_chroma_subsampled && 1725 (conversion->chroma_offsets[0] == VK_CHROMA_LOCATION_COSITED_EVEN || 1726 conversion->chroma_offsets[1] == VK_CHROMA_LOCATION_COSITED_EVEN); 1727 1728 *pYcbcrConversion = anv_ycbcr_conversion_to_handle(conversion); 1729 1730 return VK_SUCCESS; 1731} 1732 1733void anv_DestroySamplerYcbcrConversion( 1734 VkDevice _device, 1735 VkSamplerYcbcrConversion YcbcrConversion, 1736 const VkAllocationCallbacks* pAllocator) 1737{ 1738 ANV_FROM_HANDLE(anv_device, device, _device); 1739 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, YcbcrConversion); 1740 1741 if (!conversion) 1742 return; 1743 1744 vk_object_free(&device->vk, pAllocator, conversion); 1745} 1746