1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 11bf215546Sopenharmony_ci * 12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 14bf215546Sopenharmony_ci * Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22bf215546Sopenharmony_ci * IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci#include "radv_debug.h" 26bf215546Sopenharmony_ci#include "radv_private.h" 27bf215546Sopenharmony_ci 28bf215546Sopenharmony_ci#include "sid.h" 29bf215546Sopenharmony_ci#include "vk_format.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_ci#include "vk_util.h" 32bf215546Sopenharmony_ci 33bf215546Sopenharmony_ci#include "ac_drm_fourcc.h" 34bf215546Sopenharmony_ci#include "util/format_r11g11b10f.h" 35bf215546Sopenharmony_ci#include "util/format_rgb9e5.h" 36bf215546Sopenharmony_ci#include "util/format_srgb.h" 37bf215546Sopenharmony_ci#include "util/half_float.h" 38bf215546Sopenharmony_ci#include "vulkan/util/vk_format.h" 39bf215546Sopenharmony_ci#include "vulkan/util/vk_enum_defines.h" 40bf215546Sopenharmony_ci 41bf215546Sopenharmony_ciuint32_t 42bf215546Sopenharmony_ciradv_translate_buffer_dataformat(const struct util_format_description *desc, int first_non_void) 43bf215546Sopenharmony_ci{ 44bf215546Sopenharmony_ci unsigned type; 45bf215546Sopenharmony_ci int i; 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci assert(util_format_get_num_planes(desc->format) == 1); 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT) 50bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_10_11_11; 51bf215546Sopenharmony_ci 52bf215546Sopenharmony_ci if (first_non_void < 0) 53bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_INVALID; 54bf215546Sopenharmony_ci type = desc->channel[first_non_void].type; 55bf215546Sopenharmony_ci 56bf215546Sopenharmony_ci if (type == UTIL_FORMAT_TYPE_FIXED) 57bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_INVALID; 58bf215546Sopenharmony_ci if (desc->nr_channels == 4 && desc->channel[0].size == 10 && desc->channel[1].size == 10 && 59bf215546Sopenharmony_ci desc->channel[2].size == 10 && desc->channel[3].size == 2) 60bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_2_10_10_10; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci /* See whether the components are of the same size. */ 63bf215546Sopenharmony_ci for (i = 0; i < desc->nr_channels; i++) { 64bf215546Sopenharmony_ci if (desc->channel[first_non_void].size != desc->channel[i].size) 65bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_INVALID; 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci 68bf215546Sopenharmony_ci switch (desc->channel[first_non_void].size) { 69bf215546Sopenharmony_ci case 8: 70bf215546Sopenharmony_ci switch (desc->nr_channels) { 71bf215546Sopenharmony_ci case 1: 72bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_8; 73bf215546Sopenharmony_ci case 2: 74bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_8_8; 75bf215546Sopenharmony_ci case 4: 76bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_8_8_8_8; 77bf215546Sopenharmony_ci } 78bf215546Sopenharmony_ci break; 79bf215546Sopenharmony_ci case 16: 80bf215546Sopenharmony_ci switch (desc->nr_channels) { 81bf215546Sopenharmony_ci case 1: 82bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_16; 83bf215546Sopenharmony_ci case 2: 84bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_16_16; 85bf215546Sopenharmony_ci case 4: 86bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_16_16_16_16; 87bf215546Sopenharmony_ci } 88bf215546Sopenharmony_ci break; 89bf215546Sopenharmony_ci case 32: 90bf215546Sopenharmony_ci /* From the Southern Islands ISA documentation about MTBUF: 91bf215546Sopenharmony_ci * 'Memory reads of data in memory that is 32 or 64 bits do not 92bf215546Sopenharmony_ci * undergo any format conversion.' 93bf215546Sopenharmony_ci */ 94bf215546Sopenharmony_ci if (type != UTIL_FORMAT_TYPE_FLOAT && !desc->channel[first_non_void].pure_integer) 95bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_INVALID; 96bf215546Sopenharmony_ci 97bf215546Sopenharmony_ci switch (desc->nr_channels) { 98bf215546Sopenharmony_ci case 1: 99bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_32; 100bf215546Sopenharmony_ci case 2: 101bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_32_32; 102bf215546Sopenharmony_ci case 3: 103bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_32_32_32; 104bf215546Sopenharmony_ci case 4: 105bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_32_32_32_32; 106bf215546Sopenharmony_ci } 107bf215546Sopenharmony_ci break; 108bf215546Sopenharmony_ci case 64: 109bf215546Sopenharmony_ci if (type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1) 110bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_32_32; 111bf215546Sopenharmony_ci } 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci return V_008F0C_BUF_DATA_FORMAT_INVALID; 114bf215546Sopenharmony_ci} 115bf215546Sopenharmony_ci 116bf215546Sopenharmony_ciuint32_t 117bf215546Sopenharmony_ciradv_translate_buffer_numformat(const struct util_format_description *desc, int first_non_void) 118bf215546Sopenharmony_ci{ 119bf215546Sopenharmony_ci assert(util_format_get_num_planes(desc->format) == 1); 120bf215546Sopenharmony_ci 121bf215546Sopenharmony_ci if (desc->format == PIPE_FORMAT_R11G11B10_FLOAT) 122bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_FLOAT; 123bf215546Sopenharmony_ci 124bf215546Sopenharmony_ci if (first_non_void < 0) 125bf215546Sopenharmony_ci return ~0; 126bf215546Sopenharmony_ci 127bf215546Sopenharmony_ci switch (desc->channel[first_non_void].type) { 128bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_SIGNED: 129bf215546Sopenharmony_ci if (desc->channel[first_non_void].normalized) 130bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_SNORM; 131bf215546Sopenharmony_ci else if (desc->channel[first_non_void].pure_integer) 132bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_SINT; 133bf215546Sopenharmony_ci else 134bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_SSCALED; 135bf215546Sopenharmony_ci break; 136bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_UNSIGNED: 137bf215546Sopenharmony_ci if (desc->channel[first_non_void].normalized) 138bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_UNORM; 139bf215546Sopenharmony_ci else if (desc->channel[first_non_void].pure_integer) 140bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_UINT; 141bf215546Sopenharmony_ci else 142bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_USCALED; 143bf215546Sopenharmony_ci break; 144bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_FLOAT: 145bf215546Sopenharmony_ci default: 146bf215546Sopenharmony_ci return V_008F0C_BUF_NUM_FORMAT_FLOAT; 147bf215546Sopenharmony_ci } 148bf215546Sopenharmony_ci} 149bf215546Sopenharmony_ci 150bf215546Sopenharmony_civoid 151bf215546Sopenharmony_ciradv_translate_vertex_format(const struct radv_physical_device *pdevice, VkFormat format, 152bf215546Sopenharmony_ci const struct util_format_description *desc, unsigned *dfmt, 153bf215546Sopenharmony_ci unsigned *nfmt, bool *post_shuffle, 154bf215546Sopenharmony_ci enum radv_vs_input_alpha_adjust *alpha_adjust) 155bf215546Sopenharmony_ci{ 156bf215546Sopenharmony_ci assert(desc->channel[0].type != UTIL_FORMAT_TYPE_VOID); 157bf215546Sopenharmony_ci *nfmt = radv_translate_buffer_numformat(desc, 0); 158bf215546Sopenharmony_ci *dfmt = radv_translate_buffer_dataformat(desc, 0); 159bf215546Sopenharmony_ci 160bf215546Sopenharmony_ci *alpha_adjust = ALPHA_ADJUST_NONE; 161bf215546Sopenharmony_ci if (pdevice->rad_info.gfx_level <= GFX8 && pdevice->rad_info.family != CHIP_STONEY) { 162bf215546Sopenharmony_ci switch (format) { 163bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SNORM_PACK32: 164bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SNORM_PACK32: 165bf215546Sopenharmony_ci *alpha_adjust = ALPHA_ADJUST_SNORM; 166bf215546Sopenharmony_ci break; 167bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 168bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: 169bf215546Sopenharmony_ci *alpha_adjust = ALPHA_ADJUST_SSCALED; 170bf215546Sopenharmony_ci break; 171bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SINT_PACK32: 172bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SINT_PACK32: 173bf215546Sopenharmony_ci *alpha_adjust = ALPHA_ADJUST_SINT; 174bf215546Sopenharmony_ci break; 175bf215546Sopenharmony_ci default: 176bf215546Sopenharmony_ci break; 177bf215546Sopenharmony_ci } 178bf215546Sopenharmony_ci } 179bf215546Sopenharmony_ci 180bf215546Sopenharmony_ci switch (format) { 181bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_UNORM: 182bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_SNORM: 183bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_USCALED: 184bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_SSCALED: 185bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_UINT: 186bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_SINT: 187bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8A8_SRGB: 188bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_UNORM_PACK32: 189bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SNORM_PACK32: 190bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_USCALED_PACK32: 191bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 192bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_UINT_PACK32: 193bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SINT_PACK32: 194bf215546Sopenharmony_ci *post_shuffle = true; 195bf215546Sopenharmony_ci break; 196bf215546Sopenharmony_ci default: 197bf215546Sopenharmony_ci *post_shuffle = false; 198bf215546Sopenharmony_ci break; 199bf215546Sopenharmony_ci } 200bf215546Sopenharmony_ci} 201bf215546Sopenharmony_ci 202bf215546Sopenharmony_ciuint32_t 203bf215546Sopenharmony_ciradv_translate_tex_dataformat(VkFormat format, const struct util_format_description *desc, 204bf215546Sopenharmony_ci int first_non_void) 205bf215546Sopenharmony_ci{ 206bf215546Sopenharmony_ci bool uniform = true; 207bf215546Sopenharmony_ci int i; 208bf215546Sopenharmony_ci 209bf215546Sopenharmony_ci assert(vk_format_get_plane_count(format) == 1); 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci /* Colorspace (return non-RGB formats directly). */ 212bf215546Sopenharmony_ci switch (desc->colorspace) { 213bf215546Sopenharmony_ci /* Depth stencil formats */ 214bf215546Sopenharmony_ci case UTIL_FORMAT_COLORSPACE_ZS: 215bf215546Sopenharmony_ci switch (format) { 216bf215546Sopenharmony_ci case VK_FORMAT_D16_UNORM: 217bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_16; 218bf215546Sopenharmony_ci case VK_FORMAT_D24_UNORM_S8_UINT: 219bf215546Sopenharmony_ci case VK_FORMAT_X8_D24_UNORM_PACK32: 220bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_8_24; 221bf215546Sopenharmony_ci case VK_FORMAT_S8_UINT: 222bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_8; 223bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT: 224bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32; 225bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT_S8_UINT: 226bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_X24_8_32; 227bf215546Sopenharmony_ci default: 228bf215546Sopenharmony_ci goto out_unknown; 229bf215546Sopenharmony_ci } 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci case UTIL_FORMAT_COLORSPACE_YUV: 232bf215546Sopenharmony_ci goto out_unknown; /* TODO */ 233bf215546Sopenharmony_ci 234bf215546Sopenharmony_ci default: 235bf215546Sopenharmony_ci break; 236bf215546Sopenharmony_ci } 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 239bf215546Sopenharmony_ci switch (format) { 240bf215546Sopenharmony_ci /* Don't ask me why this looks inverted. PAL does the same. */ 241bf215546Sopenharmony_ci case VK_FORMAT_G8B8G8R8_422_UNORM: 242bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BG_RG; 243bf215546Sopenharmony_ci case VK_FORMAT_B8G8R8G8_422_UNORM: 244bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_GB_GR; 245bf215546Sopenharmony_ci default: 246bf215546Sopenharmony_ci goto out_unknown; 247bf215546Sopenharmony_ci } 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_RGTC) { 251bf215546Sopenharmony_ci switch (format) { 252bf215546Sopenharmony_ci case VK_FORMAT_BC4_UNORM_BLOCK: 253bf215546Sopenharmony_ci case VK_FORMAT_BC4_SNORM_BLOCK: 254bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC4; 255bf215546Sopenharmony_ci case VK_FORMAT_BC5_UNORM_BLOCK: 256bf215546Sopenharmony_ci case VK_FORMAT_BC5_SNORM_BLOCK: 257bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC5; 258bf215546Sopenharmony_ci default: 259bf215546Sopenharmony_ci break; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci 263bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_S3TC) { 264bf215546Sopenharmony_ci switch (format) { 265bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGB_UNORM_BLOCK: 266bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 267bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGBA_UNORM_BLOCK: 268bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 269bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC1; 270bf215546Sopenharmony_ci case VK_FORMAT_BC2_UNORM_BLOCK: 271bf215546Sopenharmony_ci case VK_FORMAT_BC2_SRGB_BLOCK: 272bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC2; 273bf215546Sopenharmony_ci case VK_FORMAT_BC3_UNORM_BLOCK: 274bf215546Sopenharmony_ci case VK_FORMAT_BC3_SRGB_BLOCK: 275bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC3; 276bf215546Sopenharmony_ci default: 277bf215546Sopenharmony_ci break; 278bf215546Sopenharmony_ci } 279bf215546Sopenharmony_ci } 280bf215546Sopenharmony_ci 281bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_BPTC) { 282bf215546Sopenharmony_ci switch (format) { 283bf215546Sopenharmony_ci case VK_FORMAT_BC6H_UFLOAT_BLOCK: 284bf215546Sopenharmony_ci case VK_FORMAT_BC6H_SFLOAT_BLOCK: 285bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC6; 286bf215546Sopenharmony_ci case VK_FORMAT_BC7_UNORM_BLOCK: 287bf215546Sopenharmony_ci case VK_FORMAT_BC7_SRGB_BLOCK: 288bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_BC7; 289bf215546Sopenharmony_ci default: 290bf215546Sopenharmony_ci break; 291bf215546Sopenharmony_ci } 292bf215546Sopenharmony_ci } 293bf215546Sopenharmony_ci 294bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) { 295bf215546Sopenharmony_ci switch (format) { 296bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 297bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 298bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_ETC2_RGB; 299bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 300bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 301bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA1; 302bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 303bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 304bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_ETC2_RGBA; 305bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11_UNORM_BLOCK: 306bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11_SNORM_BLOCK: 307bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_ETC2_R; 308bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 309bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 310bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_ETC2_RG; 311bf215546Sopenharmony_ci default: 312bf215546Sopenharmony_ci break; 313bf215546Sopenharmony_ci } 314bf215546Sopenharmony_ci } 315bf215546Sopenharmony_ci 316bf215546Sopenharmony_ci if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 317bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_5_9_9_9; 318bf215546Sopenharmony_ci } else if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 319bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_10_11_11; 320bf215546Sopenharmony_ci } 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci /* R8G8Bx_SNORM - TODO CxV8U8 */ 323bf215546Sopenharmony_ci 324bf215546Sopenharmony_ci /* hw cannot support mixed formats (except depth/stencil, since only 325bf215546Sopenharmony_ci * depth is read).*/ 326bf215546Sopenharmony_ci if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) 327bf215546Sopenharmony_ci goto out_unknown; 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ci /* See whether the components are of the same size. */ 330bf215546Sopenharmony_ci for (i = 1; i < desc->nr_channels; i++) { 331bf215546Sopenharmony_ci uniform = uniform && desc->channel[0].size == desc->channel[i].size; 332bf215546Sopenharmony_ci } 333bf215546Sopenharmony_ci 334bf215546Sopenharmony_ci /* Non-uniform formats. */ 335bf215546Sopenharmony_ci if (!uniform) { 336bf215546Sopenharmony_ci switch (desc->nr_channels) { 337bf215546Sopenharmony_ci case 3: 338bf215546Sopenharmony_ci if (desc->channel[0].size == 5 && desc->channel[1].size == 6 && 339bf215546Sopenharmony_ci desc->channel[2].size == 5) { 340bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_5_6_5; 341bf215546Sopenharmony_ci } 342bf215546Sopenharmony_ci goto out_unknown; 343bf215546Sopenharmony_ci case 4: 344bf215546Sopenharmony_ci if (desc->channel[0].size == 5 && desc->channel[1].size == 5 && 345bf215546Sopenharmony_ci desc->channel[2].size == 5 && desc->channel[3].size == 1) { 346bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_1_5_5_5; 347bf215546Sopenharmony_ci } 348bf215546Sopenharmony_ci if (desc->channel[0].size == 1 && desc->channel[1].size == 5 && 349bf215546Sopenharmony_ci desc->channel[2].size == 5 && desc->channel[3].size == 5) { 350bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_5_5_5_1; 351bf215546Sopenharmony_ci } 352bf215546Sopenharmony_ci if (desc->channel[0].size == 10 && desc->channel[1].size == 10 && 353bf215546Sopenharmony_ci desc->channel[2].size == 10 && desc->channel[3].size == 2) { 354bf215546Sopenharmony_ci /* Closed VK driver does this also no 2/10/10/10 snorm */ 355bf215546Sopenharmony_ci if (desc->channel[0].type == UTIL_FORMAT_TYPE_SIGNED && desc->channel[0].normalized) 356bf215546Sopenharmony_ci goto out_unknown; 357bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_2_10_10_10; 358bf215546Sopenharmony_ci } 359bf215546Sopenharmony_ci goto out_unknown; 360bf215546Sopenharmony_ci } 361bf215546Sopenharmony_ci goto out_unknown; 362bf215546Sopenharmony_ci } 363bf215546Sopenharmony_ci 364bf215546Sopenharmony_ci if (first_non_void < 0 || first_non_void > 3) 365bf215546Sopenharmony_ci goto out_unknown; 366bf215546Sopenharmony_ci 367bf215546Sopenharmony_ci /* uniform formats */ 368bf215546Sopenharmony_ci switch (desc->channel[first_non_void].size) { 369bf215546Sopenharmony_ci case 4: 370bf215546Sopenharmony_ci switch (desc->nr_channels) { 371bf215546Sopenharmony_ci#if 0 /* Not supported for render targets */ 372bf215546Sopenharmony_ci case 2: 373bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_4_4; 374bf215546Sopenharmony_ci#endif 375bf215546Sopenharmony_ci case 4: 376bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_4_4_4_4; 377bf215546Sopenharmony_ci } 378bf215546Sopenharmony_ci break; 379bf215546Sopenharmony_ci case 8: 380bf215546Sopenharmony_ci switch (desc->nr_channels) { 381bf215546Sopenharmony_ci case 1: 382bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_8; 383bf215546Sopenharmony_ci case 2: 384bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_8_8; 385bf215546Sopenharmony_ci case 4: 386bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_8_8_8_8; 387bf215546Sopenharmony_ci } 388bf215546Sopenharmony_ci break; 389bf215546Sopenharmony_ci case 16: 390bf215546Sopenharmony_ci switch (desc->nr_channels) { 391bf215546Sopenharmony_ci case 1: 392bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_16; 393bf215546Sopenharmony_ci case 2: 394bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_16_16; 395bf215546Sopenharmony_ci case 4: 396bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_16_16_16_16; 397bf215546Sopenharmony_ci } 398bf215546Sopenharmony_ci break; 399bf215546Sopenharmony_ci case 32: 400bf215546Sopenharmony_ci switch (desc->nr_channels) { 401bf215546Sopenharmony_ci case 1: 402bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32; 403bf215546Sopenharmony_ci case 2: 404bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32_32; 405bf215546Sopenharmony_ci case 3: 406bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32_32_32; 407bf215546Sopenharmony_ci case 4: 408bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32_32_32_32; 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci break; 411bf215546Sopenharmony_ci case 64: 412bf215546Sopenharmony_ci if (desc->channel[0].type != UTIL_FORMAT_TYPE_FLOAT && desc->nr_channels == 1) 413bf215546Sopenharmony_ci return V_008F14_IMG_DATA_FORMAT_32_32; 414bf215546Sopenharmony_ci break; 415bf215546Sopenharmony_ci } 416bf215546Sopenharmony_ci 417bf215546Sopenharmony_ciout_unknown: 418bf215546Sopenharmony_ci /* R600_ERR("Unable to handle texformat %d %s\n", format, vk_format_name(format)); */ 419bf215546Sopenharmony_ci return ~0; 420bf215546Sopenharmony_ci} 421bf215546Sopenharmony_ci 422bf215546Sopenharmony_ciuint32_t 423bf215546Sopenharmony_ciradv_translate_tex_numformat(VkFormat format, const struct util_format_description *desc, 424bf215546Sopenharmony_ci int first_non_void) 425bf215546Sopenharmony_ci{ 426bf215546Sopenharmony_ci assert(vk_format_get_plane_count(format) == 1); 427bf215546Sopenharmony_ci 428bf215546Sopenharmony_ci switch (format) { 429bf215546Sopenharmony_ci case VK_FORMAT_D24_UNORM_S8_UINT: 430bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UNORM; 431bf215546Sopenharmony_ci default: 432bf215546Sopenharmony_ci if (first_non_void < 0) { 433bf215546Sopenharmony_ci if (vk_format_is_compressed(format)) { 434bf215546Sopenharmony_ci switch (format) { 435bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGB_SRGB_BLOCK: 436bf215546Sopenharmony_ci case VK_FORMAT_BC1_RGBA_SRGB_BLOCK: 437bf215546Sopenharmony_ci case VK_FORMAT_BC2_SRGB_BLOCK: 438bf215546Sopenharmony_ci case VK_FORMAT_BC3_SRGB_BLOCK: 439bf215546Sopenharmony_ci case VK_FORMAT_BC7_SRGB_BLOCK: 440bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 441bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 442bf215546Sopenharmony_ci case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 443bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SRGB; 444bf215546Sopenharmony_ci case VK_FORMAT_BC4_SNORM_BLOCK: 445bf215546Sopenharmony_ci case VK_FORMAT_BC5_SNORM_BLOCK: 446bf215546Sopenharmony_ci case VK_FORMAT_BC6H_SFLOAT_BLOCK: 447bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11_SNORM_BLOCK: 448bf215546Sopenharmony_ci case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 449bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SNORM; 450bf215546Sopenharmony_ci default: 451bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UNORM; 452bf215546Sopenharmony_ci } 453bf215546Sopenharmony_ci } else if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 454bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UNORM; 455bf215546Sopenharmony_ci } else { 456bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_FLOAT; 457bf215546Sopenharmony_ci } 458bf215546Sopenharmony_ci } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 459bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SRGB; 460bf215546Sopenharmony_ci } else { 461bf215546Sopenharmony_ci switch (desc->channel[first_non_void].type) { 462bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_FLOAT: 463bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_FLOAT; 464bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_SIGNED: 465bf215546Sopenharmony_ci if (desc->channel[first_non_void].normalized) 466bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SNORM; 467bf215546Sopenharmony_ci else if (desc->channel[first_non_void].pure_integer) 468bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SINT; 469bf215546Sopenharmony_ci else 470bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_SSCALED; 471bf215546Sopenharmony_ci case UTIL_FORMAT_TYPE_UNSIGNED: 472bf215546Sopenharmony_ci if (desc->channel[first_non_void].normalized) 473bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UNORM; 474bf215546Sopenharmony_ci else if (desc->channel[first_non_void].pure_integer) 475bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UINT; 476bf215546Sopenharmony_ci else 477bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_USCALED; 478bf215546Sopenharmony_ci default: 479bf215546Sopenharmony_ci return V_008F14_IMG_NUM_FORMAT_UNORM; 480bf215546Sopenharmony_ci } 481bf215546Sopenharmony_ci } 482bf215546Sopenharmony_ci } 483bf215546Sopenharmony_ci} 484bf215546Sopenharmony_ci 485bf215546Sopenharmony_ciuint32_t 486bf215546Sopenharmony_ciradv_translate_color_numformat(VkFormat format, const struct util_format_description *desc, 487bf215546Sopenharmony_ci int first_non_void) 488bf215546Sopenharmony_ci{ 489bf215546Sopenharmony_ci unsigned ntype; 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci assert(vk_format_get_plane_count(format) == 1); 492bf215546Sopenharmony_ci 493bf215546Sopenharmony_ci if (first_non_void == -1 || desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_FLOAT) 494bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_FLOAT; 495bf215546Sopenharmony_ci else { 496bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_UNORM; 497bf215546Sopenharmony_ci if (desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) 498bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_SRGB; 499bf215546Sopenharmony_ci else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_SIGNED) { 500bf215546Sopenharmony_ci if (desc->channel[first_non_void].pure_integer) { 501bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_SINT; 502bf215546Sopenharmony_ci } else if (desc->channel[first_non_void].normalized) { 503bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_SNORM; 504bf215546Sopenharmony_ci } else 505bf215546Sopenharmony_ci ntype = ~0u; 506bf215546Sopenharmony_ci } else if (desc->channel[first_non_void].type == UTIL_FORMAT_TYPE_UNSIGNED) { 507bf215546Sopenharmony_ci if (desc->channel[first_non_void].pure_integer) { 508bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_UINT; 509bf215546Sopenharmony_ci } else if (desc->channel[first_non_void].normalized) { 510bf215546Sopenharmony_ci ntype = V_028C70_NUMBER_UNORM; 511bf215546Sopenharmony_ci } else 512bf215546Sopenharmony_ci ntype = ~0u; 513bf215546Sopenharmony_ci } 514bf215546Sopenharmony_ci } 515bf215546Sopenharmony_ci return ntype; 516bf215546Sopenharmony_ci} 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_cistatic bool 519bf215546Sopenharmony_ciradv_is_sampler_format_supported(VkFormat format, bool *linear_sampling) 520bf215546Sopenharmony_ci{ 521bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 522bf215546Sopenharmony_ci uint32_t num_format; 523bf215546Sopenharmony_ci if (format == VK_FORMAT_UNDEFINED || format == VK_FORMAT_R64_UINT || 524bf215546Sopenharmony_ci format == VK_FORMAT_R64_SINT) 525bf215546Sopenharmony_ci return false; 526bf215546Sopenharmony_ci num_format = 527bf215546Sopenharmony_ci radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format)); 528bf215546Sopenharmony_ci 529bf215546Sopenharmony_ci if (num_format == V_008F14_IMG_NUM_FORMAT_USCALED || 530bf215546Sopenharmony_ci num_format == V_008F14_IMG_NUM_FORMAT_SSCALED) 531bf215546Sopenharmony_ci return false; 532bf215546Sopenharmony_ci 533bf215546Sopenharmony_ci if (num_format == V_008F14_IMG_NUM_FORMAT_UNORM || num_format == V_008F14_IMG_NUM_FORMAT_SNORM || 534bf215546Sopenharmony_ci num_format == V_008F14_IMG_NUM_FORMAT_FLOAT || num_format == V_008F14_IMG_NUM_FORMAT_SRGB) 535bf215546Sopenharmony_ci *linear_sampling = true; 536bf215546Sopenharmony_ci else 537bf215546Sopenharmony_ci *linear_sampling = false; 538bf215546Sopenharmony_ci return radv_translate_tex_dataformat(format, vk_format_description(format), 539bf215546Sopenharmony_ci vk_format_get_first_non_void_channel(format)) != ~0U; 540bf215546Sopenharmony_ci} 541bf215546Sopenharmony_ci 542bf215546Sopenharmony_cibool 543bf215546Sopenharmony_ciradv_is_atomic_format_supported(VkFormat format) 544bf215546Sopenharmony_ci{ 545bf215546Sopenharmony_ci return format == VK_FORMAT_R32_UINT || format == VK_FORMAT_R32_SINT || 546bf215546Sopenharmony_ci format == VK_FORMAT_R32_SFLOAT || format == VK_FORMAT_R64_UINT || 547bf215546Sopenharmony_ci format == VK_FORMAT_R64_SINT; 548bf215546Sopenharmony_ci} 549bf215546Sopenharmony_ci 550bf215546Sopenharmony_cibool 551bf215546Sopenharmony_ciradv_is_storage_image_format_supported(struct radv_physical_device *physical_device, 552bf215546Sopenharmony_ci VkFormat format) 553bf215546Sopenharmony_ci{ 554bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 555bf215546Sopenharmony_ci unsigned data_format, num_format; 556bf215546Sopenharmony_ci if (format == VK_FORMAT_UNDEFINED) 557bf215546Sopenharmony_ci return false; 558bf215546Sopenharmony_ci 559bf215546Sopenharmony_ci data_format = 560bf215546Sopenharmony_ci radv_translate_tex_dataformat(format, desc, vk_format_get_first_non_void_channel(format)); 561bf215546Sopenharmony_ci num_format = 562bf215546Sopenharmony_ci radv_translate_tex_numformat(format, desc, vk_format_get_first_non_void_channel(format)); 563bf215546Sopenharmony_ci 564bf215546Sopenharmony_ci if (data_format == ~0 || num_format == ~0) 565bf215546Sopenharmony_ci return false; 566bf215546Sopenharmony_ci 567bf215546Sopenharmony_ci /* Extracted from the GCN3 ISA document. */ 568bf215546Sopenharmony_ci switch (num_format) { 569bf215546Sopenharmony_ci case V_008F14_IMG_NUM_FORMAT_UNORM: 570bf215546Sopenharmony_ci case V_008F14_IMG_NUM_FORMAT_SNORM: 571bf215546Sopenharmony_ci case V_008F14_IMG_NUM_FORMAT_UINT: 572bf215546Sopenharmony_ci case V_008F14_IMG_NUM_FORMAT_SINT: 573bf215546Sopenharmony_ci case V_008F14_IMG_NUM_FORMAT_FLOAT: 574bf215546Sopenharmony_ci break; 575bf215546Sopenharmony_ci default: 576bf215546Sopenharmony_ci return false; 577bf215546Sopenharmony_ci } 578bf215546Sopenharmony_ci 579bf215546Sopenharmony_ci switch (data_format) { 580bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_8: 581bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_16: 582bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_8_8: 583bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_32: 584bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_16_16: 585bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_10_11_11: 586bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_11_11_10: 587bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_10_10_10_2: 588bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_2_10_10_10: 589bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_8_8_8_8: 590bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_32_32: 591bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_16_16_16_16: 592bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_32_32_32_32: 593bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_5_6_5: 594bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_1_5_5_5: 595bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_5_5_5_1: 596bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_4_4_4_4: 597bf215546Sopenharmony_ci /* TODO: FMASK formats. */ 598bf215546Sopenharmony_ci return true; 599bf215546Sopenharmony_ci case V_008F14_IMG_DATA_FORMAT_5_9_9_9: 600bf215546Sopenharmony_ci return physical_device->rad_info.gfx_level >= GFX10_3; 601bf215546Sopenharmony_ci default: 602bf215546Sopenharmony_ci return false; 603bf215546Sopenharmony_ci } 604bf215546Sopenharmony_ci} 605bf215546Sopenharmony_ci 606bf215546Sopenharmony_cibool 607bf215546Sopenharmony_ciradv_is_buffer_format_supported(VkFormat format, bool *scaled) 608bf215546Sopenharmony_ci{ 609bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 610bf215546Sopenharmony_ci unsigned data_format, num_format; 611bf215546Sopenharmony_ci if (format == VK_FORMAT_UNDEFINED) 612bf215546Sopenharmony_ci return false; 613bf215546Sopenharmony_ci 614bf215546Sopenharmony_ci data_format = 615bf215546Sopenharmony_ci radv_translate_buffer_dataformat(desc, vk_format_get_first_non_void_channel(format)); 616bf215546Sopenharmony_ci num_format = radv_translate_buffer_numformat(desc, vk_format_get_first_non_void_channel(format)); 617bf215546Sopenharmony_ci 618bf215546Sopenharmony_ci if (scaled) 619bf215546Sopenharmony_ci *scaled = (num_format == V_008F0C_BUF_NUM_FORMAT_SSCALED) || 620bf215546Sopenharmony_ci (num_format == V_008F0C_BUF_NUM_FORMAT_USCALED); 621bf215546Sopenharmony_ci return data_format != V_008F0C_BUF_DATA_FORMAT_INVALID && num_format != ~0; 622bf215546Sopenharmony_ci} 623bf215546Sopenharmony_ci 624bf215546Sopenharmony_cibool 625bf215546Sopenharmony_ciradv_is_colorbuffer_format_supported(const struct radv_physical_device *pdevice, VkFormat format, 626bf215546Sopenharmony_ci bool *blendable) 627bf215546Sopenharmony_ci{ 628bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 629bf215546Sopenharmony_ci uint32_t color_format = radv_translate_colorformat(format); 630bf215546Sopenharmony_ci uint32_t color_swap = radv_translate_colorswap(format, false); 631bf215546Sopenharmony_ci uint32_t color_num_format = 632bf215546Sopenharmony_ci radv_translate_color_numformat(format, desc, vk_format_get_first_non_void_channel(format)); 633bf215546Sopenharmony_ci 634bf215546Sopenharmony_ci if (color_num_format == V_028C70_NUMBER_UINT || color_num_format == V_028C70_NUMBER_SINT || 635bf215546Sopenharmony_ci color_format == V_028C70_COLOR_8_24 || color_format == V_028C70_COLOR_24_8 || 636bf215546Sopenharmony_ci color_format == V_028C70_COLOR_X24_8_32_FLOAT) { 637bf215546Sopenharmony_ci *blendable = false; 638bf215546Sopenharmony_ci } else 639bf215546Sopenharmony_ci *blendable = true; 640bf215546Sopenharmony_ci 641bf215546Sopenharmony_ci if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32 && pdevice->rad_info.gfx_level < GFX10_3) 642bf215546Sopenharmony_ci return false; 643bf215546Sopenharmony_ci 644bf215546Sopenharmony_ci return color_format != V_028C70_COLOR_INVALID && color_swap != ~0U && color_num_format != ~0; 645bf215546Sopenharmony_ci} 646bf215546Sopenharmony_ci 647bf215546Sopenharmony_cistatic bool 648bf215546Sopenharmony_ciradv_is_zs_format_supported(VkFormat format) 649bf215546Sopenharmony_ci{ 650bf215546Sopenharmony_ci return radv_translate_dbformat(format) != V_028040_Z_INVALID || format == VK_FORMAT_S8_UINT; 651bf215546Sopenharmony_ci} 652bf215546Sopenharmony_ci 653bf215546Sopenharmony_cistatic bool 654bf215546Sopenharmony_ciradv_is_filter_minmax_format_supported(VkFormat format) 655bf215546Sopenharmony_ci{ 656bf215546Sopenharmony_ci /* From the Vulkan spec 1.1.71: 657bf215546Sopenharmony_ci * 658bf215546Sopenharmony_ci * "The following formats must support the 659bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT feature with 660bf215546Sopenharmony_ci * VK_IMAGE_TILING_OPTIMAL, if they support 661bf215546Sopenharmony_ci * VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT." 662bf215546Sopenharmony_ci */ 663bf215546Sopenharmony_ci /* TODO: enable more formats. */ 664bf215546Sopenharmony_ci switch (format) { 665bf215546Sopenharmony_ci case VK_FORMAT_R8_UNORM: 666bf215546Sopenharmony_ci case VK_FORMAT_R8_SNORM: 667bf215546Sopenharmony_ci case VK_FORMAT_R16_UNORM: 668bf215546Sopenharmony_ci case VK_FORMAT_R16_SNORM: 669bf215546Sopenharmony_ci case VK_FORMAT_R16_SFLOAT: 670bf215546Sopenharmony_ci case VK_FORMAT_R32_SFLOAT: 671bf215546Sopenharmony_ci case VK_FORMAT_D16_UNORM: 672bf215546Sopenharmony_ci case VK_FORMAT_X8_D24_UNORM_PACK32: 673bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT: 674bf215546Sopenharmony_ci case VK_FORMAT_D16_UNORM_S8_UINT: 675bf215546Sopenharmony_ci case VK_FORMAT_D24_UNORM_S8_UINT: 676bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT_S8_UINT: 677bf215546Sopenharmony_ci return true; 678bf215546Sopenharmony_ci default: 679bf215546Sopenharmony_ci return false; 680bf215546Sopenharmony_ci } 681bf215546Sopenharmony_ci} 682bf215546Sopenharmony_ci 683bf215546Sopenharmony_cibool 684bf215546Sopenharmony_ciradv_device_supports_etc(struct radv_physical_device *physical_device) 685bf215546Sopenharmony_ci{ 686bf215546Sopenharmony_ci return physical_device->rad_info.family == CHIP_VEGA10 || 687bf215546Sopenharmony_ci physical_device->rad_info.family == CHIP_RAVEN || 688bf215546Sopenharmony_ci physical_device->rad_info.family == CHIP_RAVEN2 || 689bf215546Sopenharmony_ci physical_device->rad_info.family == CHIP_STONEY; 690bf215546Sopenharmony_ci} 691bf215546Sopenharmony_ci 692bf215546Sopenharmony_cistatic void 693bf215546Sopenharmony_ciradv_physical_device_get_format_properties(struct radv_physical_device *physical_device, 694bf215546Sopenharmony_ci VkFormat format, VkFormatProperties3 *out_properties) 695bf215546Sopenharmony_ci{ 696bf215546Sopenharmony_ci VkFormatFeatureFlags2 linear = 0, tiled = 0, buffer = 0; 697bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 698bf215546Sopenharmony_ci bool blendable; 699bf215546Sopenharmony_ci bool scaled = false; 700bf215546Sopenharmony_ci /* TODO: implement some software emulation of SUBSAMPLED formats. */ 701bf215546Sopenharmony_ci if (desc->format == PIPE_FORMAT_NONE || desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 702bf215546Sopenharmony_ci out_properties->linearTilingFeatures = linear; 703bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = tiled; 704bf215546Sopenharmony_ci out_properties->bufferFeatures = buffer; 705bf215546Sopenharmony_ci return; 706bf215546Sopenharmony_ci } 707bf215546Sopenharmony_ci 708bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && !radv_device_supports_etc(physical_device) && 709bf215546Sopenharmony_ci !physical_device->emulate_etc2) { 710bf215546Sopenharmony_ci out_properties->linearTilingFeatures = linear; 711bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = tiled; 712bf215546Sopenharmony_ci out_properties->bufferFeatures = buffer; 713bf215546Sopenharmony_ci return; 714bf215546Sopenharmony_ci } 715bf215546Sopenharmony_ci 716bf215546Sopenharmony_ci const bool multiplanar = vk_format_get_plane_count(format) > 1; 717bf215546Sopenharmony_ci if (multiplanar || desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 718bf215546Sopenharmony_ci uint64_t tiling = VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | 719bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT | 720bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | 721bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_COSITED_CHROMA_SAMPLES_BIT | 722bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_MIDPOINT_CHROMA_SAMPLES_BIT; 723bf215546Sopenharmony_ci 724bf215546Sopenharmony_ci /* The subsampled formats have no support for linear filters. */ 725bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 726bf215546Sopenharmony_ci tiling |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_YCBCR_CONVERSION_LINEAR_FILTER_BIT; 727bf215546Sopenharmony_ci } 728bf215546Sopenharmony_ci 729bf215546Sopenharmony_ci if (multiplanar) 730bf215546Sopenharmony_ci tiling |= VK_FORMAT_FEATURE_2_DISJOINT_BIT; 731bf215546Sopenharmony_ci 732bf215546Sopenharmony_ci /* Fails for unknown reasons with linear tiling & subsampled formats. */ 733bf215546Sopenharmony_ci out_properties->linearTilingFeatures = 734bf215546Sopenharmony_ci desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED ? 0 : tiling; 735bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = tiling; 736bf215546Sopenharmony_ci out_properties->bufferFeatures = 0; 737bf215546Sopenharmony_ci return; 738bf215546Sopenharmony_ci } 739bf215546Sopenharmony_ci 740bf215546Sopenharmony_ci if (radv_is_storage_image_format_supported(physical_device, format)) { 741bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT | 742bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | 743bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 744bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT | 745bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | 746bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 747bf215546Sopenharmony_ci } 748bf215546Sopenharmony_ci 749bf215546Sopenharmony_ci if (radv_is_buffer_format_supported(format, &scaled)) { 750bf215546Sopenharmony_ci if (format != VK_FORMAT_R64_UINT && format != VK_FORMAT_R64_SINT && 751bf215546Sopenharmony_ci !vk_format_is_srgb(format)) { 752bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_2_VERTEX_BUFFER_BIT; 753bf215546Sopenharmony_ci if (!scaled) 754bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT; 755bf215546Sopenharmony_ci } 756bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT | 757bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_READ_WITHOUT_FORMAT_BIT | 758bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_STORAGE_WRITE_WITHOUT_FORMAT_BIT; 759bf215546Sopenharmony_ci } 760bf215546Sopenharmony_ci 761bf215546Sopenharmony_ci if (vk_format_is_depth_or_stencil(format)) { 762bf215546Sopenharmony_ci if (radv_is_zs_format_supported(format)) { 763bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT; 764bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT; 765bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_BLIT_SRC_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 766bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 767bf215546Sopenharmony_ci 768bf215546Sopenharmony_ci if (radv_is_filter_minmax_format_supported(format)) 769bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT; 770bf215546Sopenharmony_ci 771bf215546Sopenharmony_ci if (vk_format_has_depth(format)) { 772bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT | 773bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_DEPTH_COMPARISON_BIT; 774bf215546Sopenharmony_ci } 775bf215546Sopenharmony_ci 776bf215546Sopenharmony_ci /* Don't support blitting surfaces with depth/stencil. */ 777bf215546Sopenharmony_ci if (vk_format_has_depth(format) && vk_format_has_stencil(format)) 778bf215546Sopenharmony_ci tiled &= ~VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 779bf215546Sopenharmony_ci 780bf215546Sopenharmony_ci /* Don't support linear depth surfaces */ 781bf215546Sopenharmony_ci linear = 0; 782bf215546Sopenharmony_ci } 783bf215546Sopenharmony_ci } else { 784bf215546Sopenharmony_ci bool linear_sampling; 785bf215546Sopenharmony_ci if (radv_is_sampler_format_supported(format, &linear_sampling)) { 786bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT; 787bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT | VK_FORMAT_FEATURE_2_BLIT_SRC_BIT; 788bf215546Sopenharmony_ci 789bf215546Sopenharmony_ci if (radv_is_filter_minmax_format_supported(format)) 790bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_MINMAX_BIT; 791bf215546Sopenharmony_ci 792bf215546Sopenharmony_ci if (linear_sampling) { 793bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 794bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_FILTER_LINEAR_BIT; 795bf215546Sopenharmony_ci } 796bf215546Sopenharmony_ci 797bf215546Sopenharmony_ci /* Don't support blitting for R32G32B32 formats. */ 798bf215546Sopenharmony_ci if (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_UINT || 799bf215546Sopenharmony_ci format == VK_FORMAT_R32G32B32_SINT) { 800bf215546Sopenharmony_ci linear &= ~VK_FORMAT_FEATURE_2_BLIT_SRC_BIT; 801bf215546Sopenharmony_ci } 802bf215546Sopenharmony_ci } 803bf215546Sopenharmony_ci if (radv_is_colorbuffer_format_supported(physical_device, format, &blendable)) { 804bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 805bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | VK_FORMAT_FEATURE_2_BLIT_DST_BIT; 806bf215546Sopenharmony_ci if (blendable) { 807bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT; 808bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BLEND_BIT; 809bf215546Sopenharmony_ci } 810bf215546Sopenharmony_ci } 811bf215546Sopenharmony_ci if (tiled && !scaled) { 812bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 813bf215546Sopenharmony_ci } 814bf215546Sopenharmony_ci 815bf215546Sopenharmony_ci /* Tiled formatting does not support NPOT pixel sizes */ 816bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(vk_format_get_blocksize(format))) 817bf215546Sopenharmony_ci tiled = 0; 818bf215546Sopenharmony_ci } 819bf215546Sopenharmony_ci 820bf215546Sopenharmony_ci if (linear && !scaled) { 821bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT | VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; 822bf215546Sopenharmony_ci } 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci if (radv_is_atomic_format_supported(format)) { 825bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_ATOMIC_BIT; 826bf215546Sopenharmony_ci linear |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; 827bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_STORAGE_IMAGE_ATOMIC_BIT; 828bf215546Sopenharmony_ci } 829bf215546Sopenharmony_ci 830bf215546Sopenharmony_ci switch (format) { 831bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SNORM_PACK32: 832bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SNORM_PACK32: 833bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SSCALED_PACK32: 834bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SSCALED_PACK32: 835bf215546Sopenharmony_ci case VK_FORMAT_A2R10G10B10_SINT_PACK32: 836bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_SINT_PACK32: 837bf215546Sopenharmony_ci buffer &= 838bf215546Sopenharmony_ci ~(VK_FORMAT_FEATURE_2_UNIFORM_TEXEL_BUFFER_BIT | VK_FORMAT_FEATURE_2_STORAGE_TEXEL_BUFFER_BIT); 839bf215546Sopenharmony_ci linear = 0; 840bf215546Sopenharmony_ci tiled = 0; 841bf215546Sopenharmony_ci break; 842bf215546Sopenharmony_ci default: 843bf215546Sopenharmony_ci break; 844bf215546Sopenharmony_ci } 845bf215546Sopenharmony_ci 846bf215546Sopenharmony_ci switch (format) { 847bf215546Sopenharmony_ci case VK_FORMAT_R32G32_SFLOAT: 848bf215546Sopenharmony_ci case VK_FORMAT_R32G32B32_SFLOAT: 849bf215546Sopenharmony_ci case VK_FORMAT_R32G32B32A32_SFLOAT: 850bf215546Sopenharmony_ci case VK_FORMAT_R16G16_SFLOAT: 851bf215546Sopenharmony_ci case VK_FORMAT_R16G16B16_SFLOAT: 852bf215546Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SFLOAT: 853bf215546Sopenharmony_ci case VK_FORMAT_R16G16_SNORM: 854bf215546Sopenharmony_ci case VK_FORMAT_R16G16_UNORM: 855bf215546Sopenharmony_ci case VK_FORMAT_R16G16B16A16_SNORM: 856bf215546Sopenharmony_ci case VK_FORMAT_R16G16B16A16_UNORM: 857bf215546Sopenharmony_ci case VK_FORMAT_R8G8_SNORM: 858bf215546Sopenharmony_ci case VK_FORMAT_R8G8_UNORM: 859bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8A8_SNORM: 860bf215546Sopenharmony_ci case VK_FORMAT_R8G8B8A8_UNORM: 861bf215546Sopenharmony_ci case VK_FORMAT_A2B10G10R10_UNORM_PACK32: 862bf215546Sopenharmony_ci buffer |= VK_FORMAT_FEATURE_2_ACCELERATION_STRUCTURE_VERTEX_BUFFER_BIT_KHR; 863bf215546Sopenharmony_ci break; 864bf215546Sopenharmony_ci default: 865bf215546Sopenharmony_ci break; 866bf215546Sopenharmony_ci } 867bf215546Sopenharmony_ci /* addrlib does not support linear compressed textures. */ 868bf215546Sopenharmony_ci if (vk_format_is_compressed(format)) 869bf215546Sopenharmony_ci linear = 0; 870bf215546Sopenharmony_ci 871bf215546Sopenharmony_ci /* From the Vulkan spec 1.2.163: 872bf215546Sopenharmony_ci * 873bf215546Sopenharmony_ci * "VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT must be supported for the 874bf215546Sopenharmony_ci * following formats if the attachmentFragmentShadingRate feature is supported:" 875bf215546Sopenharmony_ci * 876bf215546Sopenharmony_ci * - VK_FORMAT_R8_UINT 877bf215546Sopenharmony_ci */ 878bf215546Sopenharmony_ci if (format == VK_FORMAT_R8_UINT) { 879bf215546Sopenharmony_ci tiled |= VK_FORMAT_FEATURE_2_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR; 880bf215546Sopenharmony_ci } 881bf215546Sopenharmony_ci 882bf215546Sopenharmony_ci /* It's invalid to expose buffer features with depth/stencil formats. */ 883bf215546Sopenharmony_ci if (vk_format_is_depth_or_stencil(format)) { 884bf215546Sopenharmony_ci buffer = 0; 885bf215546Sopenharmony_ci } 886bf215546Sopenharmony_ci 887bf215546Sopenharmony_ci out_properties->linearTilingFeatures = linear; 888bf215546Sopenharmony_ci out_properties->optimalTilingFeatures = tiled; 889bf215546Sopenharmony_ci out_properties->bufferFeatures = buffer; 890bf215546Sopenharmony_ci} 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ciuint32_t 893bf215546Sopenharmony_ciradv_translate_colorformat(VkFormat format) 894bf215546Sopenharmony_ci{ 895bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 896bf215546Sopenharmony_ci 897bf215546Sopenharmony_ci#define HAS_SIZE(x, y, z, w) \ 898bf215546Sopenharmony_ci (desc->channel[0].size == (x) && desc->channel[1].size == (y) && \ 899bf215546Sopenharmony_ci desc->channel[2].size == (z) && desc->channel[3].size == (w)) 900bf215546Sopenharmony_ci 901bf215546Sopenharmony_ci if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) /* isn't plain */ 902bf215546Sopenharmony_ci return V_028C70_COLOR_10_11_11; 903bf215546Sopenharmony_ci 904bf215546Sopenharmony_ci if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) 905bf215546Sopenharmony_ci return V_028C70_COLOR_5_9_9_9; 906bf215546Sopenharmony_ci 907bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) 908bf215546Sopenharmony_ci return V_028C70_COLOR_INVALID; 909bf215546Sopenharmony_ci 910bf215546Sopenharmony_ci /* hw cannot support mixed formats (except depth/stencil, since 911bf215546Sopenharmony_ci * stencil is not written to). */ 912bf215546Sopenharmony_ci if (desc->is_mixed && desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS) 913bf215546Sopenharmony_ci return V_028C70_COLOR_INVALID; 914bf215546Sopenharmony_ci 915bf215546Sopenharmony_ci switch (desc->nr_channels) { 916bf215546Sopenharmony_ci case 1: 917bf215546Sopenharmony_ci switch (desc->channel[0].size) { 918bf215546Sopenharmony_ci case 8: 919bf215546Sopenharmony_ci return V_028C70_COLOR_8; 920bf215546Sopenharmony_ci case 16: 921bf215546Sopenharmony_ci return V_028C70_COLOR_16; 922bf215546Sopenharmony_ci case 32: 923bf215546Sopenharmony_ci return V_028C70_COLOR_32; 924bf215546Sopenharmony_ci } 925bf215546Sopenharmony_ci break; 926bf215546Sopenharmony_ci case 2: 927bf215546Sopenharmony_ci if (desc->channel[0].size == desc->channel[1].size) { 928bf215546Sopenharmony_ci switch (desc->channel[0].size) { 929bf215546Sopenharmony_ci case 8: 930bf215546Sopenharmony_ci return V_028C70_COLOR_8_8; 931bf215546Sopenharmony_ci case 16: 932bf215546Sopenharmony_ci return V_028C70_COLOR_16_16; 933bf215546Sopenharmony_ci case 32: 934bf215546Sopenharmony_ci return V_028C70_COLOR_32_32; 935bf215546Sopenharmony_ci } 936bf215546Sopenharmony_ci } else if (HAS_SIZE(8, 24, 0, 0)) { 937bf215546Sopenharmony_ci return V_028C70_COLOR_24_8; 938bf215546Sopenharmony_ci } else if (HAS_SIZE(24, 8, 0, 0)) { 939bf215546Sopenharmony_ci return V_028C70_COLOR_8_24; 940bf215546Sopenharmony_ci } 941bf215546Sopenharmony_ci break; 942bf215546Sopenharmony_ci case 3: 943bf215546Sopenharmony_ci if (HAS_SIZE(5, 6, 5, 0)) { 944bf215546Sopenharmony_ci return V_028C70_COLOR_5_6_5; 945bf215546Sopenharmony_ci } else if (HAS_SIZE(32, 8, 24, 0)) { 946bf215546Sopenharmony_ci return V_028C70_COLOR_X24_8_32_FLOAT; 947bf215546Sopenharmony_ci } 948bf215546Sopenharmony_ci break; 949bf215546Sopenharmony_ci case 4: 950bf215546Sopenharmony_ci if (desc->channel[0].size == desc->channel[1].size && 951bf215546Sopenharmony_ci desc->channel[0].size == desc->channel[2].size && 952bf215546Sopenharmony_ci desc->channel[0].size == desc->channel[3].size) { 953bf215546Sopenharmony_ci switch (desc->channel[0].size) { 954bf215546Sopenharmony_ci case 4: 955bf215546Sopenharmony_ci return V_028C70_COLOR_4_4_4_4; 956bf215546Sopenharmony_ci case 8: 957bf215546Sopenharmony_ci return V_028C70_COLOR_8_8_8_8; 958bf215546Sopenharmony_ci case 16: 959bf215546Sopenharmony_ci return V_028C70_COLOR_16_16_16_16; 960bf215546Sopenharmony_ci case 32: 961bf215546Sopenharmony_ci return V_028C70_COLOR_32_32_32_32; 962bf215546Sopenharmony_ci } 963bf215546Sopenharmony_ci } else if (HAS_SIZE(5, 5, 5, 1)) { 964bf215546Sopenharmony_ci return V_028C70_COLOR_1_5_5_5; 965bf215546Sopenharmony_ci } else if (HAS_SIZE(1, 5, 5, 5)) { 966bf215546Sopenharmony_ci return V_028C70_COLOR_5_5_5_1; 967bf215546Sopenharmony_ci } else if (HAS_SIZE(10, 10, 10, 2)) { 968bf215546Sopenharmony_ci return V_028C70_COLOR_2_10_10_10; 969bf215546Sopenharmony_ci } 970bf215546Sopenharmony_ci break; 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci return V_028C70_COLOR_INVALID; 973bf215546Sopenharmony_ci} 974bf215546Sopenharmony_ci 975bf215546Sopenharmony_ciuint32_t 976bf215546Sopenharmony_ciradv_colorformat_endian_swap(uint32_t colorformat) 977bf215546Sopenharmony_ci{ 978bf215546Sopenharmony_ci if (0 /*SI_BIG_ENDIAN*/) { 979bf215546Sopenharmony_ci switch (colorformat) { 980bf215546Sopenharmony_ci /* 8-bit buffers. */ 981bf215546Sopenharmony_ci case V_028C70_COLOR_8: 982bf215546Sopenharmony_ci return V_028C70_ENDIAN_NONE; 983bf215546Sopenharmony_ci 984bf215546Sopenharmony_ci /* 16-bit buffers. */ 985bf215546Sopenharmony_ci case V_028C70_COLOR_5_6_5: 986bf215546Sopenharmony_ci case V_028C70_COLOR_1_5_5_5: 987bf215546Sopenharmony_ci case V_028C70_COLOR_4_4_4_4: 988bf215546Sopenharmony_ci case V_028C70_COLOR_16: 989bf215546Sopenharmony_ci case V_028C70_COLOR_8_8: 990bf215546Sopenharmony_ci return V_028C70_ENDIAN_8IN16; 991bf215546Sopenharmony_ci 992bf215546Sopenharmony_ci /* 32-bit buffers. */ 993bf215546Sopenharmony_ci case V_028C70_COLOR_8_8_8_8: 994bf215546Sopenharmony_ci case V_028C70_COLOR_2_10_10_10: 995bf215546Sopenharmony_ci case V_028C70_COLOR_8_24: 996bf215546Sopenharmony_ci case V_028C70_COLOR_24_8: 997bf215546Sopenharmony_ci case V_028C70_COLOR_16_16: 998bf215546Sopenharmony_ci return V_028C70_ENDIAN_8IN32; 999bf215546Sopenharmony_ci 1000bf215546Sopenharmony_ci /* 64-bit buffers. */ 1001bf215546Sopenharmony_ci case V_028C70_COLOR_16_16_16_16: 1002bf215546Sopenharmony_ci return V_028C70_ENDIAN_8IN16; 1003bf215546Sopenharmony_ci 1004bf215546Sopenharmony_ci case V_028C70_COLOR_32_32: 1005bf215546Sopenharmony_ci return V_028C70_ENDIAN_8IN32; 1006bf215546Sopenharmony_ci 1007bf215546Sopenharmony_ci /* 128-bit buffers. */ 1008bf215546Sopenharmony_ci case V_028C70_COLOR_32_32_32_32: 1009bf215546Sopenharmony_ci return V_028C70_ENDIAN_8IN32; 1010bf215546Sopenharmony_ci default: 1011bf215546Sopenharmony_ci return V_028C70_ENDIAN_NONE; /* Unsupported. */ 1012bf215546Sopenharmony_ci } 1013bf215546Sopenharmony_ci } else { 1014bf215546Sopenharmony_ci return V_028C70_ENDIAN_NONE; 1015bf215546Sopenharmony_ci } 1016bf215546Sopenharmony_ci} 1017bf215546Sopenharmony_ci 1018bf215546Sopenharmony_ciuint32_t 1019bf215546Sopenharmony_ciradv_translate_dbformat(VkFormat format) 1020bf215546Sopenharmony_ci{ 1021bf215546Sopenharmony_ci switch (format) { 1022bf215546Sopenharmony_ci case VK_FORMAT_D16_UNORM: 1023bf215546Sopenharmony_ci case VK_FORMAT_D16_UNORM_S8_UINT: 1024bf215546Sopenharmony_ci return V_028040_Z_16; 1025bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT: 1026bf215546Sopenharmony_ci case VK_FORMAT_D32_SFLOAT_S8_UINT: 1027bf215546Sopenharmony_ci return V_028040_Z_32_FLOAT; 1028bf215546Sopenharmony_ci default: 1029bf215546Sopenharmony_ci return V_028040_Z_INVALID; 1030bf215546Sopenharmony_ci } 1031bf215546Sopenharmony_ci} 1032bf215546Sopenharmony_ci 1033bf215546Sopenharmony_ciunsigned 1034bf215546Sopenharmony_ciradv_translate_colorswap(VkFormat format, bool do_endian_swap) 1035bf215546Sopenharmony_ci{ 1036bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 1037bf215546Sopenharmony_ci 1038bf215546Sopenharmony_ci#define HAS_SWIZZLE(chan, swz) (desc->swizzle[chan] == PIPE_SWIZZLE_##swz) 1039bf215546Sopenharmony_ci 1040bf215546Sopenharmony_ci if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) 1041bf215546Sopenharmony_ci return V_028C70_SWAP_STD; 1042bf215546Sopenharmony_ci 1043bf215546Sopenharmony_ci if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) 1044bf215546Sopenharmony_ci return V_028C70_SWAP_STD; 1045bf215546Sopenharmony_ci 1046bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) 1047bf215546Sopenharmony_ci return ~0U; 1048bf215546Sopenharmony_ci 1049bf215546Sopenharmony_ci switch (desc->nr_channels) { 1050bf215546Sopenharmony_ci case 1: 1051bf215546Sopenharmony_ci if (HAS_SWIZZLE(0, X)) 1052bf215546Sopenharmony_ci return V_028C70_SWAP_STD; /* X___ */ 1053bf215546Sopenharmony_ci else if (HAS_SWIZZLE(3, X)) 1054bf215546Sopenharmony_ci return V_028C70_SWAP_ALT_REV; /* ___X */ 1055bf215546Sopenharmony_ci break; 1056bf215546Sopenharmony_ci case 2: 1057bf215546Sopenharmony_ci if ((HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, Y)) || (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(1, NONE)) || 1058bf215546Sopenharmony_ci (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, Y))) 1059bf215546Sopenharmony_ci return V_028C70_SWAP_STD; /* XY__ */ 1060bf215546Sopenharmony_ci else if ((HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, X)) || 1061bf215546Sopenharmony_ci (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(1, NONE)) || 1062bf215546Sopenharmony_ci (HAS_SWIZZLE(0, NONE) && HAS_SWIZZLE(1, X))) 1063bf215546Sopenharmony_ci /* YX__ */ 1064bf215546Sopenharmony_ci return (do_endian_swap ? V_028C70_SWAP_STD : V_028C70_SWAP_STD_REV); 1065bf215546Sopenharmony_ci else if (HAS_SWIZZLE(0, X) && HAS_SWIZZLE(3, Y)) 1066bf215546Sopenharmony_ci return V_028C70_SWAP_ALT; /* X__Y */ 1067bf215546Sopenharmony_ci else if (HAS_SWIZZLE(0, Y) && HAS_SWIZZLE(3, X)) 1068bf215546Sopenharmony_ci return V_028C70_SWAP_ALT_REV; /* Y__X */ 1069bf215546Sopenharmony_ci break; 1070bf215546Sopenharmony_ci case 3: 1071bf215546Sopenharmony_ci if (HAS_SWIZZLE(0, X)) 1072bf215546Sopenharmony_ci return (do_endian_swap ? V_028C70_SWAP_STD_REV : V_028C70_SWAP_STD); 1073bf215546Sopenharmony_ci else if (HAS_SWIZZLE(0, Z)) 1074bf215546Sopenharmony_ci return V_028C70_SWAP_STD_REV; /* ZYX */ 1075bf215546Sopenharmony_ci break; 1076bf215546Sopenharmony_ci case 4: 1077bf215546Sopenharmony_ci /* check the middle channels, the 1st and 4th channel can be NONE */ 1078bf215546Sopenharmony_ci if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, Z)) { 1079bf215546Sopenharmony_ci return V_028C70_SWAP_STD; /* XYZW */ 1080bf215546Sopenharmony_ci } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, Y)) { 1081bf215546Sopenharmony_ci return V_028C70_SWAP_STD_REV; /* WZYX */ 1082bf215546Sopenharmony_ci } else if (HAS_SWIZZLE(1, Y) && HAS_SWIZZLE(2, X)) { 1083bf215546Sopenharmony_ci return V_028C70_SWAP_ALT; /* ZYXW */ 1084bf215546Sopenharmony_ci } else if (HAS_SWIZZLE(1, Z) && HAS_SWIZZLE(2, W)) { 1085bf215546Sopenharmony_ci /* YZWX */ 1086bf215546Sopenharmony_ci if (desc->is_array) 1087bf215546Sopenharmony_ci return V_028C70_SWAP_ALT_REV; 1088bf215546Sopenharmony_ci else 1089bf215546Sopenharmony_ci return (do_endian_swap ? V_028C70_SWAP_ALT : V_028C70_SWAP_ALT_REV); 1090bf215546Sopenharmony_ci } 1091bf215546Sopenharmony_ci break; 1092bf215546Sopenharmony_ci } 1093bf215546Sopenharmony_ci return ~0U; 1094bf215546Sopenharmony_ci} 1095bf215546Sopenharmony_ci 1096bf215546Sopenharmony_cibool 1097bf215546Sopenharmony_ciradv_format_pack_clear_color(VkFormat format, uint32_t clear_vals[2], VkClearColorValue *value) 1098bf215546Sopenharmony_ci{ 1099bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 1100bf215546Sopenharmony_ci 1101bf215546Sopenharmony_ci if (format == VK_FORMAT_B10G11R11_UFLOAT_PACK32) { 1102bf215546Sopenharmony_ci clear_vals[0] = float3_to_r11g11b10f(value->float32); 1103bf215546Sopenharmony_ci clear_vals[1] = 0; 1104bf215546Sopenharmony_ci return true; 1105bf215546Sopenharmony_ci } else if (format == VK_FORMAT_E5B9G9R9_UFLOAT_PACK32) { 1106bf215546Sopenharmony_ci clear_vals[0] = float3_to_rgb9e5(value->float32); 1107bf215546Sopenharmony_ci clear_vals[1] = 0; 1108bf215546Sopenharmony_ci return true; 1109bf215546Sopenharmony_ci } 1110bf215546Sopenharmony_ci 1111bf215546Sopenharmony_ci if (desc->layout != UTIL_FORMAT_LAYOUT_PLAIN) { 1112bf215546Sopenharmony_ci fprintf(stderr, "failed to fast clear for non-plain format %d\n", format); 1113bf215546Sopenharmony_ci return false; 1114bf215546Sopenharmony_ci } 1115bf215546Sopenharmony_ci 1116bf215546Sopenharmony_ci if (!util_is_power_of_two_or_zero(desc->block.bits)) { 1117bf215546Sopenharmony_ci fprintf(stderr, "failed to fast clear for NPOT format %d\n", format); 1118bf215546Sopenharmony_ci return false; 1119bf215546Sopenharmony_ci } 1120bf215546Sopenharmony_ci 1121bf215546Sopenharmony_ci if (desc->block.bits > 64) { 1122bf215546Sopenharmony_ci /* 1123bf215546Sopenharmony_ci * We have a 128 bits format, check if the first 3 components are the same. 1124bf215546Sopenharmony_ci * Every elements has to be 32 bits since we don't support 64-bit formats, 1125bf215546Sopenharmony_ci * and we can skip swizzling checks as alpha always comes last for these and 1126bf215546Sopenharmony_ci * we do not care about the rest as they have to be the same. 1127bf215546Sopenharmony_ci */ 1128bf215546Sopenharmony_ci if (desc->channel[0].type == UTIL_FORMAT_TYPE_FLOAT) { 1129bf215546Sopenharmony_ci if (value->float32[0] != value->float32[1] || value->float32[0] != value->float32[2]) 1130bf215546Sopenharmony_ci return false; 1131bf215546Sopenharmony_ci } else { 1132bf215546Sopenharmony_ci if (value->uint32[0] != value->uint32[1] || value->uint32[0] != value->uint32[2]) 1133bf215546Sopenharmony_ci return false; 1134bf215546Sopenharmony_ci } 1135bf215546Sopenharmony_ci clear_vals[0] = value->uint32[0]; 1136bf215546Sopenharmony_ci clear_vals[1] = value->uint32[3]; 1137bf215546Sopenharmony_ci return true; 1138bf215546Sopenharmony_ci } 1139bf215546Sopenharmony_ci uint64_t clear_val = 0; 1140bf215546Sopenharmony_ci 1141bf215546Sopenharmony_ci for (unsigned c = 0; c < 4; ++c) { 1142bf215546Sopenharmony_ci if (desc->swizzle[c] >= 4) 1143bf215546Sopenharmony_ci continue; 1144bf215546Sopenharmony_ci 1145bf215546Sopenharmony_ci const struct util_format_channel_description *channel = &desc->channel[desc->swizzle[c]]; 1146bf215546Sopenharmony_ci assert(channel->size); 1147bf215546Sopenharmony_ci 1148bf215546Sopenharmony_ci uint64_t v = 0; 1149bf215546Sopenharmony_ci if (channel->pure_integer) { 1150bf215546Sopenharmony_ci v = value->uint32[c] & ((1ULL << channel->size) - 1); 1151bf215546Sopenharmony_ci } else if (channel->normalized) { 1152bf215546Sopenharmony_ci if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED && desc->swizzle[c] < 3 && 1153bf215546Sopenharmony_ci desc->colorspace == UTIL_FORMAT_COLORSPACE_SRGB) { 1154bf215546Sopenharmony_ci assert(channel->size == 8); 1155bf215546Sopenharmony_ci 1156bf215546Sopenharmony_ci v = util_format_linear_float_to_srgb_8unorm(value->float32[c]); 1157bf215546Sopenharmony_ci } else { 1158bf215546Sopenharmony_ci float f = MIN2(value->float32[c], 1.0f); 1159bf215546Sopenharmony_ci 1160bf215546Sopenharmony_ci if (channel->type == UTIL_FORMAT_TYPE_UNSIGNED) { 1161bf215546Sopenharmony_ci f = MAX2(f, 0.0f) * ((1ULL << channel->size) - 1); 1162bf215546Sopenharmony_ci } else { 1163bf215546Sopenharmony_ci f = MAX2(f, -1.0f) * ((1ULL << (channel->size - 1)) - 1); 1164bf215546Sopenharmony_ci } 1165bf215546Sopenharmony_ci 1166bf215546Sopenharmony_ci /* The hardware rounds before conversion. */ 1167bf215546Sopenharmony_ci if (f > 0) 1168bf215546Sopenharmony_ci f += 0.5f; 1169bf215546Sopenharmony_ci else 1170bf215546Sopenharmony_ci f -= 0.5f; 1171bf215546Sopenharmony_ci 1172bf215546Sopenharmony_ci v = (uint64_t)f; 1173bf215546Sopenharmony_ci } 1174bf215546Sopenharmony_ci } else if (channel->type == UTIL_FORMAT_TYPE_FLOAT) { 1175bf215546Sopenharmony_ci if (channel->size == 32) { 1176bf215546Sopenharmony_ci memcpy(&v, &value->float32[c], 4); 1177bf215546Sopenharmony_ci } else if (channel->size == 16) { 1178bf215546Sopenharmony_ci v = _mesa_float_to_float16_rtz(value->float32[c]); 1179bf215546Sopenharmony_ci } else { 1180bf215546Sopenharmony_ci fprintf(stderr, "failed to fast clear for unhandled float size in format %d\n", format); 1181bf215546Sopenharmony_ci return false; 1182bf215546Sopenharmony_ci } 1183bf215546Sopenharmony_ci } else { 1184bf215546Sopenharmony_ci fprintf(stderr, "failed to fast clear for unhandled component type in format %d\n", 1185bf215546Sopenharmony_ci format); 1186bf215546Sopenharmony_ci return false; 1187bf215546Sopenharmony_ci } 1188bf215546Sopenharmony_ci clear_val |= (v & ((1ULL << channel->size) - 1)) << channel->shift; 1189bf215546Sopenharmony_ci } 1190bf215546Sopenharmony_ci 1191bf215546Sopenharmony_ci clear_vals[0] = clear_val; 1192bf215546Sopenharmony_ci clear_vals[1] = clear_val >> 32; 1193bf215546Sopenharmony_ci 1194bf215546Sopenharmony_ci return true; 1195bf215546Sopenharmony_ci} 1196bf215546Sopenharmony_ci 1197bf215546Sopenharmony_cistatic const struct ac_modifier_options radv_modifier_options = { 1198bf215546Sopenharmony_ci .dcc = true, 1199bf215546Sopenharmony_ci .dcc_retile = true, 1200bf215546Sopenharmony_ci}; 1201bf215546Sopenharmony_ci 1202bf215546Sopenharmony_cistatic VkFormatFeatureFlags2 1203bf215546Sopenharmony_ciradv_get_modifier_flags(struct radv_physical_device *dev, VkFormat format, uint64_t modifier, 1204bf215546Sopenharmony_ci const VkFormatProperties3 *props) 1205bf215546Sopenharmony_ci{ 1206bf215546Sopenharmony_ci VkFormatFeatureFlags2 features; 1207bf215546Sopenharmony_ci 1208bf215546Sopenharmony_ci if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) 1209bf215546Sopenharmony_ci return 0; 1210bf215546Sopenharmony_ci 1211bf215546Sopenharmony_ci if (modifier == DRM_FORMAT_MOD_LINEAR) 1212bf215546Sopenharmony_ci features = props->linearTilingFeatures; 1213bf215546Sopenharmony_ci else 1214bf215546Sopenharmony_ci features = props->optimalTilingFeatures; 1215bf215546Sopenharmony_ci 1216bf215546Sopenharmony_ci /* Unconditionally disable DISJOINT support for modifiers for now */ 1217bf215546Sopenharmony_ci features &= ~VK_FORMAT_FEATURE_2_DISJOINT_BIT; 1218bf215546Sopenharmony_ci 1219bf215546Sopenharmony_ci if (ac_modifier_has_dcc(modifier)) { 1220bf215546Sopenharmony_ci /* Only disable support for STORAGE_IMAGE on modifiers that 1221bf215546Sopenharmony_ci * do not support DCC image stores. 1222bf215546Sopenharmony_ci */ 1223bf215546Sopenharmony_ci if (!ac_modifier_supports_dcc_image_stores(modifier) || radv_is_atomic_format_supported(format)) 1224bf215546Sopenharmony_ci features &= ~VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT; 1225bf215546Sopenharmony_ci 1226bf215546Sopenharmony_ci if (dev->instance->debug_flags & (RADV_DEBUG_NO_DCC | RADV_DEBUG_NO_DISPLAY_DCC)) 1227bf215546Sopenharmony_ci return 0; 1228bf215546Sopenharmony_ci } 1229bf215546Sopenharmony_ci 1230bf215546Sopenharmony_ci return features; 1231bf215546Sopenharmony_ci} 1232bf215546Sopenharmony_ci 1233bf215546Sopenharmony_cistatic VkFormatFeatureFlags 1234bf215546Sopenharmony_cifeatures2_to_features(VkFormatFeatureFlags2 features2) 1235bf215546Sopenharmony_ci{ 1236bf215546Sopenharmony_ci return features2 & VK_ALL_FORMAT_FEATURE_FLAG_BITS; 1237bf215546Sopenharmony_ci} 1238bf215546Sopenharmony_ci 1239bf215546Sopenharmony_cistatic void 1240bf215546Sopenharmony_ciradv_list_drm_format_modifiers(struct radv_physical_device *dev, VkFormat format, 1241bf215546Sopenharmony_ci const VkFormatProperties3 *format_props, 1242bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT *mod_list) 1243bf215546Sopenharmony_ci{ 1244bf215546Sopenharmony_ci unsigned mod_count; 1245bf215546Sopenharmony_ci 1246bf215546Sopenharmony_ci if (!mod_list) 1247bf215546Sopenharmony_ci return; 1248bf215546Sopenharmony_ci 1249bf215546Sopenharmony_ci if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) { 1250bf215546Sopenharmony_ci mod_list->drmFormatModifierCount = 0; 1251bf215546Sopenharmony_ci return; 1252bf215546Sopenharmony_ci } 1253bf215546Sopenharmony_ci 1254bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierPropertiesEXT, out, 1255bf215546Sopenharmony_ci mod_list->pDrmFormatModifierProperties, 1256bf215546Sopenharmony_ci &mod_list->drmFormatModifierCount); 1257bf215546Sopenharmony_ci 1258bf215546Sopenharmony_ci ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options, 1259bf215546Sopenharmony_ci vk_format_to_pipe_format(format), &mod_count, NULL); 1260bf215546Sopenharmony_ci 1261bf215546Sopenharmony_ci uint64_t *mods = malloc(mod_count * sizeof(uint64_t)); 1262bf215546Sopenharmony_ci if (!mods) { 1263bf215546Sopenharmony_ci /* We can't return an error here ... */ 1264bf215546Sopenharmony_ci mod_list->drmFormatModifierCount = 0; 1265bf215546Sopenharmony_ci return; 1266bf215546Sopenharmony_ci } 1267bf215546Sopenharmony_ci ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options, 1268bf215546Sopenharmony_ci vk_format_to_pipe_format(format), &mod_count, mods); 1269bf215546Sopenharmony_ci 1270bf215546Sopenharmony_ci for (unsigned i = 0; i < mod_count; ++i) { 1271bf215546Sopenharmony_ci VkFormatFeatureFlags2 features = 1272bf215546Sopenharmony_ci radv_get_modifier_flags(dev, format, mods[i], format_props); 1273bf215546Sopenharmony_ci unsigned planes = vk_format_get_plane_count(format); 1274bf215546Sopenharmony_ci if (planes == 1) { 1275bf215546Sopenharmony_ci if (ac_modifier_has_dcc_retile(mods[i])) 1276bf215546Sopenharmony_ci planes = 3; 1277bf215546Sopenharmony_ci else if (ac_modifier_has_dcc(mods[i])) 1278bf215546Sopenharmony_ci planes = 2; 1279bf215546Sopenharmony_ci } 1280bf215546Sopenharmony_ci 1281bf215546Sopenharmony_ci if (!features) 1282bf215546Sopenharmony_ci continue; 1283bf215546Sopenharmony_ci 1284bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierPropertiesEXT, &out, out_props) { 1285bf215546Sopenharmony_ci *out_props = (VkDrmFormatModifierPropertiesEXT) { 1286bf215546Sopenharmony_ci .drmFormatModifier = mods[i], 1287bf215546Sopenharmony_ci .drmFormatModifierPlaneCount = planes, 1288bf215546Sopenharmony_ci .drmFormatModifierTilingFeatures = features2_to_features(features), 1289bf215546Sopenharmony_ci }; 1290bf215546Sopenharmony_ci }; 1291bf215546Sopenharmony_ci } 1292bf215546Sopenharmony_ci 1293bf215546Sopenharmony_ci free(mods); 1294bf215546Sopenharmony_ci} 1295bf215546Sopenharmony_ci 1296bf215546Sopenharmony_cistatic void 1297bf215546Sopenharmony_ciradv_list_drm_format_modifiers_2(struct radv_physical_device *dev, VkFormat format, 1298bf215546Sopenharmony_ci const VkFormatProperties3 *format_props, 1299bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesList2EXT *mod_list) 1300bf215546Sopenharmony_ci{ 1301bf215546Sopenharmony_ci unsigned mod_count; 1302bf215546Sopenharmony_ci 1303bf215546Sopenharmony_ci if (!mod_list) 1304bf215546Sopenharmony_ci return; 1305bf215546Sopenharmony_ci 1306bf215546Sopenharmony_ci if (vk_format_is_compressed(format) || vk_format_is_depth_or_stencil(format)) { 1307bf215546Sopenharmony_ci mod_list->drmFormatModifierCount = 0; 1308bf215546Sopenharmony_ci return; 1309bf215546Sopenharmony_ci } 1310bf215546Sopenharmony_ci 1311bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkDrmFormatModifierProperties2EXT, out, 1312bf215546Sopenharmony_ci mod_list->pDrmFormatModifierProperties, 1313bf215546Sopenharmony_ci &mod_list->drmFormatModifierCount); 1314bf215546Sopenharmony_ci 1315bf215546Sopenharmony_ci ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options, 1316bf215546Sopenharmony_ci vk_format_to_pipe_format(format), &mod_count, NULL); 1317bf215546Sopenharmony_ci 1318bf215546Sopenharmony_ci uint64_t *mods = malloc(mod_count * sizeof(uint64_t)); 1319bf215546Sopenharmony_ci if (!mods) { 1320bf215546Sopenharmony_ci /* We can't return an error here ... */ 1321bf215546Sopenharmony_ci mod_list->drmFormatModifierCount = 0; 1322bf215546Sopenharmony_ci return; 1323bf215546Sopenharmony_ci } 1324bf215546Sopenharmony_ci ac_get_supported_modifiers(&dev->rad_info, &radv_modifier_options, 1325bf215546Sopenharmony_ci vk_format_to_pipe_format(format), &mod_count, mods); 1326bf215546Sopenharmony_ci 1327bf215546Sopenharmony_ci for (unsigned i = 0; i < mod_count; ++i) { 1328bf215546Sopenharmony_ci VkFormatFeatureFlags2 features = 1329bf215546Sopenharmony_ci radv_get_modifier_flags(dev, format, mods[i], format_props); 1330bf215546Sopenharmony_ci unsigned planes = vk_format_get_plane_count(format); 1331bf215546Sopenharmony_ci if (planes == 1) { 1332bf215546Sopenharmony_ci if (ac_modifier_has_dcc_retile(mods[i])) 1333bf215546Sopenharmony_ci planes = 3; 1334bf215546Sopenharmony_ci else if (ac_modifier_has_dcc(mods[i])) 1335bf215546Sopenharmony_ci planes = 2; 1336bf215546Sopenharmony_ci } 1337bf215546Sopenharmony_ci 1338bf215546Sopenharmony_ci if (!features) 1339bf215546Sopenharmony_ci continue; 1340bf215546Sopenharmony_ci 1341bf215546Sopenharmony_ci vk_outarray_append_typed(VkDrmFormatModifierProperties2EXT, &out, out_props) { 1342bf215546Sopenharmony_ci *out_props = (VkDrmFormatModifierProperties2EXT) { 1343bf215546Sopenharmony_ci .drmFormatModifier = mods[i], 1344bf215546Sopenharmony_ci .drmFormatModifierPlaneCount = planes, 1345bf215546Sopenharmony_ci .drmFormatModifierTilingFeatures = features, 1346bf215546Sopenharmony_ci }; 1347bf215546Sopenharmony_ci }; 1348bf215546Sopenharmony_ci } 1349bf215546Sopenharmony_ci 1350bf215546Sopenharmony_ci free(mods); 1351bf215546Sopenharmony_ci} 1352bf215546Sopenharmony_ci 1353bf215546Sopenharmony_cistatic VkResult 1354bf215546Sopenharmony_ciradv_check_modifier_support(struct radv_physical_device *dev, 1355bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, 1356bf215546Sopenharmony_ci VkImageFormatProperties *props, VkFormat format, uint64_t modifier) 1357bf215546Sopenharmony_ci{ 1358bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 1359bf215546Sopenharmony_ci uint32_t max_width, max_height; 1360bf215546Sopenharmony_ci 1361bf215546Sopenharmony_ci if (info->type != VK_IMAGE_TYPE_2D) 1362bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1363bf215546Sopenharmony_ci 1364bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && dev->emulate_etc2) 1365bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1366bf215546Sopenharmony_ci 1367bf215546Sopenharmony_ci /* We did not add modifiers for sparse textures. */ 1368bf215546Sopenharmony_ci if (info->flags & (VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | 1369bf215546Sopenharmony_ci VK_IMAGE_CREATE_SPARSE_ALIASED_BIT)) 1370bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1371bf215546Sopenharmony_ci 1372bf215546Sopenharmony_ci /* 1373bf215546Sopenharmony_ci * Need to check the modifier is supported in general: 1374bf215546Sopenharmony_ci * "If the drmFormatModifier is incompatible with the parameters specified 1375bf215546Sopenharmony_ci * in VkPhysicalDeviceImageFormatInfo2 and its pNext chain, then 1376bf215546Sopenharmony_ci * vkGetPhysicalDeviceImageFormatProperties2 returns VK_ERROR_FORMAT_NOT_SUPPORTED. 1377bf215546Sopenharmony_ci * The implementation must support the query of any drmFormatModifier, 1378bf215546Sopenharmony_ci * including unknown and invalid modifier values." 1379bf215546Sopenharmony_ci */ 1380bf215546Sopenharmony_ci VkDrmFormatModifierPropertiesListEXT mod_list = { 1381bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT, 1382bf215546Sopenharmony_ci }; 1383bf215546Sopenharmony_ci 1384bf215546Sopenharmony_ci VkFormatProperties2 format_props2 = {.sType = VK_STRUCTURE_TYPE_FORMAT_PROPERTIES_2, 1385bf215546Sopenharmony_ci .pNext = &mod_list}; 1386bf215546Sopenharmony_ci 1387bf215546Sopenharmony_ci radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format, 1388bf215546Sopenharmony_ci &format_props2); 1389bf215546Sopenharmony_ci 1390bf215546Sopenharmony_ci if (!mod_list.drmFormatModifierCount) 1391bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1392bf215546Sopenharmony_ci 1393bf215546Sopenharmony_ci mod_list.pDrmFormatModifierProperties = 1394bf215546Sopenharmony_ci calloc(mod_list.drmFormatModifierCount, sizeof(*mod_list.pDrmFormatModifierProperties)); 1395bf215546Sopenharmony_ci if (!mod_list.pDrmFormatModifierProperties) 1396bf215546Sopenharmony_ci return VK_ERROR_OUT_OF_HOST_MEMORY; 1397bf215546Sopenharmony_ci 1398bf215546Sopenharmony_ci radv_GetPhysicalDeviceFormatProperties2(radv_physical_device_to_handle(dev), format, 1399bf215546Sopenharmony_ci &format_props2); 1400bf215546Sopenharmony_ci 1401bf215546Sopenharmony_ci bool found = false; 1402bf215546Sopenharmony_ci for (uint32_t i = 0; i < mod_list.drmFormatModifierCount && !found; ++i) 1403bf215546Sopenharmony_ci if (mod_list.pDrmFormatModifierProperties[i].drmFormatModifier == modifier) 1404bf215546Sopenharmony_ci found = true; 1405bf215546Sopenharmony_ci 1406bf215546Sopenharmony_ci free(mod_list.pDrmFormatModifierProperties); 1407bf215546Sopenharmony_ci 1408bf215546Sopenharmony_ci if (!found) 1409bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1410bf215546Sopenharmony_ci 1411bf215546Sopenharmony_ci bool need_dcc_sign_reinterpret = false; 1412bf215546Sopenharmony_ci if (ac_modifier_has_dcc(modifier) && 1413bf215546Sopenharmony_ci !radv_are_formats_dcc_compatible(dev, info->pNext, format, info->flags, 1414bf215546Sopenharmony_ci &need_dcc_sign_reinterpret) && 1415bf215546Sopenharmony_ci !need_dcc_sign_reinterpret) 1416bf215546Sopenharmony_ci return VK_ERROR_FORMAT_NOT_SUPPORTED; 1417bf215546Sopenharmony_ci 1418bf215546Sopenharmony_ci /* We can expand this as needed and implemented but there is not much demand 1419bf215546Sopenharmony_ci * for more. */ 1420bf215546Sopenharmony_ci if (ac_modifier_has_dcc(modifier)) { 1421bf215546Sopenharmony_ci props->maxMipLevels = 1; 1422bf215546Sopenharmony_ci props->maxArrayLayers = 1; 1423bf215546Sopenharmony_ci } 1424bf215546Sopenharmony_ci 1425bf215546Sopenharmony_ci ac_modifier_max_extent(&dev->rad_info, modifier, &max_width, &max_height); 1426bf215546Sopenharmony_ci props->maxExtent.width = MIN2(props->maxExtent.width, max_width); 1427bf215546Sopenharmony_ci props->maxExtent.height = MIN2(props->maxExtent.width, max_height); 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci /* We don't support MSAA for modifiers */ 1430bf215546Sopenharmony_ci props->sampleCounts &= VK_SAMPLE_COUNT_1_BIT; 1431bf215546Sopenharmony_ci return VK_SUCCESS; 1432bf215546Sopenharmony_ci} 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1435bf215546Sopenharmony_ciradv_GetPhysicalDeviceFormatProperties2(VkPhysicalDevice physicalDevice, VkFormat format, 1436bf215546Sopenharmony_ci VkFormatProperties2 *pFormatProperties) 1437bf215546Sopenharmony_ci{ 1438bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1439bf215546Sopenharmony_ci VkFormatProperties3 format_props; 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_ci radv_physical_device_get_format_properties(physical_device, format, &format_props); 1442bf215546Sopenharmony_ci 1443bf215546Sopenharmony_ci pFormatProperties->formatProperties.linearTilingFeatures = 1444bf215546Sopenharmony_ci features2_to_features(format_props.linearTilingFeatures); 1445bf215546Sopenharmony_ci pFormatProperties->formatProperties.optimalTilingFeatures = 1446bf215546Sopenharmony_ci features2_to_features(format_props.optimalTilingFeatures); 1447bf215546Sopenharmony_ci pFormatProperties->formatProperties.bufferFeatures = 1448bf215546Sopenharmony_ci features2_to_features(format_props.bufferFeatures); 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci VkFormatProperties3 *format_props_extended = 1451bf215546Sopenharmony_ci vk_find_struct(pFormatProperties, FORMAT_PROPERTIES_3); 1452bf215546Sopenharmony_ci if (format_props_extended) { 1453bf215546Sopenharmony_ci format_props_extended->linearTilingFeatures = format_props.linearTilingFeatures; 1454bf215546Sopenharmony_ci format_props_extended->optimalTilingFeatures = format_props.optimalTilingFeatures; 1455bf215546Sopenharmony_ci format_props_extended->bufferFeatures = format_props.bufferFeatures; 1456bf215546Sopenharmony_ci } 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci radv_list_drm_format_modifiers( 1459bf215546Sopenharmony_ci physical_device, format, &format_props, 1460bf215546Sopenharmony_ci vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_EXT)); 1461bf215546Sopenharmony_ci radv_list_drm_format_modifiers_2( 1462bf215546Sopenharmony_ci physical_device, format, &format_props, 1463bf215546Sopenharmony_ci vk_find_struct(pFormatProperties, DRM_FORMAT_MODIFIER_PROPERTIES_LIST_2_EXT)); 1464bf215546Sopenharmony_ci} 1465bf215546Sopenharmony_ci 1466bf215546Sopenharmony_cistatic VkResult 1467bf215546Sopenharmony_ciradv_get_image_format_properties(struct radv_physical_device *physical_device, 1468bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *info, VkFormat format, 1469bf215546Sopenharmony_ci VkImageFormatProperties *pImageFormatProperties) 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_ci{ 1472bf215546Sopenharmony_ci VkFormatProperties3 format_props; 1473bf215546Sopenharmony_ci VkFormatFeatureFlags2 format_feature_flags; 1474bf215546Sopenharmony_ci VkExtent3D maxExtent; 1475bf215546Sopenharmony_ci uint32_t maxMipLevels; 1476bf215546Sopenharmony_ci uint32_t maxArraySize; 1477bf215546Sopenharmony_ci VkSampleCountFlags sampleCounts = VK_SAMPLE_COUNT_1_BIT; 1478bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(format); 1479bf215546Sopenharmony_ci enum amd_gfx_level gfx_level = physical_device->rad_info.gfx_level; 1480bf215546Sopenharmony_ci VkImageTiling tiling = info->tiling; 1481bf215546Sopenharmony_ci const VkPhysicalDeviceImageDrmFormatModifierInfoEXT *mod_info = 1482bf215546Sopenharmony_ci vk_find_struct_const(info->pNext, PHYSICAL_DEVICE_IMAGE_DRM_FORMAT_MODIFIER_INFO_EXT); 1483bf215546Sopenharmony_ci VkResult result = VK_ERROR_FORMAT_NOT_SUPPORTED; 1484bf215546Sopenharmony_ci 1485bf215546Sopenharmony_ci radv_physical_device_get_format_properties(physical_device, format, &format_props); 1486bf215546Sopenharmony_ci if (tiling == VK_IMAGE_TILING_LINEAR) { 1487bf215546Sopenharmony_ci format_feature_flags = format_props.linearTilingFeatures; 1488bf215546Sopenharmony_ci } else if (tiling == VK_IMAGE_TILING_OPTIMAL) { 1489bf215546Sopenharmony_ci format_feature_flags = format_props.optimalTilingFeatures; 1490bf215546Sopenharmony_ci } else if (tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1491bf215546Sopenharmony_ci format_feature_flags = radv_get_modifier_flags(physical_device, format, 1492bf215546Sopenharmony_ci mod_info->drmFormatModifier, &format_props); 1493bf215546Sopenharmony_ci } else { 1494bf215546Sopenharmony_ci unreachable("bad VkImageTiling"); 1495bf215546Sopenharmony_ci } 1496bf215546Sopenharmony_ci 1497bf215546Sopenharmony_ci if (format_feature_flags == 0) 1498bf215546Sopenharmony_ci goto unsupported; 1499bf215546Sopenharmony_ci 1500bf215546Sopenharmony_ci if (info->type != VK_IMAGE_TYPE_2D && vk_format_is_depth_or_stencil(format)) 1501bf215546Sopenharmony_ci goto unsupported; 1502bf215546Sopenharmony_ci 1503bf215546Sopenharmony_ci switch (info->type) { 1504bf215546Sopenharmony_ci default: 1505bf215546Sopenharmony_ci unreachable("bad vkimage type\n"); 1506bf215546Sopenharmony_ci case VK_IMAGE_TYPE_1D: 1507bf215546Sopenharmony_ci maxExtent.width = 16384; 1508bf215546Sopenharmony_ci maxExtent.height = 1; 1509bf215546Sopenharmony_ci maxExtent.depth = 1; 1510bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1511bf215546Sopenharmony_ci maxArraySize = gfx_level >= GFX10 ? 8192 : 2048; 1512bf215546Sopenharmony_ci break; 1513bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 1514bf215546Sopenharmony_ci maxExtent.width = 16384; 1515bf215546Sopenharmony_ci maxExtent.height = 16384; 1516bf215546Sopenharmony_ci maxExtent.depth = 1; 1517bf215546Sopenharmony_ci maxMipLevels = 15; /* log2(maxWidth) + 1 */ 1518bf215546Sopenharmony_ci maxArraySize = gfx_level >= GFX10 ? 8192 : 2048; 1519bf215546Sopenharmony_ci break; 1520bf215546Sopenharmony_ci case VK_IMAGE_TYPE_3D: 1521bf215546Sopenharmony_ci if (gfx_level >= GFX10) { 1522bf215546Sopenharmony_ci maxExtent.width = 8192; 1523bf215546Sopenharmony_ci maxExtent.height = 8192; 1524bf215546Sopenharmony_ci maxExtent.depth = 8192; 1525bf215546Sopenharmony_ci } else { 1526bf215546Sopenharmony_ci maxExtent.width = 2048; 1527bf215546Sopenharmony_ci maxExtent.height = 2048; 1528bf215546Sopenharmony_ci maxExtent.depth = 2048; 1529bf215546Sopenharmony_ci } 1530bf215546Sopenharmony_ci maxMipLevels = util_logbase2(maxExtent.width) + 1; 1531bf215546Sopenharmony_ci maxArraySize = 1; 1532bf215546Sopenharmony_ci break; 1533bf215546Sopenharmony_ci } 1534bf215546Sopenharmony_ci 1535bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_SUBSAMPLED) { 1536bf215546Sopenharmony_ci /* Might be able to support but the entire format support is 1537bf215546Sopenharmony_ci * messy, so taking the lazy way out. */ 1538bf215546Sopenharmony_ci maxArraySize = 1; 1539bf215546Sopenharmony_ci } 1540bf215546Sopenharmony_ci 1541bf215546Sopenharmony_ci if (tiling == VK_IMAGE_TILING_OPTIMAL && info->type == VK_IMAGE_TYPE_2D && 1542bf215546Sopenharmony_ci (format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | 1543bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) && 1544bf215546Sopenharmony_ci !(info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) && 1545bf215546Sopenharmony_ci !(info->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) { 1546bf215546Sopenharmony_ci sampleCounts |= VK_SAMPLE_COUNT_2_BIT | VK_SAMPLE_COUNT_4_BIT | VK_SAMPLE_COUNT_8_BIT; 1547bf215546Sopenharmony_ci } 1548bf215546Sopenharmony_ci 1549bf215546Sopenharmony_ci if (tiling == VK_IMAGE_TILING_LINEAR && 1550bf215546Sopenharmony_ci (format == VK_FORMAT_R32G32B32_SFLOAT || format == VK_FORMAT_R32G32B32_SINT || 1551bf215546Sopenharmony_ci format == VK_FORMAT_R32G32B32_UINT)) { 1552bf215546Sopenharmony_ci /* R32G32B32 is a weird format and the driver currently only 1553bf215546Sopenharmony_ci * supports the barely minimum. 1554bf215546Sopenharmony_ci * TODO: Implement more if we really need to. 1555bf215546Sopenharmony_ci */ 1556bf215546Sopenharmony_ci if (info->type == VK_IMAGE_TYPE_3D) 1557bf215546Sopenharmony_ci goto unsupported; 1558bf215546Sopenharmony_ci maxArraySize = 1; 1559bf215546Sopenharmony_ci maxMipLevels = 1; 1560bf215546Sopenharmony_ci } 1561bf215546Sopenharmony_ci 1562bf215546Sopenharmony_ci /* We can't create 3d compressed 128bpp images that can be rendered to on GFX9 */ 1563bf215546Sopenharmony_ci if (physical_device->rad_info.gfx_level >= GFX9 && info->type == VK_IMAGE_TYPE_3D && 1564bf215546Sopenharmony_ci vk_format_get_blocksizebits(format) == 128 && vk_format_is_compressed(format) && 1565bf215546Sopenharmony_ci (info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) && 1566bf215546Sopenharmony_ci ((info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) || 1567bf215546Sopenharmony_ci (info->usage & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT))) { 1568bf215546Sopenharmony_ci goto unsupported; 1569bf215546Sopenharmony_ci } 1570bf215546Sopenharmony_ci 1571bf215546Sopenharmony_ci /* From the Vulkan 1.3.206 spec: 1572bf215546Sopenharmony_ci * 1573bf215546Sopenharmony_ci * "VK_IMAGE_CREATE_EXTENDED_USAGE_BIT specifies that the image can be created with usage flags 1574bf215546Sopenharmony_ci * that are not supported for the format the image is created with but are supported for at least 1575bf215546Sopenharmony_ci * one format a VkImageView created from the image can have." 1576bf215546Sopenharmony_ci */ 1577bf215546Sopenharmony_ci VkImageUsageFlags image_usage = info->usage; 1578bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT) 1579bf215546Sopenharmony_ci image_usage = 0; 1580bf215546Sopenharmony_ci 1581bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_SAMPLED_BIT) { 1582bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_SAMPLED_IMAGE_BIT)) { 1583bf215546Sopenharmony_ci goto unsupported; 1584bf215546Sopenharmony_ci } 1585bf215546Sopenharmony_ci } 1586bf215546Sopenharmony_ci 1587bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1588bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_STORAGE_IMAGE_BIT)) { 1589bf215546Sopenharmony_ci goto unsupported; 1590bf215546Sopenharmony_ci } 1591bf215546Sopenharmony_ci } 1592bf215546Sopenharmony_ci 1593bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) { 1594bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT)) { 1595bf215546Sopenharmony_ci goto unsupported; 1596bf215546Sopenharmony_ci } 1597bf215546Sopenharmony_ci } 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 1600bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT)) { 1601bf215546Sopenharmony_ci goto unsupported; 1602bf215546Sopenharmony_ci } 1603bf215546Sopenharmony_ci } 1604bf215546Sopenharmony_ci 1605bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 1606bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT)) { 1607bf215546Sopenharmony_ci goto unsupported; 1608bf215546Sopenharmony_ci } 1609bf215546Sopenharmony_ci } 1610bf215546Sopenharmony_ci 1611bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) { 1612bf215546Sopenharmony_ci if (!(format_feature_flags & VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT)) { 1613bf215546Sopenharmony_ci goto unsupported; 1614bf215546Sopenharmony_ci } 1615bf215546Sopenharmony_ci } 1616bf215546Sopenharmony_ci 1617bf215546Sopenharmony_ci if (image_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 1618bf215546Sopenharmony_ci if (!(format_feature_flags & (VK_FORMAT_FEATURE_2_COLOR_ATTACHMENT_BIT | 1619bf215546Sopenharmony_ci VK_FORMAT_FEATURE_2_DEPTH_STENCIL_ATTACHMENT_BIT))) { 1620bf215546Sopenharmony_ci goto unsupported; 1621bf215546Sopenharmony_ci } 1622bf215546Sopenharmony_ci } 1623bf215546Sopenharmony_ci 1624bf215546Sopenharmony_ci /* Sparse resources with multi-planar formats are unsupported. */ 1625bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { 1626bf215546Sopenharmony_ci if (vk_format_get_plane_count(format) > 1) 1627bf215546Sopenharmony_ci goto unsupported; 1628bf215546Sopenharmony_ci } 1629bf215546Sopenharmony_ci 1630bf215546Sopenharmony_ci if (info->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) { 1631bf215546Sopenharmony_ci /* Sparse textures are only supported on GFX8+. */ 1632bf215546Sopenharmony_ci if (physical_device->rad_info.gfx_level < GFX8) 1633bf215546Sopenharmony_ci goto unsupported; 1634bf215546Sopenharmony_ci 1635bf215546Sopenharmony_ci if (vk_format_get_plane_count(format) > 1 || info->type != VK_IMAGE_TYPE_2D || 1636bf215546Sopenharmony_ci info->tiling != VK_IMAGE_TILING_OPTIMAL || vk_format_is_depth_or_stencil(format)) 1637bf215546Sopenharmony_ci goto unsupported; 1638bf215546Sopenharmony_ci } 1639bf215546Sopenharmony_ci 1640bf215546Sopenharmony_ci if ((info->flags & 1641bf215546Sopenharmony_ci (VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT | VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT)) && 1642bf215546Sopenharmony_ci (desc->layout == UTIL_FORMAT_LAYOUT_ETC && physical_device->emulate_etc2)) { 1643bf215546Sopenharmony_ci goto unsupported; 1644bf215546Sopenharmony_ci } 1645bf215546Sopenharmony_ci 1646bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties){ 1647bf215546Sopenharmony_ci .maxExtent = maxExtent, 1648bf215546Sopenharmony_ci .maxMipLevels = maxMipLevels, 1649bf215546Sopenharmony_ci .maxArrayLayers = maxArraySize, 1650bf215546Sopenharmony_ci .sampleCounts = sampleCounts, 1651bf215546Sopenharmony_ci 1652bf215546Sopenharmony_ci /* FINISHME: Accurately calculate 1653bf215546Sopenharmony_ci * VkImageFormatProperties::maxResourceSize. 1654bf215546Sopenharmony_ci */ 1655bf215546Sopenharmony_ci .maxResourceSize = UINT32_MAX, 1656bf215546Sopenharmony_ci }; 1657bf215546Sopenharmony_ci 1658bf215546Sopenharmony_ci if (mod_info) { 1659bf215546Sopenharmony_ci result = radv_check_modifier_support(physical_device, info, pImageFormatProperties, format, 1660bf215546Sopenharmony_ci mod_info->drmFormatModifier); 1661bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1662bf215546Sopenharmony_ci goto unsupported; 1663bf215546Sopenharmony_ci } 1664bf215546Sopenharmony_ci 1665bf215546Sopenharmony_ci return VK_SUCCESS; 1666bf215546Sopenharmony_ciunsupported: 1667bf215546Sopenharmony_ci *pImageFormatProperties = (VkImageFormatProperties){ 1668bf215546Sopenharmony_ci .maxExtent = {0, 0, 0}, 1669bf215546Sopenharmony_ci .maxMipLevels = 0, 1670bf215546Sopenharmony_ci .maxArrayLayers = 0, 1671bf215546Sopenharmony_ci .sampleCounts = 0, 1672bf215546Sopenharmony_ci .maxResourceSize = 0, 1673bf215546Sopenharmony_ci }; 1674bf215546Sopenharmony_ci 1675bf215546Sopenharmony_ci return result; 1676bf215546Sopenharmony_ci} 1677bf215546Sopenharmony_ci 1678bf215546Sopenharmony_cistatic void 1679bf215546Sopenharmony_ciget_external_image_format_properties(struct radv_physical_device *physical_device, 1680bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, 1681bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlagBits handleType, 1682bf215546Sopenharmony_ci VkExternalMemoryProperties *external_properties, 1683bf215546Sopenharmony_ci VkImageFormatProperties *format_properties) 1684bf215546Sopenharmony_ci{ 1685bf215546Sopenharmony_ci VkExternalMemoryFeatureFlagBits flags = 0; 1686bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags export_flags = 0; 1687bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags compat_flags = 0; 1688bf215546Sopenharmony_ci const struct util_format_description *desc = vk_format_description(pImageFormatInfo->format); 1689bf215546Sopenharmony_ci 1690bf215546Sopenharmony_ci if (desc->layout == UTIL_FORMAT_LAYOUT_ETC && physical_device->emulate_etc2) 1691bf215546Sopenharmony_ci return; 1692bf215546Sopenharmony_ci 1693bf215546Sopenharmony_ci if (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) 1694bf215546Sopenharmony_ci return; 1695bf215546Sopenharmony_ci 1696bf215546Sopenharmony_ci switch (handleType) { 1697bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 1698bf215546Sopenharmony_ci if (pImageFormatInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 1699bf215546Sopenharmony_ci break; 1700bf215546Sopenharmony_ci 1701bf215546Sopenharmony_ci switch (pImageFormatInfo->type) { 1702bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 1703bf215546Sopenharmony_ci flags = 1704bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 1705bf215546Sopenharmony_ci 1706bf215546Sopenharmony_ci compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 1707bf215546Sopenharmony_ci break; 1708bf215546Sopenharmony_ci default: 1709bf215546Sopenharmony_ci break; 1710bf215546Sopenharmony_ci } 1711bf215546Sopenharmony_ci break; 1712bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 1713bf215546Sopenharmony_ci switch (pImageFormatInfo->type) { 1714bf215546Sopenharmony_ci case VK_IMAGE_TYPE_2D: 1715bf215546Sopenharmony_ci flags = 1716bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 1717bf215546Sopenharmony_ci if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR) 1718bf215546Sopenharmony_ci flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT; 1719bf215546Sopenharmony_ci 1720bf215546Sopenharmony_ci compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT; 1721bf215546Sopenharmony_ci break; 1722bf215546Sopenharmony_ci default: 1723bf215546Sopenharmony_ci break; 1724bf215546Sopenharmony_ci } 1725bf215546Sopenharmony_ci break; 1726bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID: 1727bf215546Sopenharmony_ci if (!physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer) 1728bf215546Sopenharmony_ci break; 1729bf215546Sopenharmony_ci 1730bf215546Sopenharmony_ci if (!radv_android_gralloc_supports_format(pImageFormatInfo->format, pImageFormatInfo->usage)) 1731bf215546Sopenharmony_ci break; 1732bf215546Sopenharmony_ci 1733bf215546Sopenharmony_ci if (pImageFormatInfo->type != VK_IMAGE_TYPE_2D) 1734bf215546Sopenharmony_ci break; 1735bf215546Sopenharmony_ci 1736bf215546Sopenharmony_ci format_properties->maxMipLevels = MIN2(1, format_properties->maxMipLevels); 1737bf215546Sopenharmony_ci format_properties->maxArrayLayers = MIN2(1, format_properties->maxArrayLayers); 1738bf215546Sopenharmony_ci format_properties->sampleCounts &= VK_SAMPLE_COUNT_1_BIT; 1739bf215546Sopenharmony_ci 1740bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 1741bf215546Sopenharmony_ci if (pImageFormatInfo->tiling != VK_IMAGE_TILING_LINEAR) 1742bf215546Sopenharmony_ci flags |= VK_EXTERNAL_MEMORY_FEATURE_DEDICATED_ONLY_BIT; 1743bf215546Sopenharmony_ci 1744bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID; 1745bf215546Sopenharmony_ci break; 1746bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 1747bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 1748bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 1749bf215546Sopenharmony_ci break; 1750bf215546Sopenharmony_ci default: 1751bf215546Sopenharmony_ci break; 1752bf215546Sopenharmony_ci } 1753bf215546Sopenharmony_ci 1754bf215546Sopenharmony_ci *external_properties = (VkExternalMemoryProperties){ 1755bf215546Sopenharmony_ci .externalMemoryFeatures = flags, 1756bf215546Sopenharmony_ci .exportFromImportedHandleTypes = export_flags, 1757bf215546Sopenharmony_ci .compatibleHandleTypes = compat_flags, 1758bf215546Sopenharmony_ci }; 1759bf215546Sopenharmony_ci} 1760bf215546Sopenharmony_ci 1761bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 1762bf215546Sopenharmony_ciradv_GetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physicalDevice, 1763bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 *base_info, 1764bf215546Sopenharmony_ci VkImageFormatProperties2 *base_props) 1765bf215546Sopenharmony_ci{ 1766bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_physical_device, physical_device, physicalDevice); 1767bf215546Sopenharmony_ci const VkPhysicalDeviceExternalImageFormatInfo *external_info = NULL; 1768bf215546Sopenharmony_ci VkExternalImageFormatProperties *external_props = NULL; 1769bf215546Sopenharmony_ci struct VkAndroidHardwareBufferUsageANDROID *android_usage = NULL; 1770bf215546Sopenharmony_ci VkSamplerYcbcrConversionImageFormatProperties *ycbcr_props = NULL; 1771bf215546Sopenharmony_ci VkTextureLODGatherFormatPropertiesAMD *texture_lod_props = NULL; 1772bf215546Sopenharmony_ci VkResult result; 1773bf215546Sopenharmony_ci VkFormat format = radv_select_android_external_format(base_info->pNext, base_info->format); 1774bf215546Sopenharmony_ci 1775bf215546Sopenharmony_ci result = radv_get_image_format_properties(physical_device, base_info, format, 1776bf215546Sopenharmony_ci &base_props->imageFormatProperties); 1777bf215546Sopenharmony_ci if (result != VK_SUCCESS) 1778bf215546Sopenharmony_ci return result; 1779bf215546Sopenharmony_ci 1780bf215546Sopenharmony_ci /* Extract input structs */ 1781bf215546Sopenharmony_ci vk_foreach_struct_const(s, base_info->pNext) 1782bf215546Sopenharmony_ci { 1783bf215546Sopenharmony_ci switch (s->sType) { 1784bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_EXTERNAL_IMAGE_FORMAT_INFO: 1785bf215546Sopenharmony_ci external_info = (const void *)s; 1786bf215546Sopenharmony_ci break; 1787bf215546Sopenharmony_ci default: 1788bf215546Sopenharmony_ci break; 1789bf215546Sopenharmony_ci } 1790bf215546Sopenharmony_ci } 1791bf215546Sopenharmony_ci 1792bf215546Sopenharmony_ci /* Extract output structs */ 1793bf215546Sopenharmony_ci vk_foreach_struct(s, base_props->pNext) 1794bf215546Sopenharmony_ci { 1795bf215546Sopenharmony_ci switch (s->sType) { 1796bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_EXTERNAL_IMAGE_FORMAT_PROPERTIES: 1797bf215546Sopenharmony_ci external_props = (void *)s; 1798bf215546Sopenharmony_ci break; 1799bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_SAMPLER_YCBCR_CONVERSION_IMAGE_FORMAT_PROPERTIES: 1800bf215546Sopenharmony_ci ycbcr_props = (void *)s; 1801bf215546Sopenharmony_ci break; 1802bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_USAGE_ANDROID: 1803bf215546Sopenharmony_ci android_usage = (void *)s; 1804bf215546Sopenharmony_ci break; 1805bf215546Sopenharmony_ci case VK_STRUCTURE_TYPE_TEXTURE_LOD_GATHER_FORMAT_PROPERTIES_AMD: 1806bf215546Sopenharmony_ci texture_lod_props = (void *)s; 1807bf215546Sopenharmony_ci break; 1808bf215546Sopenharmony_ci default: 1809bf215546Sopenharmony_ci break; 1810bf215546Sopenharmony_ci } 1811bf215546Sopenharmony_ci } 1812bf215546Sopenharmony_ci 1813bf215546Sopenharmony_ci bool ahb_supported = 1814bf215546Sopenharmony_ci physical_device->vk.supported_extensions.ANDROID_external_memory_android_hardware_buffer; 1815bf215546Sopenharmony_ci if (android_usage && ahb_supported) { 1816bf215546Sopenharmony_ci#if RADV_SUPPORT_ANDROID_HARDWARE_BUFFER 1817bf215546Sopenharmony_ci android_usage->androidHardwareBufferUsage = 1818bf215546Sopenharmony_ci radv_ahb_usage_from_vk_usage(base_info->flags, base_info->usage); 1819bf215546Sopenharmony_ci#endif 1820bf215546Sopenharmony_ci } 1821bf215546Sopenharmony_ci 1822bf215546Sopenharmony_ci /* From the Vulkan 1.0.97 spec: 1823bf215546Sopenharmony_ci * 1824bf215546Sopenharmony_ci * If handleType is 0, vkGetPhysicalDeviceImageFormatProperties2 will 1825bf215546Sopenharmony_ci * behave as if VkPhysicalDeviceExternalImageFormatInfo was not 1826bf215546Sopenharmony_ci * present and VkExternalImageFormatProperties will be ignored. 1827bf215546Sopenharmony_ci */ 1828bf215546Sopenharmony_ci if (external_info && external_info->handleType != 0) { 1829bf215546Sopenharmony_ci VkExternalImageFormatProperties fallback_external_props; 1830bf215546Sopenharmony_ci 1831bf215546Sopenharmony_ci if (!external_props) { 1832bf215546Sopenharmony_ci memset(&fallback_external_props, 0, sizeof(fallback_external_props)); 1833bf215546Sopenharmony_ci external_props = &fallback_external_props; 1834bf215546Sopenharmony_ci } 1835bf215546Sopenharmony_ci 1836bf215546Sopenharmony_ci get_external_image_format_properties(physical_device, base_info, external_info->handleType, 1837bf215546Sopenharmony_ci &external_props->externalMemoryProperties, 1838bf215546Sopenharmony_ci &base_props->imageFormatProperties); 1839bf215546Sopenharmony_ci if (!external_props->externalMemoryProperties.externalMemoryFeatures) { 1840bf215546Sopenharmony_ci /* From the Vulkan 1.0.97 spec: 1841bf215546Sopenharmony_ci * 1842bf215546Sopenharmony_ci * If handleType is not compatible with the [parameters] specified 1843bf215546Sopenharmony_ci * in VkPhysicalDeviceImageFormatInfo2, then 1844bf215546Sopenharmony_ci * vkGetPhysicalDeviceImageFormatProperties2 returns 1845bf215546Sopenharmony_ci * VK_ERROR_FORMAT_NOT_SUPPORTED. 1846bf215546Sopenharmony_ci */ 1847bf215546Sopenharmony_ci result = vk_errorf(physical_device, VK_ERROR_FORMAT_NOT_SUPPORTED, 1848bf215546Sopenharmony_ci "unsupported VkExternalMemoryTypeFlagBitsKHR 0x%x", 1849bf215546Sopenharmony_ci external_info->handleType); 1850bf215546Sopenharmony_ci goto fail; 1851bf215546Sopenharmony_ci } 1852bf215546Sopenharmony_ci } 1853bf215546Sopenharmony_ci 1854bf215546Sopenharmony_ci if (ycbcr_props) { 1855bf215546Sopenharmony_ci ycbcr_props->combinedImageSamplerDescriptorCount = vk_format_get_plane_count(format); 1856bf215546Sopenharmony_ci } 1857bf215546Sopenharmony_ci 1858bf215546Sopenharmony_ci if (texture_lod_props) { 1859bf215546Sopenharmony_ci if (physical_device->rad_info.gfx_level >= GFX9) { 1860bf215546Sopenharmony_ci texture_lod_props->supportsTextureGatherLODBiasAMD = true; 1861bf215546Sopenharmony_ci } else { 1862bf215546Sopenharmony_ci texture_lod_props->supportsTextureGatherLODBiasAMD = !vk_format_is_int(format); 1863bf215546Sopenharmony_ci } 1864bf215546Sopenharmony_ci } 1865bf215546Sopenharmony_ci 1866bf215546Sopenharmony_ci return VK_SUCCESS; 1867bf215546Sopenharmony_ci 1868bf215546Sopenharmony_cifail: 1869bf215546Sopenharmony_ci if (result == VK_ERROR_FORMAT_NOT_SUPPORTED) { 1870bf215546Sopenharmony_ci /* From the Vulkan 1.0.97 spec: 1871bf215546Sopenharmony_ci * 1872bf215546Sopenharmony_ci * If the combination of parameters to 1873bf215546Sopenharmony_ci * vkGetPhysicalDeviceImageFormatProperties2 is not supported by 1874bf215546Sopenharmony_ci * the implementation for use in vkCreateImage, then all members of 1875bf215546Sopenharmony_ci * imageFormatProperties will be filled with zero. 1876bf215546Sopenharmony_ci */ 1877bf215546Sopenharmony_ci base_props->imageFormatProperties = (VkImageFormatProperties){0}; 1878bf215546Sopenharmony_ci } 1879bf215546Sopenharmony_ci 1880bf215546Sopenharmony_ci return result; 1881bf215546Sopenharmony_ci} 1882bf215546Sopenharmony_ci 1883bf215546Sopenharmony_cistatic void 1884bf215546Sopenharmony_cifill_sparse_image_format_properties(struct radv_physical_device *pdev, VkFormat format, 1885bf215546Sopenharmony_ci VkSparseImageFormatProperties *prop) 1886bf215546Sopenharmony_ci{ 1887bf215546Sopenharmony_ci prop->aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; 1888bf215546Sopenharmony_ci prop->flags = 0; 1889bf215546Sopenharmony_ci 1890bf215546Sopenharmony_ci /* On GFX8 we first subdivide by level and then layer, leading to a single 1891bf215546Sopenharmony_ci * miptail. On GFX9+ we first subdivide by layer and then level which results 1892bf215546Sopenharmony_ci * in a miptail per layer. */ 1893bf215546Sopenharmony_ci if (pdev->rad_info.gfx_level < GFX9) 1894bf215546Sopenharmony_ci prop->flags |= VK_SPARSE_IMAGE_FORMAT_SINGLE_MIPTAIL_BIT; 1895bf215546Sopenharmony_ci 1896bf215546Sopenharmony_ci /* This assumes the sparse image tile size is always 64 KiB (1 << 16) */ 1897bf215546Sopenharmony_ci unsigned l2_size = 16 - util_logbase2(vk_format_get_blocksize(format)); 1898bf215546Sopenharmony_ci unsigned w = (1u << ((l2_size + 1) / 2)) * vk_format_get_blockwidth(format); 1899bf215546Sopenharmony_ci unsigned h = (1u << (l2_size / 2)) * vk_format_get_blockheight(format); 1900bf215546Sopenharmony_ci 1901bf215546Sopenharmony_ci prop->imageGranularity = (VkExtent3D){w, h, 1}; 1902bf215546Sopenharmony_ci} 1903bf215546Sopenharmony_ci 1904bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1905bf215546Sopenharmony_ciradv_GetPhysicalDeviceSparseImageFormatProperties2( 1906bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSparseImageFormatInfo2 *pFormatInfo, 1907bf215546Sopenharmony_ci uint32_t *pPropertyCount, VkSparseImageFormatProperties2 *pProperties) 1908bf215546Sopenharmony_ci{ 1909bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_physical_device, pdev, physicalDevice); 1910bf215546Sopenharmony_ci VkResult result; 1911bf215546Sopenharmony_ci 1912bf215546Sopenharmony_ci if (pFormatInfo->samples > VK_SAMPLE_COUNT_1_BIT) { 1913bf215546Sopenharmony_ci *pPropertyCount = 0; 1914bf215546Sopenharmony_ci return; 1915bf215546Sopenharmony_ci } 1916bf215546Sopenharmony_ci 1917bf215546Sopenharmony_ci const VkPhysicalDeviceImageFormatInfo2 fmt_info = { 1918bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_FORMAT_INFO_2, 1919bf215546Sopenharmony_ci .format = pFormatInfo->format, 1920bf215546Sopenharmony_ci .type = pFormatInfo->type, 1921bf215546Sopenharmony_ci .tiling = pFormatInfo->tiling, 1922bf215546Sopenharmony_ci .usage = pFormatInfo->usage, 1923bf215546Sopenharmony_ci .flags = VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT}; 1924bf215546Sopenharmony_ci 1925bf215546Sopenharmony_ci VkImageFormatProperties fmt_props; 1926bf215546Sopenharmony_ci result = radv_get_image_format_properties(pdev, &fmt_info, pFormatInfo->format, &fmt_props); 1927bf215546Sopenharmony_ci if (result != VK_SUCCESS) { 1928bf215546Sopenharmony_ci *pPropertyCount = 0; 1929bf215546Sopenharmony_ci return; 1930bf215546Sopenharmony_ci } 1931bf215546Sopenharmony_ci 1932bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkSparseImageFormatProperties2, out, pProperties, pPropertyCount); 1933bf215546Sopenharmony_ci 1934bf215546Sopenharmony_ci vk_outarray_append_typed(VkSparseImageFormatProperties2, &out, prop) 1935bf215546Sopenharmony_ci { 1936bf215546Sopenharmony_ci fill_sparse_image_format_properties(pdev, pFormatInfo->format, &prop->properties); 1937bf215546Sopenharmony_ci }; 1938bf215546Sopenharmony_ci} 1939bf215546Sopenharmony_ci 1940bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1941bf215546Sopenharmony_ciradv_GetImageSparseMemoryRequirements2(VkDevice _device, 1942bf215546Sopenharmony_ci const VkImageSparseMemoryRequirementsInfo2 *pInfo, 1943bf215546Sopenharmony_ci uint32_t *pSparseMemoryRequirementCount, 1944bf215546Sopenharmony_ci VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 1945bf215546Sopenharmony_ci{ 1946bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 1947bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_image, image, pInfo->image); 1948bf215546Sopenharmony_ci 1949bf215546Sopenharmony_ci if (!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) { 1950bf215546Sopenharmony_ci *pSparseMemoryRequirementCount = 0; 1951bf215546Sopenharmony_ci return; 1952bf215546Sopenharmony_ci } 1953bf215546Sopenharmony_ci 1954bf215546Sopenharmony_ci VK_OUTARRAY_MAKE_TYPED(VkSparseImageMemoryRequirements2, out, pSparseMemoryRequirements, 1955bf215546Sopenharmony_ci pSparseMemoryRequirementCount); 1956bf215546Sopenharmony_ci 1957bf215546Sopenharmony_ci vk_outarray_append_typed(VkSparseImageMemoryRequirements2, &out, req) 1958bf215546Sopenharmony_ci { 1959bf215546Sopenharmony_ci fill_sparse_image_format_properties(device->physical_device, image->vk.format, 1960bf215546Sopenharmony_ci &req->memoryRequirements.formatProperties); 1961bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailFirstLod = image->planes[0].surface.first_mip_tail_level; 1962bf215546Sopenharmony_ci 1963bf215546Sopenharmony_ci if (req->memoryRequirements.imageMipTailFirstLod < image->info.levels) { 1964bf215546Sopenharmony_ci if (device->physical_device->rad_info.gfx_level >= GFX9) { 1965bf215546Sopenharmony_ci /* The tail is always a single tile per layer. */ 1966bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailSize = 65536; 1967bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailOffset = 1968bf215546Sopenharmony_ci image->planes[0] 1969bf215546Sopenharmony_ci .surface.u.gfx9.prt_level_offset[req->memoryRequirements.imageMipTailFirstLod] & 1970bf215546Sopenharmony_ci ~65535; 1971bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailStride = 1972bf215546Sopenharmony_ci image->planes[0].surface.u.gfx9.surf_slice_size; 1973bf215546Sopenharmony_ci } else { 1974bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailOffset = 1975bf215546Sopenharmony_ci (uint64_t)image->planes[0] 1976bf215546Sopenharmony_ci .surface.u.legacy.level[req->memoryRequirements.imageMipTailFirstLod] 1977bf215546Sopenharmony_ci .offset_256B * 256; 1978bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailSize = 1979bf215546Sopenharmony_ci image->size - req->memoryRequirements.imageMipTailOffset; 1980bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailStride = 0; 1981bf215546Sopenharmony_ci } 1982bf215546Sopenharmony_ci } else { 1983bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailSize = 0; 1984bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailOffset = 0; 1985bf215546Sopenharmony_ci req->memoryRequirements.imageMipTailStride = 0; 1986bf215546Sopenharmony_ci } 1987bf215546Sopenharmony_ci }; 1988bf215546Sopenharmony_ci} 1989bf215546Sopenharmony_ci 1990bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 1991bf215546Sopenharmony_ciradv_GetDeviceImageSparseMemoryRequirements(VkDevice device, 1992bf215546Sopenharmony_ci const VkDeviceImageMemoryRequirements* pInfo, 1993bf215546Sopenharmony_ci uint32_t *pSparseMemoryRequirementCount, 1994bf215546Sopenharmony_ci VkSparseImageMemoryRequirements2 *pSparseMemoryRequirements) 1995bf215546Sopenharmony_ci{ 1996bf215546Sopenharmony_ci UNUSED VkResult result; 1997bf215546Sopenharmony_ci VkImage image; 1998bf215546Sopenharmony_ci 1999bf215546Sopenharmony_ci /* Determining the image size/alignment require to create a surface, which is complicated without 2000bf215546Sopenharmony_ci * creating an image. 2001bf215546Sopenharmony_ci * TODO: Avoid creating an image. 2002bf215546Sopenharmony_ci */ 2003bf215546Sopenharmony_ci result = radv_CreateImage(device, pInfo->pCreateInfo, NULL, &image); 2004bf215546Sopenharmony_ci assert(result == VK_SUCCESS); 2005bf215546Sopenharmony_ci 2006bf215546Sopenharmony_ci VkImageSparseMemoryRequirementsInfo2 info2 = { 2007bf215546Sopenharmony_ci .sType = VK_STRUCTURE_TYPE_IMAGE_SPARSE_MEMORY_REQUIREMENTS_INFO_2, 2008bf215546Sopenharmony_ci .image = image, 2009bf215546Sopenharmony_ci }; 2010bf215546Sopenharmony_ci 2011bf215546Sopenharmony_ci radv_GetImageSparseMemoryRequirements2(device, &info2, pSparseMemoryRequirementCount, 2012bf215546Sopenharmony_ci pSparseMemoryRequirements); 2013bf215546Sopenharmony_ci 2014bf215546Sopenharmony_ci radv_DestroyImage(device, image, NULL); 2015bf215546Sopenharmony_ci} 2016bf215546Sopenharmony_ci 2017bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 2018bf215546Sopenharmony_ciradv_GetPhysicalDeviceExternalBufferProperties( 2019bf215546Sopenharmony_ci VkPhysicalDevice physicalDevice, const VkPhysicalDeviceExternalBufferInfo *pExternalBufferInfo, 2020bf215546Sopenharmony_ci VkExternalBufferProperties *pExternalBufferProperties) 2021bf215546Sopenharmony_ci{ 2022bf215546Sopenharmony_ci VkExternalMemoryFeatureFlagBits flags = 0; 2023bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags export_flags = 0; 2024bf215546Sopenharmony_ci VkExternalMemoryHandleTypeFlags compat_flags = 0; 2025bf215546Sopenharmony_ci switch (pExternalBufferInfo->handleType) { 2026bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT: 2027bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT: 2028bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_EXPORTABLE_BIT | VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 2029bf215546Sopenharmony_ci compat_flags = export_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT | 2030bf215546Sopenharmony_ci VK_EXTERNAL_MEMORY_HANDLE_TYPE_DMA_BUF_BIT_EXT; 2031bf215546Sopenharmony_ci break; 2032bf215546Sopenharmony_ci case VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT: 2033bf215546Sopenharmony_ci flags = VK_EXTERNAL_MEMORY_FEATURE_IMPORTABLE_BIT; 2034bf215546Sopenharmony_ci compat_flags = VK_EXTERNAL_MEMORY_HANDLE_TYPE_HOST_ALLOCATION_BIT_EXT; 2035bf215546Sopenharmony_ci break; 2036bf215546Sopenharmony_ci default: 2037bf215546Sopenharmony_ci break; 2038bf215546Sopenharmony_ci } 2039bf215546Sopenharmony_ci pExternalBufferProperties->externalMemoryProperties = (VkExternalMemoryProperties){ 2040bf215546Sopenharmony_ci .externalMemoryFeatures = flags, 2041bf215546Sopenharmony_ci .exportFromImportedHandleTypes = export_flags, 2042bf215546Sopenharmony_ci .compatibleHandleTypes = compat_flags, 2043bf215546Sopenharmony_ci }; 2044bf215546Sopenharmony_ci} 2045bf215546Sopenharmony_ci 2046bf215546Sopenharmony_ci/* DCC channel type categories within which formats can be reinterpreted 2047bf215546Sopenharmony_ci * while keeping the same DCC encoding. The swizzle must also match. */ 2048bf215546Sopenharmony_cienum dcc_channel_type { 2049bf215546Sopenharmony_ci dcc_channel_float, 2050bf215546Sopenharmony_ci dcc_channel_uint, 2051bf215546Sopenharmony_ci dcc_channel_sint, 2052bf215546Sopenharmony_ci dcc_channel_incompatible, 2053bf215546Sopenharmony_ci}; 2054bf215546Sopenharmony_ci 2055bf215546Sopenharmony_ci/* Return the type of DCC encoding. */ 2056bf215546Sopenharmony_cistatic void 2057bf215546Sopenharmony_ciradv_get_dcc_channel_type(const struct util_format_description *desc, enum dcc_channel_type *type, 2058bf215546Sopenharmony_ci unsigned *size) 2059bf215546Sopenharmony_ci{ 2060bf215546Sopenharmony_ci int i; 2061bf215546Sopenharmony_ci 2062bf215546Sopenharmony_ci /* Find the first non-void channel. */ 2063bf215546Sopenharmony_ci for (i = 0; i < desc->nr_channels; i++) 2064bf215546Sopenharmony_ci if (desc->channel[i].type != UTIL_FORMAT_TYPE_VOID) 2065bf215546Sopenharmony_ci break; 2066bf215546Sopenharmony_ci if (i == desc->nr_channels) { 2067bf215546Sopenharmony_ci *type = dcc_channel_incompatible; 2068bf215546Sopenharmony_ci return; 2069bf215546Sopenharmony_ci } 2070bf215546Sopenharmony_ci 2071bf215546Sopenharmony_ci switch (desc->channel[i].size) { 2072bf215546Sopenharmony_ci case 32: 2073bf215546Sopenharmony_ci case 16: 2074bf215546Sopenharmony_ci case 10: 2075bf215546Sopenharmony_ci case 8: 2076bf215546Sopenharmony_ci *size = desc->channel[i].size; 2077bf215546Sopenharmony_ci if (desc->channel[i].type == UTIL_FORMAT_TYPE_FLOAT) 2078bf215546Sopenharmony_ci *type = dcc_channel_float; 2079bf215546Sopenharmony_ci else if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) 2080bf215546Sopenharmony_ci *type = dcc_channel_uint; 2081bf215546Sopenharmony_ci else 2082bf215546Sopenharmony_ci *type = dcc_channel_sint; 2083bf215546Sopenharmony_ci break; 2084bf215546Sopenharmony_ci default: 2085bf215546Sopenharmony_ci *type = dcc_channel_incompatible; 2086bf215546Sopenharmony_ci break; 2087bf215546Sopenharmony_ci } 2088bf215546Sopenharmony_ci} 2089bf215546Sopenharmony_ci 2090bf215546Sopenharmony_ci/* Return if it's allowed to reinterpret one format as another with DCC enabled. */ 2091bf215546Sopenharmony_cibool 2092bf215546Sopenharmony_ciradv_dcc_formats_compatible(enum amd_gfx_level gfx_level, VkFormat format1, VkFormat format2, 2093bf215546Sopenharmony_ci bool *sign_reinterpret) 2094bf215546Sopenharmony_ci{ 2095bf215546Sopenharmony_ci const struct util_format_description *desc1, *desc2; 2096bf215546Sopenharmony_ci enum dcc_channel_type type1, type2; 2097bf215546Sopenharmony_ci unsigned size1, size2; 2098bf215546Sopenharmony_ci int i; 2099bf215546Sopenharmony_ci 2100bf215546Sopenharmony_ci /* All formats are compatible on GFX11. */ 2101bf215546Sopenharmony_ci if (gfx_level >= GFX11) 2102bf215546Sopenharmony_ci return true; 2103bf215546Sopenharmony_ci 2104bf215546Sopenharmony_ci if (format1 == format2) 2105bf215546Sopenharmony_ci return true; 2106bf215546Sopenharmony_ci 2107bf215546Sopenharmony_ci desc1 = vk_format_description(format1); 2108bf215546Sopenharmony_ci desc2 = vk_format_description(format2); 2109bf215546Sopenharmony_ci 2110bf215546Sopenharmony_ci if (desc1->nr_channels != desc2->nr_channels) 2111bf215546Sopenharmony_ci return false; 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci /* Swizzles must be the same. */ 2114bf215546Sopenharmony_ci for (i = 0; i < desc1->nr_channels; i++) 2115bf215546Sopenharmony_ci if (desc1->swizzle[i] <= PIPE_SWIZZLE_W && desc2->swizzle[i] <= PIPE_SWIZZLE_W && 2116bf215546Sopenharmony_ci desc1->swizzle[i] != desc2->swizzle[i]) 2117bf215546Sopenharmony_ci return false; 2118bf215546Sopenharmony_ci 2119bf215546Sopenharmony_ci radv_get_dcc_channel_type(desc1, &type1, &size1); 2120bf215546Sopenharmony_ci radv_get_dcc_channel_type(desc2, &type2, &size2); 2121bf215546Sopenharmony_ci 2122bf215546Sopenharmony_ci if (type1 == dcc_channel_incompatible || type2 == dcc_channel_incompatible || 2123bf215546Sopenharmony_ci (type1 == dcc_channel_float) != (type2 == dcc_channel_float) || size1 != size2) 2124bf215546Sopenharmony_ci return false; 2125bf215546Sopenharmony_ci 2126bf215546Sopenharmony_ci if (type1 != type2) 2127bf215546Sopenharmony_ci *sign_reinterpret = true; 2128bf215546Sopenharmony_ci 2129bf215546Sopenharmony_ci return true; 2130bf215546Sopenharmony_ci} 2131