1/* 2 * Copyright © 2016 Red Hat. 3 * Copyright © 2016 Bas Nieuwenhuizen 4 * 5 * based in part on anv driver which is: 6 * Copyright © 2015 Intel Corporation 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a 9 * copy of this software and associated documentation files (the "Software"), 10 * to deal in the Software without restriction, including without limitation 11 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12 * and/or sell copies of the Software, and to permit persons to whom the 13 * Software is furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice (including the next 16 * paragraph) shall be included in all copies or substantial portions of the 17 * Software. 18 * 19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25 * IN THE SOFTWARE. 26 */ 27 28#include "ac_drm_fourcc.h" 29#include "util/debug.h" 30#include "util/u_atomic.h" 31#include "vulkan/util/vk_format.h" 32#include "radv_debug.h" 33#include "radv_private.h" 34#include "radv_radeon_winsys.h" 35#include "sid.h" 36#include "vk_format.h" 37#include "vk_util.h" 38 39#include "gfx10_format_table.h" 40 41static unsigned 42radv_choose_tiling(struct radv_device *device, const VkImageCreateInfo *pCreateInfo, 43 VkFormat format) 44{ 45 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) { 46 assert(pCreateInfo->samples <= 1); 47 return RADEON_SURF_MODE_LINEAR_ALIGNED; 48 } 49 50 /* MSAA resources must be 2D tiled. */ 51 if (pCreateInfo->samples > 1) 52 return RADEON_SURF_MODE_2D; 53 54 if (!vk_format_is_compressed(format) && !vk_format_is_depth_or_stencil(format) && 55 device->physical_device->rad_info.gfx_level <= GFX8) { 56 /* this causes hangs in some VK CTS tests on GFX9. */ 57 /* Textures with a very small height are recommended to be linear. */ 58 if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D || 59 /* Only very thin and long 2D textures should benefit from 60 * linear_aligned. */ 61 (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2)) 62 return RADEON_SURF_MODE_LINEAR_ALIGNED; 63 } 64 65 return RADEON_SURF_MODE_2D; 66} 67 68static bool 69radv_use_tc_compat_htile_for_image(struct radv_device *device, const VkImageCreateInfo *pCreateInfo, 70 VkFormat format) 71{ 72 /* TC-compat HTILE is only available for GFX8+. */ 73 if (device->physical_device->rad_info.gfx_level < GFX8) 74 return false; 75 76 if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT)) 77 return false; 78 79 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) 80 return false; 81 82 /* Do not enable TC-compatible HTILE if the image isn't readable by a 83 * shader because no texture fetches will happen. 84 */ 85 if (!(pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | 86 VK_IMAGE_USAGE_TRANSFER_SRC_BIT))) 87 return false; 88 89 if (device->physical_device->rad_info.gfx_level < GFX9) { 90 /* TC-compat HTILE for MSAA depth/stencil images is broken 91 * on GFX8 because the tiling doesn't match. 92 */ 93 if (pCreateInfo->samples >= 2 && format == VK_FORMAT_D32_SFLOAT_S8_UINT) 94 return false; 95 96 /* GFX9+ supports compression for both 32-bit and 16-bit depth 97 * surfaces, while GFX8 only supports 32-bit natively. Though, 98 * the driver allows TC-compat HTILE for 16-bit depth surfaces 99 * with no Z planes compression. 100 */ 101 if (format != VK_FORMAT_D32_SFLOAT_S8_UINT && format != VK_FORMAT_D32_SFLOAT && 102 format != VK_FORMAT_D16_UNORM) 103 return false; 104 } 105 106 return true; 107} 108 109static bool 110radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info) 111{ 112 if (info->bo_metadata) { 113 if (device->physical_device->rad_info.gfx_level >= GFX9) 114 return info->bo_metadata->u.gfx9.scanout; 115 else 116 return info->bo_metadata->u.legacy.scanout; 117 } 118 119 return info->scanout; 120} 121 122static bool 123radv_image_use_fast_clear_for_image_early(const struct radv_device *device, 124 const struct radv_image *image) 125{ 126 if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) 127 return true; 128 129 if (image->info.samples <= 1 && image->info.width * image->info.height <= 512 * 512) { 130 /* Do not enable CMASK or DCC for small surfaces where the cost 131 * of the eliminate pass can be higher than the benefit of fast 132 * clear. RadeonSI does this, but the image threshold is 133 * different. 134 */ 135 return false; 136 } 137 138 return !!(image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); 139} 140 141static bool 142radv_image_use_fast_clear_for_image(const struct radv_device *device, 143 const struct radv_image *image) 144{ 145 if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) 146 return true; 147 148 return radv_image_use_fast_clear_for_image_early(device, image) && 149 (image->exclusive || 150 /* Enable DCC for concurrent images if stores are 151 * supported because that means we can keep DCC compressed on 152 * all layouts/queues. 153 */ 154 radv_image_use_dcc_image_stores(device, image)); 155} 156 157bool 158radv_are_formats_dcc_compatible(const struct radv_physical_device *pdev, const void *pNext, 159 VkFormat format, VkImageCreateFlags flags, bool *sign_reinterpret) 160{ 161 bool blendable; 162 163 if (!radv_is_colorbuffer_format_supported(pdev, format, &blendable)) 164 return false; 165 166 if (sign_reinterpret != NULL) 167 *sign_reinterpret = false; 168 169 if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 170 const struct VkImageFormatListCreateInfo *format_list = 171 (const struct VkImageFormatListCreateInfo *)vk_find_struct_const( 172 pNext, IMAGE_FORMAT_LIST_CREATE_INFO); 173 174 /* We have to ignore the existence of the list if viewFormatCount = 0 */ 175 if (format_list && format_list->viewFormatCount) { 176 /* compatibility is transitive, so we only need to check 177 * one format with everything else. */ 178 for (unsigned i = 0; i < format_list->viewFormatCount; ++i) { 179 if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED) 180 continue; 181 182 if (!radv_dcc_formats_compatible(pdev->rad_info.gfx_level, format, 183 format_list->pViewFormats[i], sign_reinterpret)) 184 return false; 185 } 186 } else { 187 return false; 188 } 189 } 190 191 return true; 192} 193 194static bool 195radv_format_is_atomic_allowed(struct radv_device *device, VkFormat format) 196{ 197 if (format == VK_FORMAT_R32_SFLOAT && !device->image_float32_atomics) 198 return false; 199 200 return radv_is_atomic_format_supported(format); 201} 202 203static bool 204radv_formats_is_atomic_allowed(struct radv_device *device, const void *pNext, VkFormat format, 205 VkImageCreateFlags flags) 206{ 207 if (radv_format_is_atomic_allowed(device, format)) 208 return true; 209 210 if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) { 211 const struct VkImageFormatListCreateInfo *format_list = 212 (const struct VkImageFormatListCreateInfo *)vk_find_struct_const( 213 pNext, IMAGE_FORMAT_LIST_CREATE_INFO); 214 215 /* We have to ignore the existence of the list if viewFormatCount = 0 */ 216 if (format_list && format_list->viewFormatCount) { 217 for (unsigned i = 0; i < format_list->viewFormatCount; ++i) { 218 if (radv_format_is_atomic_allowed(device, format_list->pViewFormats[i])) 219 return true; 220 } 221 } 222 } 223 224 return false; 225} 226 227static bool 228radv_use_dcc_for_image_early(struct radv_device *device, struct radv_image *image, 229 const VkImageCreateInfo *pCreateInfo, VkFormat format, 230 bool *sign_reinterpret) 231{ 232 /* DCC (Delta Color Compression) is only available for GFX8+. */ 233 if (device->physical_device->rad_info.gfx_level < GFX8) 234 return false; 235 236 if (device->instance->debug_flags & RADV_DEBUG_NO_DCC) 237 return false; 238 239 if (image->shareable && image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 240 return false; 241 242 /* 243 * TODO: Enable DCC for storage images on GFX9 and earlier. 244 * 245 * Also disable DCC with atomics because even when DCC stores are 246 * supported atomics will always decompress. So if we are 247 * decompressing a lot anyway we might as well not have DCC. 248 */ 249 if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) && 250 (device->physical_device->rad_info.gfx_level < GFX10 || 251 radv_formats_is_atomic_allowed(device, pCreateInfo->pNext, format, pCreateInfo->flags))) 252 return false; 253 254 /* Do not enable DCC for fragment shading rate attachments. */ 255 if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR) 256 return false; 257 258 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) 259 return false; 260 261 if (vk_format_is_subsampled(format) || vk_format_get_plane_count(format) > 1) 262 return false; 263 264 if (!radv_image_use_fast_clear_for_image_early(device, image) && 265 image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 266 return false; 267 268 /* Do not enable DCC for mipmapped arrays because performance is worse. */ 269 if (pCreateInfo->arrayLayers > 1 && pCreateInfo->mipLevels > 1) 270 return false; 271 272 if (device->physical_device->rad_info.gfx_level < GFX10) { 273 /* TODO: Add support for DCC MSAA on GFX8-9. */ 274 if (pCreateInfo->samples > 1 && !device->physical_device->dcc_msaa_allowed) 275 return false; 276 277 /* TODO: Add support for DCC layers/mipmaps on GFX9. */ 278 if ((pCreateInfo->arrayLayers > 1 || pCreateInfo->mipLevels > 1) && 279 device->physical_device->rad_info.gfx_level == GFX9) 280 return false; 281 } 282 283 return radv_are_formats_dcc_compatible(device->physical_device, pCreateInfo->pNext, format, 284 pCreateInfo->flags, sign_reinterpret); 285} 286 287static bool 288radv_use_dcc_for_image_late(struct radv_device *device, struct radv_image *image) 289{ 290 if (!radv_image_has_dcc(image)) 291 return false; 292 293 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 294 return true; 295 296 if (!radv_image_use_fast_clear_for_image(device, image)) 297 return false; 298 299 /* TODO: Fix storage images with DCC without DCC image stores. 300 * Disabling it for now. */ 301 if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) && 302 !radv_image_use_dcc_image_stores(device, image)) 303 return false; 304 305 return true; 306} 307 308/* 309 * Whether to enable image stores with DCC compression for this image. If 310 * this function returns false the image subresource should be decompressed 311 * before using it with image stores. 312 * 313 * Note that this can have mixed performance implications, see 314 * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6796#note_643299 315 * 316 * This function assumes the image uses DCC compression. 317 */ 318bool 319radv_image_use_dcc_image_stores(const struct radv_device *device, const struct radv_image *image) 320{ 321 return ac_surface_supports_dcc_image_stores(device->physical_device->rad_info.gfx_level, 322 &image->planes[0].surface); 323} 324 325/* 326 * Whether to use a predicate to determine whether DCC is in a compressed 327 * state. This can be used to avoid decompressing an image multiple times. 328 */ 329bool 330radv_image_use_dcc_predication(const struct radv_device *device, const struct radv_image *image) 331{ 332 return radv_image_has_dcc(image) && !radv_image_use_dcc_image_stores(device, image); 333} 334 335static inline bool 336radv_use_fmask_for_image(const struct radv_device *device, const struct radv_image *image) 337{ 338 return image->info.samples > 1 && ((image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) || 339 (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)); 340} 341 342static inline bool 343radv_use_htile_for_image(const struct radv_device *device, const struct radv_image *image) 344{ 345 /* TODO: 346 * - Investigate about mips+layers. 347 * - Enable on other gens. 348 */ 349 bool use_htile_for_mips = 350 image->info.array_size == 1 && device->physical_device->rad_info.gfx_level >= GFX10; 351 352 /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */ 353 if (device->physical_device->rad_info.gfx_level == GFX10 && 354 image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->info.levels > 1) 355 return false; 356 357 /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */ 358 if (device->physical_device->rad_info.chip_class == GFX10 && 359 image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->info.levels > 1) 360 return false; 361 362 /* Do not enable HTILE for very small images because it seems less performant but make sure it's 363 * allowed with VRS attachments because we need HTILE. 364 */ 365 if (image->info.width * image->info.height < 8 * 8 && 366 !(device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) && 367 !device->attachment_vrs_enabled) 368 return false; 369 370 return (image->info.levels == 1 || use_htile_for_mips) && !image->shareable; 371} 372 373static bool 374radv_use_tc_compat_cmask_for_image(struct radv_device *device, struct radv_image *image) 375{ 376 /* TC-compat CMASK is only available for GFX8+. */ 377 if (device->physical_device->rad_info.gfx_level < GFX8) 378 return false; 379 380 if (device->instance->debug_flags & RADV_DEBUG_NO_TC_COMPAT_CMASK) 381 return false; 382 383 /* TC-compat CMASK with storage images is supported on GFX10+. */ 384 if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) && 385 device->physical_device->rad_info.gfx_level < GFX10) 386 return false; 387 388 /* Do not enable TC-compatible if the image isn't readable by a shader 389 * because no texture fetches will happen. 390 */ 391 if (!(image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | 392 VK_IMAGE_USAGE_TRANSFER_SRC_BIT))) 393 return false; 394 395 /* If the image doesn't have FMASK, it can't be fetchable. */ 396 if (!radv_image_has_fmask(image)) 397 return false; 398 399 return true; 400} 401 402static uint32_t 403si_get_bo_metadata_word1(const struct radv_device *device) 404{ 405 return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id; 406} 407 408static bool 409radv_is_valid_opaque_metadata(const struct radv_device *device, const struct radeon_bo_metadata *md) 410{ 411 if (md->metadata[0] != 1 || md->metadata[1] != si_get_bo_metadata_word1(device)) 412 return false; 413 414 if (md->size_metadata < 40) 415 return false; 416 417 return true; 418} 419 420static void 421radv_patch_surface_from_metadata(struct radv_device *device, struct radeon_surf *surface, 422 const struct radeon_bo_metadata *md) 423{ 424 surface->flags = RADEON_SURF_CLR(surface->flags, MODE); 425 426 if (device->physical_device->rad_info.gfx_level >= GFX9) { 427 if (md->u.gfx9.swizzle_mode > 0) 428 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 429 else 430 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); 431 432 surface->u.gfx9.swizzle_mode = md->u.gfx9.swizzle_mode; 433 } else { 434 surface->u.legacy.pipe_config = md->u.legacy.pipe_config; 435 surface->u.legacy.bankw = md->u.legacy.bankw; 436 surface->u.legacy.bankh = md->u.legacy.bankh; 437 surface->u.legacy.tile_split = md->u.legacy.tile_split; 438 surface->u.legacy.mtilea = md->u.legacy.mtilea; 439 surface->u.legacy.num_banks = md->u.legacy.num_banks; 440 441 if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED) 442 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE); 443 else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED) 444 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE); 445 else 446 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE); 447 } 448} 449 450static VkResult 451radv_patch_image_dimensions(struct radv_device *device, struct radv_image *image, 452 const struct radv_image_create_info *create_info, 453 struct ac_surf_info *image_info) 454{ 455 unsigned width = image->info.width; 456 unsigned height = image->info.height; 457 458 /* 459 * minigbm sometimes allocates bigger images which is going to result in 460 * weird strides and other properties. Lets be lenient where possible and 461 * fail it on GFX10 (as we cannot cope there). 462 * 463 * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/ 464 */ 465 if (create_info->bo_metadata && 466 radv_is_valid_opaque_metadata(device, create_info->bo_metadata)) { 467 const struct radeon_bo_metadata *md = create_info->bo_metadata; 468 469 if (device->physical_device->rad_info.gfx_level >= GFX10) { 470 width = G_00A004_WIDTH_LO(md->metadata[3]) + (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1; 471 height = G_00A008_HEIGHT(md->metadata[4]) + 1; 472 } else { 473 width = G_008F18_WIDTH(md->metadata[4]) + 1; 474 height = G_008F18_HEIGHT(md->metadata[4]) + 1; 475 } 476 } 477 478 if (image->info.width == width && image->info.height == height) 479 return VK_SUCCESS; 480 481 if (width < image->info.width || height < image->info.height) { 482 fprintf(stderr, 483 "The imported image has smaller dimensions than the internal\n" 484 "dimensions. Using it is going to fail badly, so we reject\n" 485 "this import.\n" 486 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n", 487 image->info.width, image->info.height, width, height); 488 return VK_ERROR_INVALID_EXTERNAL_HANDLE; 489 } else if (device->physical_device->rad_info.gfx_level >= GFX10) { 490 fprintf(stderr, 491 "Tried to import an image with inconsistent width on GFX10.\n" 492 "As GFX10 has no separate stride fields we cannot cope with\n" 493 "an inconsistency in width and will fail this import.\n" 494 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n", 495 image->info.width, image->info.height, width, height); 496 return VK_ERROR_INVALID_EXTERNAL_HANDLE; 497 } else { 498 fprintf(stderr, 499 "Tried to import an image with inconsistent width on pre-GFX10.\n" 500 "As GFX10 has no separate stride fields we cannot cope with\n" 501 "an inconsistency and would fail on GFX10.\n" 502 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n", 503 image->info.width, image->info.height, width, height); 504 } 505 image_info->width = width; 506 image_info->height = height; 507 508 return VK_SUCCESS; 509} 510 511static VkResult 512radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image *image, 513 const struct radv_image_create_info *create_info, 514 struct ac_surf_info *image_info) 515{ 516 VkResult result = radv_patch_image_dimensions(device, image, create_info, image_info); 517 if (result != VK_SUCCESS) 518 return result; 519 520 for (unsigned plane = 0; plane < image->plane_count; ++plane) { 521 if (create_info->bo_metadata) { 522 radv_patch_surface_from_metadata(device, &image->planes[plane].surface, 523 create_info->bo_metadata); 524 } 525 526 if (radv_surface_has_scanout(device, create_info)) { 527 image->planes[plane].surface.flags |= RADEON_SURF_SCANOUT; 528 if (device->instance->debug_flags & RADV_DEBUG_NO_DISPLAY_DCC) 529 image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC; 530 531 image->info.surf_index = NULL; 532 } 533 534 if (create_info->prime_blit_src && device->physical_device->rad_info.gfx_level == GFX9) { 535 /* Older SDMA hw can't handle DCC */ 536 image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC; 537 } 538 } 539 return VK_SUCCESS; 540} 541 542static VkFormat 543etc2_emulation_format(VkFormat format) 544{ 545 switch (format) { 546 case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK: 547 case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK: 548 case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK: 549 return VK_FORMAT_R8G8B8A8_UNORM; 550 case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK: 551 case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK: 552 case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK: 553 return VK_FORMAT_R8G8B8A8_SRGB; 554 case VK_FORMAT_EAC_R11_UNORM_BLOCK: 555 return VK_FORMAT_R16_UNORM; 556 case VK_FORMAT_EAC_R11_SNORM_BLOCK: 557 return VK_FORMAT_R16_SNORM; 558 case VK_FORMAT_EAC_R11G11_UNORM_BLOCK: 559 return VK_FORMAT_R16G16_UNORM; 560 case VK_FORMAT_EAC_R11G11_SNORM_BLOCK: 561 return VK_FORMAT_R16G16_SNORM; 562 default: 563 unreachable("Unhandled ETC format"); 564 } 565} 566 567static VkFormat 568radv_image_get_plane_format(const struct radv_physical_device *pdev, const struct radv_image *image, 569 unsigned plane) 570{ 571 if (pdev->emulate_etc2 && 572 vk_format_description(image->vk.format)->layout == UTIL_FORMAT_LAYOUT_ETC) { 573 if (plane == 0) 574 return image->vk.format; 575 return etc2_emulation_format(image->vk.format); 576 } 577 return vk_format_get_plane_format(image->vk.format, plane); 578} 579 580static uint64_t 581radv_get_surface_flags(struct radv_device *device, struct radv_image *image, unsigned plane_id, 582 const VkImageCreateInfo *pCreateInfo, VkFormat image_format) 583{ 584 uint64_t flags; 585 unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format); 586 VkFormat format = radv_image_get_plane_format(device->physical_device, image, plane_id); 587 const struct util_format_description *desc = vk_format_description(format); 588 bool is_depth, is_stencil; 589 590 is_depth = util_format_has_depth(desc); 591 is_stencil = util_format_has_stencil(desc); 592 593 flags = RADEON_SURF_SET(array_mode, MODE); 594 595 switch (pCreateInfo->imageType) { 596 case VK_IMAGE_TYPE_1D: 597 if (pCreateInfo->arrayLayers > 1) 598 flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE); 599 else 600 flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE); 601 break; 602 case VK_IMAGE_TYPE_2D: 603 if (pCreateInfo->arrayLayers > 1) 604 flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE); 605 else 606 flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE); 607 break; 608 case VK_IMAGE_TYPE_3D: 609 flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE); 610 break; 611 default: 612 unreachable("unhandled image type"); 613 } 614 615 /* Required for clearing/initializing a specific layer on GFX8. */ 616 flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS; 617 618 if (is_depth) { 619 flags |= RADEON_SURF_ZBUFFER; 620 621 if (radv_use_htile_for_image(device, image) && 622 !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) { 623 if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format)) 624 flags |= RADEON_SURF_TC_COMPATIBLE_HTILE; 625 } else { 626 flags |= RADEON_SURF_NO_HTILE; 627 } 628 } 629 630 if (is_stencil) 631 flags |= RADEON_SURF_SBUFFER; 632 633 if (device->physical_device->rad_info.gfx_level >= GFX9 && 634 pCreateInfo->imageType == VK_IMAGE_TYPE_3D && 635 vk_format_get_blocksizebits(image_format) == 128 && vk_format_is_compressed(image_format)) 636 flags |= RADEON_SURF_NO_RENDER_TARGET; 637 638 if (!radv_use_dcc_for_image_early(device, image, pCreateInfo, image_format, 639 &image->dcc_sign_reinterpret)) 640 flags |= RADEON_SURF_DISABLE_DCC; 641 642 if (!radv_use_fmask_for_image(device, image)) 643 flags |= RADEON_SURF_NO_FMASK; 644 645 if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) { 646 flags |= 647 RADEON_SURF_PRT | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE | RADEON_SURF_DISABLE_DCC; 648 } 649 650 return flags; 651} 652 653static inline unsigned 654si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil) 655{ 656 if (stencil) 657 return plane->surface.u.legacy.zs.stencil_tiling_index[level]; 658 else 659 return plane->surface.u.legacy.tiling_index[level]; 660} 661 662static unsigned 663radv_map_swizzle(unsigned swizzle) 664{ 665 switch (swizzle) { 666 case PIPE_SWIZZLE_Y: 667 return V_008F0C_SQ_SEL_Y; 668 case PIPE_SWIZZLE_Z: 669 return V_008F0C_SQ_SEL_Z; 670 case PIPE_SWIZZLE_W: 671 return V_008F0C_SQ_SEL_W; 672 case PIPE_SWIZZLE_0: 673 return V_008F0C_SQ_SEL_0; 674 case PIPE_SWIZZLE_1: 675 return V_008F0C_SQ_SEL_1; 676 default: /* PIPE_SWIZZLE_X */ 677 return V_008F0C_SQ_SEL_X; 678 } 679} 680 681static void 682radv_compose_swizzle(const struct util_format_description *desc, const VkComponentMapping *mapping, 683 enum pipe_swizzle swizzle[4]) 684{ 685 if (desc->format == PIPE_FORMAT_R64_UINT || desc->format == PIPE_FORMAT_R64_SINT) { 686 /* 64-bit formats only support storage images and storage images 687 * require identity component mappings. We use 32-bit 688 * instructions to access 64-bit images, so we need a special 689 * case here. 690 * 691 * The zw components are 1,0 so that they can be easily be used 692 * by loads to create the w component, which has to be 0 for 693 * NULL descriptors. 694 */ 695 swizzle[0] = PIPE_SWIZZLE_X; 696 swizzle[1] = PIPE_SWIZZLE_Y; 697 swizzle[2] = PIPE_SWIZZLE_1; 698 swizzle[3] = PIPE_SWIZZLE_0; 699 } else if (!mapping) { 700 for (unsigned i = 0; i < 4; i++) 701 swizzle[i] = desc->swizzle[i]; 702 } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) { 703 const unsigned char swizzle_xxxx[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_0, PIPE_SWIZZLE_0, 704 PIPE_SWIZZLE_1}; 705 vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle); 706 } else { 707 vk_format_compose_swizzles(mapping, desc->swizzle, swizzle); 708 } 709} 710 711static void 712radv_make_buffer_descriptor(struct radv_device *device, struct radv_buffer *buffer, 713 VkFormat vk_format, unsigned offset, unsigned range, uint32_t *state) 714{ 715 const struct util_format_description *desc; 716 unsigned stride; 717 uint64_t gpu_address = radv_buffer_get_va(buffer->bo); 718 uint64_t va = gpu_address + buffer->offset; 719 unsigned num_format, data_format; 720 int first_non_void; 721 enum pipe_swizzle swizzle[4]; 722 desc = vk_format_description(vk_format); 723 first_non_void = vk_format_get_first_non_void_channel(vk_format); 724 stride = desc->block.bits / 8; 725 726 radv_compose_swizzle(desc, NULL, swizzle); 727 728 va += offset; 729 state[0] = va; 730 state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) | S_008F04_STRIDE(stride); 731 732 if (device->physical_device->rad_info.gfx_level != GFX8 && stride) { 733 range /= stride; 734 } 735 736 state[2] = range; 737 state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(swizzle[0])) | 738 S_008F0C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) | 739 S_008F0C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) | 740 S_008F0C_DST_SEL_W(radv_map_swizzle(swizzle[3])); 741 742 if (device->physical_device->rad_info.gfx_level >= GFX10) { 743 const struct gfx10_format *fmt = &ac_get_gfx10_format_table(&device->physical_device->rad_info)[vk_format_to_pipe_format(vk_format)]; 744 745 /* OOB_SELECT chooses the out-of-bounds check: 746 * - 0: (index >= NUM_RECORDS) || (offset >= STRIDE) 747 * - 1: index >= NUM_RECORDS 748 * - 2: NUM_RECORDS == 0 749 * - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS 750 * else: swizzle_address >= NUM_RECORDS 751 */ 752 state[3] |= S_008F0C_FORMAT(fmt->img_format) | 753 S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) | 754 S_008F0C_RESOURCE_LEVEL(device->physical_device->rad_info.gfx_level < GFX11); 755 } else { 756 num_format = radv_translate_buffer_numformat(desc, first_non_void); 757 data_format = radv_translate_buffer_dataformat(desc, first_non_void); 758 759 assert(data_format != V_008F0C_BUF_DATA_FORMAT_INVALID); 760 assert(num_format != ~0); 761 762 state[3] |= S_008F0C_NUM_FORMAT(num_format) | S_008F0C_DATA_FORMAT(data_format); 763 } 764} 765 766static void 767si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *image, 768 const struct legacy_surf_level *base_level_info, unsigned plane_id, 769 unsigned base_level, unsigned first_level, unsigned block_width, 770 bool is_stencil, bool is_storage_image, bool disable_compression, 771 bool enable_write_compression, uint32_t *state) 772{ 773 struct radv_image_plane *plane = &image->planes[plane_id]; 774 struct radv_image_binding *binding = image->disjoint ? &image->bindings[plane_id] : &image->bindings[0]; 775 uint64_t gpu_address = binding->bo ? radv_buffer_get_va(binding->bo) + binding->offset : 0; 776 uint64_t va = gpu_address; 777 enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level; 778 uint64_t meta_va = 0; 779 if (gfx_level >= GFX9) { 780 if (is_stencil) 781 va += plane->surface.u.gfx9.zs.stencil_offset; 782 else 783 va += plane->surface.u.gfx9.surf_offset; 784 } else 785 va += (uint64_t)base_level_info->offset_256B * 256; 786 787 state[0] = va >> 8; 788 if (gfx_level >= GFX9 || base_level_info->mode == RADEON_SURF_MODE_2D) 789 state[0] |= plane->surface.tile_swizzle; 790 state[1] &= C_008F14_BASE_ADDRESS_HI; 791 state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40); 792 793 if (gfx_level >= GFX8) { 794 state[6] &= C_008F28_COMPRESSION_EN; 795 state[7] = 0; 796 if (!disable_compression && radv_dcc_enabled(image, first_level)) { 797 meta_va = gpu_address + plane->surface.meta_offset; 798 if (gfx_level <= GFX8) 799 meta_va += plane->surface.u.legacy.color.dcc_level[base_level].dcc_offset; 800 801 unsigned dcc_tile_swizzle = plane->surface.tile_swizzle << 8; 802 dcc_tile_swizzle &= (1 << plane->surface.meta_alignment_log2) - 1; 803 meta_va |= dcc_tile_swizzle; 804 } else if (!disable_compression && radv_image_is_tc_compat_htile(image)) { 805 meta_va = gpu_address + plane->surface.meta_offset; 806 } 807 808 if (meta_va) { 809 state[6] |= S_008F28_COMPRESSION_EN(1); 810 if (gfx_level <= GFX9) 811 state[7] = meta_va >> 8; 812 } 813 } 814 815 if (gfx_level >= GFX10) { 816 state[3] &= C_00A00C_SW_MODE; 817 818 if (is_stencil) { 819 state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode); 820 } else { 821 state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.swizzle_mode); 822 } 823 824 state[6] &= C_00A018_META_DATA_ADDRESS_LO & C_00A018_META_PIPE_ALIGNED; 825 826 if (meta_va) { 827 struct gfx9_surf_meta_flags meta = { 828 .rb_aligned = 1, 829 .pipe_aligned = 1, 830 }; 831 832 if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER)) 833 meta = plane->surface.u.gfx9.color.dcc; 834 835 if (radv_dcc_enabled(image, first_level) && is_storage_image && enable_write_compression) 836 state[6] |= S_00A018_WRITE_COMPRESS_ENABLE(1); 837 838 state[6] |= S_00A018_META_PIPE_ALIGNED(meta.pipe_aligned) | 839 S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8); 840 } 841 842 state[7] = meta_va >> 16; 843 } else if (gfx_level == GFX9) { 844 state[3] &= C_008F1C_SW_MODE; 845 state[4] &= C_008F20_PITCH; 846 847 if (is_stencil) { 848 state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode); 849 state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.zs.stencil_epitch); 850 } else { 851 state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.swizzle_mode); 852 state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.epitch); 853 } 854 855 state[5] &= 856 C_008F24_META_DATA_ADDRESS & C_008F24_META_PIPE_ALIGNED & C_008F24_META_RB_ALIGNED; 857 if (meta_va) { 858 struct gfx9_surf_meta_flags meta = { 859 .rb_aligned = 1, 860 .pipe_aligned = 1, 861 }; 862 863 if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER)) 864 meta = plane->surface.u.gfx9.color.dcc; 865 866 state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) | 867 S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) | 868 S_008F24_META_RB_ALIGNED(meta.rb_aligned); 869 } 870 } else { 871 /* GFX6-GFX8 */ 872 unsigned pitch = base_level_info->nblk_x * block_width; 873 unsigned index = si_tile_mode_index(plane, base_level, is_stencil); 874 875 state[3] &= C_008F1C_TILING_INDEX; 876 state[3] |= S_008F1C_TILING_INDEX(index); 877 state[4] &= C_008F20_PITCH; 878 state[4] |= S_008F20_PITCH(pitch - 1); 879 } 880} 881 882static unsigned 883radv_tex_dim(VkImageType image_type, VkImageViewType view_type, unsigned nr_layers, 884 unsigned nr_samples, bool is_storage_image, bool gfx9) 885{ 886 if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) 887 return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE; 888 889 /* GFX9 allocates 1D textures as 2D. */ 890 if (gfx9 && image_type == VK_IMAGE_TYPE_1D) 891 image_type = VK_IMAGE_TYPE_2D; 892 switch (image_type) { 893 case VK_IMAGE_TYPE_1D: 894 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D; 895 case VK_IMAGE_TYPE_2D: 896 if (nr_samples > 1) 897 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY : V_008F1C_SQ_RSRC_IMG_2D_MSAA; 898 else 899 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_2D; 900 case VK_IMAGE_TYPE_3D: 901 if (view_type == VK_IMAGE_VIEW_TYPE_3D) 902 return V_008F1C_SQ_RSRC_IMG_3D; 903 else 904 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY; 905 default: 906 unreachable("illegal image type"); 907 } 908} 909 910static unsigned 911gfx9_border_color_swizzle(const struct util_format_description *desc) 912{ 913 unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW; 914 915 if (desc->swizzle[3] == PIPE_SWIZZLE_X) { 916 /* For the pre-defined border color values (white, opaque 917 * black, transparent black), the only thing that matters is 918 * that the alpha channel winds up in the correct place 919 * (because the RGB channels are all the same) so either of 920 * these enumerations will work. 921 */ 922 if (desc->swizzle[2] == PIPE_SWIZZLE_Y) 923 bc_swizzle = V_008F20_BC_SWIZZLE_WZYX; 924 else 925 bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ; 926 } else if (desc->swizzle[0] == PIPE_SWIZZLE_X) { 927 if (desc->swizzle[1] == PIPE_SWIZZLE_Y) 928 bc_swizzle = V_008F20_BC_SWIZZLE_XYZW; 929 else 930 bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ; 931 } else if (desc->swizzle[1] == PIPE_SWIZZLE_X) { 932 bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ; 933 } else if (desc->swizzle[2] == PIPE_SWIZZLE_X) { 934 bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW; 935 } 936 937 return bc_swizzle; 938} 939 940bool 941vi_alpha_is_on_msb(struct radv_device *device, VkFormat format) 942{ 943 const struct util_format_description *desc = vk_format_description(format); 944 945 if (device->physical_device->rad_info.gfx_level >= GFX10 && desc->nr_channels == 1) 946 return desc->swizzle[3] == PIPE_SWIZZLE_X; 947 948 return radv_translate_colorswap(format, false) <= 1; 949} 950/** 951 * Build the sampler view descriptor for a texture (GFX10). 952 */ 953static void 954gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *image, 955 bool is_storage_image, VkImageViewType view_type, VkFormat vk_format, 956 const VkComponentMapping *mapping, unsigned first_level, 957 unsigned last_level, unsigned first_layer, unsigned last_layer, 958 unsigned width, unsigned height, unsigned depth, float min_lod, 959 uint32_t *state, uint32_t *fmask_state, 960 VkImageCreateFlags img_create_flags) 961{ 962 const struct util_format_description *desc; 963 enum pipe_swizzle swizzle[4]; 964 unsigned img_format; 965 unsigned type; 966 967 desc = vk_format_description(vk_format); 968 969 /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so 970 * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format, 971 * this uses the Gallium formats to set the description. */ 972 if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK && 973 vk_format == VK_FORMAT_R8G8B8A8_UNORM) { 974 desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM); 975 } else if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK && 976 vk_format == VK_FORMAT_R8G8B8A8_SRGB) { 977 desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB); 978 } 979 980 img_format = ac_get_gfx10_format_table(&device->physical_device->rad_info)[vk_format_to_pipe_format(vk_format)].img_format; 981 982 radv_compose_swizzle(desc, mapping, swizzle); 983 984 if (img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) { 985 assert(image->vk.image_type == VK_IMAGE_TYPE_3D); 986 type = V_008F1C_SQ_RSRC_IMG_3D; 987 } else { 988 type = radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, image->info.samples, 989 is_storage_image, device->physical_device->rad_info.gfx_level == GFX9); 990 } 991 992 if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) { 993 height = 1; 994 depth = image->info.array_size; 995 } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) { 996 if (view_type != VK_IMAGE_VIEW_TYPE_3D) 997 depth = image->info.array_size; 998 } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE) 999 depth = image->info.array_size / 6; 1000 1001 state[0] = 0; 1002 state[1] = S_00A004_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) | 1003 S_00A004_FORMAT(img_format) | 1004 S_00A004_WIDTH_LO(width - 1); 1005 state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) | 1006 S_00A008_RESOURCE_LEVEL(device->physical_device->rad_info.gfx_level < GFX11); 1007 state[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle[0])) | 1008 S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) | 1009 S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) | 1010 S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle[3])) | 1011 S_00A00C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) | 1012 S_00A00C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples) 1013 : last_level) | 1014 S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(desc)) | S_00A00C_TYPE(type); 1015 /* Depth is the the last accessible layer on gfx9+. The hw doesn't need 1016 * to know the total number of layers. 1017 */ 1018 state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) | 1019 S_00A010_BASE_ARRAY(first_layer); 1020 state[5] = S_00A014_ARRAY_PITCH(0) | 1021 S_00A014_PERF_MOD(4); 1022 state[6] = 0; 1023 state[7] = 0; 1024 1025 if (img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) { 1026 assert(type == V_008F1C_SQ_RSRC_IMG_3D); 1027 1028 /* ARRAY_PITCH is only meaningful for 3D images, 0 means SRV, 1 means UAV. 1029 * In SRV mode, BASE_ARRAY is ignored and DEPTH is the last slice of mipmap level 0. 1030 * In UAV mode, BASE_ARRAY is the first slice and DEPTH is the last slice of the bound level. 1031 */ 1032 state[4] &= C_00A010_DEPTH; 1033 state[4] |= S_00A010_DEPTH(!is_storage_image ? depth - 1 : u_minify(depth, first_level) - 1); 1034 state[5] |= S_00A014_ARRAY_PITCH(is_storage_image); 1035 } 1036 1037 unsigned max_mip = 1038 image->info.samples > 1 ? util_logbase2(image->info.samples) : image->info.levels - 1; 1039 1040 if (device->physical_device->rad_info.gfx_level >= GFX11) { 1041 state[1] |= S_00A004_MAX_MIP(max_mip); 1042 } else { 1043 state[5] |= S_00A014_MAX_MIP(max_mip); 1044 } 1045 1046 if (radv_dcc_enabled(image, first_level)) { 1047 state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) | 1048 S_00A018_MAX_COMPRESSED_BLOCK_SIZE( 1049 image->planes[0].surface.u.gfx9.color.dcc.max_compressed_block_size) | 1050 S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format)); 1051 } 1052 1053 if (radv_image_get_iterate256(device, image)) { 1054 state[6] |= S_00A018_ITERATE_256(1); 1055 } 1056 1057 /* Initialize the sampler view for FMASK. */ 1058 if (fmask_state) { 1059 if (radv_image_has_fmask(image)) { 1060 uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo); 1061 uint32_t format; 1062 uint64_t va; 1063 1064 assert(image->plane_count == 1); 1065 1066 va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset; 1067 1068 switch (image->info.samples) { 1069 case 2: 1070 format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2; 1071 break; 1072 case 4: 1073 format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4; 1074 break; 1075 case 8: 1076 format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8; 1077 break; 1078 default: 1079 unreachable("invalid nr_samples"); 1080 } 1081 1082 fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle; 1083 fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) | S_00A004_FORMAT(format) | 1084 S_00A004_WIDTH_LO(width - 1); 1085 fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) | 1086 S_00A008_RESOURCE_LEVEL(1); 1087 fmask_state[3] = 1088 S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | 1089 S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) | 1090 S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode) | 1091 S_00A00C_TYPE( 1092 radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, 0, false, false)); 1093 fmask_state[4] = S_00A010_DEPTH(last_layer) | S_00A010_BASE_ARRAY(first_layer); 1094 fmask_state[5] = 0; 1095 fmask_state[6] = S_00A018_META_PIPE_ALIGNED(1); 1096 fmask_state[7] = 0; 1097 1098 if (radv_image_is_tc_compat_cmask(image)) { 1099 va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; 1100 1101 fmask_state[6] |= S_00A018_COMPRESSION_EN(1); 1102 fmask_state[6] |= S_00A018_META_DATA_ADDRESS_LO(va >> 8); 1103 fmask_state[7] |= va >> 16; 1104 } 1105 } else 1106 memset(fmask_state, 0, 8 * 4); 1107 } 1108} 1109 1110/** 1111 * Build the sampler view descriptor for a texture (SI-GFX9) 1112 */ 1113static void 1114si_make_texture_descriptor(struct radv_device *device, struct radv_image *image, 1115 bool is_storage_image, VkImageViewType view_type, VkFormat vk_format, 1116 const VkComponentMapping *mapping, unsigned first_level, 1117 unsigned last_level, unsigned first_layer, unsigned last_layer, 1118 unsigned width, unsigned height, unsigned depth, float min_lod, 1119 uint32_t *state, uint32_t *fmask_state, 1120 VkImageCreateFlags img_create_flags) 1121{ 1122 const struct util_format_description *desc; 1123 enum pipe_swizzle swizzle[4]; 1124 int first_non_void; 1125 unsigned num_format, data_format, type; 1126 1127 desc = vk_format_description(vk_format); 1128 1129 /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so 1130 * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format, 1131 * this uses the Gallium formats to set the description. */ 1132 if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK && 1133 vk_format == VK_FORMAT_R8G8B8A8_UNORM) { 1134 desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM); 1135 } else if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK && 1136 vk_format == VK_FORMAT_R8G8B8A8_SRGB) { 1137 desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB); 1138 } 1139 1140 radv_compose_swizzle(desc, mapping, swizzle); 1141 1142 first_non_void = vk_format_get_first_non_void_channel(vk_format); 1143 1144 num_format = radv_translate_tex_numformat(vk_format, desc, first_non_void); 1145 if (num_format == ~0) { 1146 num_format = 0; 1147 } 1148 1149 data_format = radv_translate_tex_dataformat(vk_format, desc, first_non_void); 1150 if (data_format == ~0) { 1151 data_format = 0; 1152 } 1153 1154 /* S8 with either Z16 or Z32 HTILE need a special format. */ 1155 if (device->physical_device->rad_info.gfx_level == GFX9 && vk_format == VK_FORMAT_S8_UINT && 1156 radv_image_is_tc_compat_htile(image)) { 1157 if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT) 1158 data_format = V_008F14_IMG_DATA_FORMAT_S8_32; 1159 else if (image->vk.format == VK_FORMAT_D16_UNORM_S8_UINT) 1160 data_format = V_008F14_IMG_DATA_FORMAT_S8_16; 1161 } 1162 1163 if (device->physical_device->rad_info.gfx_level == GFX9 && 1164 img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) { 1165 assert(image->vk.image_type == VK_IMAGE_TYPE_3D); 1166 type = V_008F1C_SQ_RSRC_IMG_3D; 1167 } else { 1168 type = radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, image->info.samples, 1169 is_storage_image, device->physical_device->rad_info.gfx_level == GFX9); 1170 } 1171 1172 if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) { 1173 height = 1; 1174 depth = image->info.array_size; 1175 } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) { 1176 if (view_type != VK_IMAGE_VIEW_TYPE_3D) 1177 depth = image->info.array_size; 1178 } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE) 1179 depth = image->info.array_size / 6; 1180 1181 state[0] = 0; 1182 state[1] = (S_008F14_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) | 1183 S_008F14_DATA_FORMAT(data_format) | 1184 S_008F14_NUM_FORMAT(num_format)); 1185 state[2] = (S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1) | S_008F18_PERF_MOD(4)); 1186 state[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle[0])) | 1187 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) | 1188 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) | 1189 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) | 1190 S_008F1C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) | 1191 S_008F1C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples) 1192 : last_level) | 1193 S_008F1C_TYPE(type)); 1194 state[4] = 0; 1195 state[5] = S_008F24_BASE_ARRAY(first_layer); 1196 state[6] = 0; 1197 state[7] = 0; 1198 1199 if (device->physical_device->rad_info.gfx_level == GFX9) { 1200 unsigned bc_swizzle = gfx9_border_color_swizzle(desc); 1201 1202 /* Depth is the last accessible layer on Gfx9. 1203 * The hw doesn't need to know the total number of layers. 1204 */ 1205 if (type == V_008F1C_SQ_RSRC_IMG_3D) 1206 state[4] |= S_008F20_DEPTH(depth - 1); 1207 else 1208 state[4] |= S_008F20_DEPTH(last_layer); 1209 1210 state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle); 1211 state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples) 1212 : image->info.levels - 1); 1213 } else { 1214 state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1); 1215 state[4] |= S_008F20_DEPTH(depth - 1); 1216 state[5] |= S_008F24_LAST_ARRAY(last_layer); 1217 } 1218 if (!(image->planes[0].surface.flags & RADEON_SURF_Z_OR_SBUFFER) && 1219 image->planes[0].surface.meta_offset) { 1220 state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format)); 1221 } else { 1222 if (device->instance->disable_aniso_single_level) { 1223 /* The last dword is unused by hw. The shader uses it to clear 1224 * bits in the first dword of sampler state. 1225 */ 1226 if (device->physical_device->rad_info.gfx_level <= GFX7 && image->info.samples <= 1) { 1227 if (first_level == last_level) 1228 state[7] = C_008F30_MAX_ANISO_RATIO; 1229 else 1230 state[7] = 0xffffffff; 1231 } 1232 } 1233 } 1234 1235 /* Initialize the sampler view for FMASK. */ 1236 if (fmask_state) { 1237 if (radv_image_has_fmask(image)) { 1238 uint32_t fmask_format; 1239 uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo); 1240 uint64_t va; 1241 1242 assert(image->plane_count == 1); 1243 1244 va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset; 1245 1246 if (device->physical_device->rad_info.gfx_level == GFX9) { 1247 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK; 1248 switch (image->info.samples) { 1249 case 2: 1250 num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2; 1251 break; 1252 case 4: 1253 num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4; 1254 break; 1255 case 8: 1256 num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8; 1257 break; 1258 default: 1259 unreachable("invalid nr_samples"); 1260 } 1261 } else { 1262 switch (image->info.samples) { 1263 case 2: 1264 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2; 1265 break; 1266 case 4: 1267 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4; 1268 break; 1269 case 8: 1270 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8; 1271 break; 1272 default: 1273 assert(0); 1274 fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID; 1275 } 1276 num_format = V_008F14_IMG_NUM_FORMAT_UINT; 1277 } 1278 1279 fmask_state[0] = va >> 8; 1280 fmask_state[0] |= image->planes[0].surface.fmask_tile_swizzle; 1281 fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT(fmask_format) | 1282 S_008F14_NUM_FORMAT(num_format); 1283 fmask_state[2] = S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1); 1284 fmask_state[3] = 1285 S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) | 1286 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) | 1287 S_008F1C_TYPE( 1288 radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, 0, false, false)); 1289 fmask_state[4] = 0; 1290 fmask_state[5] = S_008F24_BASE_ARRAY(first_layer); 1291 fmask_state[6] = 0; 1292 fmask_state[7] = 0; 1293 1294 if (device->physical_device->rad_info.gfx_level == GFX9) { 1295 fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode); 1296 fmask_state[4] |= S_008F20_DEPTH(last_layer) | 1297 S_008F20_PITCH(image->planes[0].surface.u.gfx9.color.fmask_epitch); 1298 fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(1) | S_008F24_META_RB_ALIGNED(1); 1299 1300 if (radv_image_is_tc_compat_cmask(image)) { 1301 va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; 1302 1303 fmask_state[5] |= S_008F24_META_DATA_ADDRESS(va >> 40); 1304 fmask_state[6] |= S_008F28_COMPRESSION_EN(1); 1305 fmask_state[7] |= va >> 8; 1306 } 1307 } else { 1308 fmask_state[3] |= 1309 S_008F1C_TILING_INDEX(image->planes[0].surface.u.legacy.color.fmask.tiling_index); 1310 fmask_state[4] |= 1311 S_008F20_DEPTH(depth - 1) | 1312 S_008F20_PITCH(image->planes[0].surface.u.legacy.color.fmask.pitch_in_pixels - 1); 1313 fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer); 1314 1315 if (radv_image_is_tc_compat_cmask(image)) { 1316 va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset; 1317 1318 fmask_state[6] |= S_008F28_COMPRESSION_EN(1); 1319 fmask_state[7] |= va >> 8; 1320 } 1321 } 1322 } else 1323 memset(fmask_state, 0, 8 * 4); 1324 } 1325} 1326 1327static void 1328radv_make_texture_descriptor(struct radv_device *device, struct radv_image *image, 1329 bool is_storage_image, VkImageViewType view_type, VkFormat vk_format, 1330 const VkComponentMapping *mapping, unsigned first_level, 1331 unsigned last_level, unsigned first_layer, unsigned last_layer, 1332 unsigned width, unsigned height, unsigned depth, float min_lod, uint32_t *state, 1333 uint32_t *fmask_state, VkImageCreateFlags img_create_flags) 1334{ 1335 if (device->physical_device->rad_info.gfx_level >= GFX10) { 1336 gfx10_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping, 1337 first_level, last_level, first_layer, last_layer, width, height, 1338 depth, min_lod, state, fmask_state, img_create_flags); 1339 } else { 1340 si_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping, 1341 first_level, last_level, first_layer, last_layer, width, height, 1342 depth, min_lod, state, fmask_state, img_create_flags); 1343 } 1344} 1345 1346static void 1347radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image, 1348 struct radeon_bo_metadata *md) 1349{ 1350 static const VkComponentMapping fixedmapping; 1351 uint32_t desc[8]; 1352 1353 assert(image->plane_count == 1); 1354 1355 radv_make_texture_descriptor(device, image, false, (VkImageViewType)image->vk.image_type, 1356 image->vk.format, &fixedmapping, 0, image->info.levels - 1, 0, 1357 image->info.array_size - 1, image->info.width, image->info.height, 1358 image->info.depth, 0.0f, desc, NULL, 0); 1359 1360 si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0, 1361 0, image->planes[0].surface.blk_w, false, false, false, false, 1362 desc); 1363 1364 ac_surface_get_umd_metadata(&device->physical_device->rad_info, &image->planes[0].surface, 1365 image->info.levels, desc, &md->size_metadata, md->metadata); 1366} 1367 1368void 1369radv_init_metadata(struct radv_device *device, struct radv_image *image, 1370 struct radeon_bo_metadata *metadata) 1371{ 1372 struct radeon_surf *surface = &image->planes[0].surface; 1373 1374 memset(metadata, 0, sizeof(*metadata)); 1375 1376 if (device->physical_device->rad_info.gfx_level >= GFX9) { 1377 uint64_t dcc_offset = 1378 image->bindings[0].offset + 1379 (surface->display_dcc_offset ? surface->display_dcc_offset : surface->meta_offset); 1380 metadata->u.gfx9.swizzle_mode = surface->u.gfx9.swizzle_mode; 1381 metadata->u.gfx9.dcc_offset_256b = dcc_offset >> 8; 1382 metadata->u.gfx9.dcc_pitch_max = surface->u.gfx9.color.display_dcc_pitch_max; 1383 metadata->u.gfx9.dcc_independent_64b_blocks = surface->u.gfx9.color.dcc.independent_64B_blocks; 1384 metadata->u.gfx9.dcc_independent_128b_blocks = surface->u.gfx9.color.dcc.independent_128B_blocks; 1385 metadata->u.gfx9.dcc_max_compressed_block_size = 1386 surface->u.gfx9.color.dcc.max_compressed_block_size; 1387 metadata->u.gfx9.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0; 1388 } else { 1389 metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D 1390 ? RADEON_LAYOUT_TILED 1391 : RADEON_LAYOUT_LINEAR; 1392 metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D 1393 ? RADEON_LAYOUT_TILED 1394 : RADEON_LAYOUT_LINEAR; 1395 metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config; 1396 metadata->u.legacy.bankw = surface->u.legacy.bankw; 1397 metadata->u.legacy.bankh = surface->u.legacy.bankh; 1398 metadata->u.legacy.tile_split = surface->u.legacy.tile_split; 1399 metadata->u.legacy.mtilea = surface->u.legacy.mtilea; 1400 metadata->u.legacy.num_banks = surface->u.legacy.num_banks; 1401 metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe; 1402 metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0; 1403 } 1404 radv_query_opaque_metadata(device, image, metadata); 1405} 1406 1407void 1408radv_image_override_offset_stride(struct radv_device *device, struct radv_image *image, 1409 uint64_t offset, uint32_t stride) 1410{ 1411 ac_surface_override_offset_stride(&device->physical_device->rad_info, &image->planes[0].surface, 1412 image->info.levels, offset, stride); 1413} 1414 1415static void 1416radv_image_alloc_single_sample_cmask(const struct radv_device *device, 1417 const struct radv_image *image, struct radeon_surf *surf) 1418{ 1419 if (!surf->cmask_size || surf->cmask_offset || surf->bpe > 8 || image->info.levels > 1 || 1420 image->info.depth > 1 || radv_image_has_dcc(image) || 1421 !radv_image_use_fast_clear_for_image(device, image) || 1422 (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)) 1423 return; 1424 1425 assert(image->info.storage_samples == 1); 1426 1427 surf->cmask_offset = align64(surf->total_size, 1 << surf->cmask_alignment_log2); 1428 surf->total_size = surf->cmask_offset + surf->cmask_size; 1429 surf->alignment_log2 = MAX2(surf->alignment_log2, surf->cmask_alignment_log2); 1430} 1431 1432static void 1433radv_image_alloc_values(const struct radv_device *device, struct radv_image *image) 1434{ 1435 /* images with modifiers can be potentially imported */ 1436 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 1437 return; 1438 1439 if (radv_image_has_cmask(image) || (radv_image_has_dcc(image) && !image->support_comp_to_single)) { 1440 image->fce_pred_offset = image->size; 1441 image->size += 8 * image->info.levels; 1442 } 1443 1444 if (radv_image_use_dcc_predication(device, image)) { 1445 image->dcc_pred_offset = image->size; 1446 image->size += 8 * image->info.levels; 1447 } 1448 1449 if ((radv_image_has_dcc(image) && !image->support_comp_to_single) || 1450 radv_image_has_cmask(image) || radv_image_has_htile(image)) { 1451 image->clear_value_offset = image->size; 1452 image->size += 8 * image->info.levels; 1453 } 1454 1455 if (radv_image_is_tc_compat_htile(image) && 1456 device->physical_device->rad_info.has_tc_compat_zrange_bug) { 1457 /* Metadata for the TC-compatible HTILE hardware bug which 1458 * have to be fixed by updating ZRANGE_PRECISION when doing 1459 * fast depth clears to 0.0f. 1460 */ 1461 image->tc_compat_zrange_offset = image->size; 1462 image->size += image->info.levels * 4; 1463 } 1464} 1465 1466/* Determine if the image is affected by the pipe misaligned metadata issue 1467 * which requires to invalidate L2. 1468 */ 1469static bool 1470radv_image_is_pipe_misaligned(const struct radv_device *device, const struct radv_image *image) 1471{ 1472 struct radeon_info *rad_info = &device->physical_device->rad_info; 1473 int log2_samples = util_logbase2(image->info.samples); 1474 1475 assert(rad_info->gfx_level >= GFX10); 1476 1477 for (unsigned i = 0; i < image->plane_count; ++i) { 1478 VkFormat fmt = radv_image_get_plane_format(device->physical_device, image, i); 1479 int log2_bpp = util_logbase2(vk_format_get_blocksize(fmt)); 1480 int log2_bpp_and_samples; 1481 1482 if (rad_info->gfx_level >= GFX10_3) { 1483 log2_bpp_and_samples = log2_bpp + log2_samples; 1484 } else { 1485 if (vk_format_has_depth(image->vk.format) && image->info.array_size >= 8) { 1486 log2_bpp = 2; 1487 } 1488 1489 log2_bpp_and_samples = MIN2(6, log2_bpp + log2_samples); 1490 } 1491 1492 int num_pipes = G_0098F8_NUM_PIPES(rad_info->gb_addr_config); 1493 int overlap = MAX2(0, log2_bpp_and_samples + num_pipes - 8); 1494 1495 if (vk_format_has_depth(image->vk.format)) { 1496 if (radv_image_is_tc_compat_htile(image) && overlap) { 1497 return true; 1498 } 1499 } else { 1500 int max_compressed_frags = G_0098F8_MAX_COMPRESSED_FRAGS(rad_info->gb_addr_config); 1501 int log2_samples_frag_diff = MAX2(0, log2_samples - max_compressed_frags); 1502 int samples_overlap = MIN2(log2_samples, overlap); 1503 1504 /* TODO: It shouldn't be necessary if the image has DCC but 1505 * not readable by shader. 1506 */ 1507 if ((radv_image_has_dcc(image) || radv_image_is_tc_compat_cmask(image)) && 1508 (samples_overlap > log2_samples_frag_diff)) { 1509 return true; 1510 } 1511 } 1512 } 1513 1514 return false; 1515} 1516 1517static bool 1518radv_image_is_l2_coherent(const struct radv_device *device, const struct radv_image *image) 1519{ 1520 if (device->physical_device->rad_info.gfx_level >= GFX10) { 1521 return !device->physical_device->rad_info.tcc_rb_non_coherent && 1522 !radv_image_is_pipe_misaligned(device, image); 1523 } else if (device->physical_device->rad_info.gfx_level == GFX9) { 1524 if (image->info.samples == 1 && 1525 (image->vk.usage & 1526 (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) && 1527 !vk_format_has_stencil(image->vk.format)) { 1528 /* Single-sample color and single-sample depth 1529 * (not stencil) are coherent with shaders on 1530 * GFX9. 1531 */ 1532 return true; 1533 } 1534 } 1535 1536 return false; 1537} 1538 1539/** 1540 * Determine if the given image can be fast cleared. 1541 */ 1542static bool 1543radv_image_can_fast_clear(const struct radv_device *device, const struct radv_image *image) 1544{ 1545 if (device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS) 1546 return false; 1547 1548 if (vk_format_is_color(image->vk.format)) { 1549 if (!radv_image_has_cmask(image) && !radv_image_has_dcc(image)) 1550 return false; 1551 1552 /* RB+ doesn't work with CMASK fast clear on Stoney. */ 1553 if (!radv_image_has_dcc(image) && device->physical_device->rad_info.family == CHIP_STONEY) 1554 return false; 1555 } else { 1556 if (!radv_image_has_htile(image)) 1557 return false; 1558 } 1559 1560 /* Do not fast clears 3D images. */ 1561 if (image->vk.image_type == VK_IMAGE_TYPE_3D) 1562 return false; 1563 1564 return true; 1565} 1566 1567/** 1568 * Determine if the given image can be fast cleared using comp-to-single. 1569 */ 1570static bool 1571radv_image_use_comp_to_single(const struct radv_device *device, const struct radv_image *image) 1572{ 1573 /* comp-to-single is only available for GFX10+. */ 1574 if (device->physical_device->rad_info.gfx_level < GFX10) 1575 return false; 1576 1577 /* If the image can't be fast cleared, comp-to-single can't be used. */ 1578 if (!radv_image_can_fast_clear(device, image)) 1579 return false; 1580 1581 /* If the image doesn't have DCC, it can't be fast cleared using comp-to-single */ 1582 if (!radv_image_has_dcc(image)) 1583 return false; 1584 1585 /* It seems 8bpp and 16bpp require RB+ to work. */ 1586 unsigned bytes_per_pixel = vk_format_get_blocksize(image->vk.format); 1587 if (bytes_per_pixel <= 2 && !device->physical_device->rad_info.rbplus_allowed) 1588 return false; 1589 1590 return true; 1591} 1592 1593static unsigned 1594radv_get_internal_plane_count(const struct radv_physical_device *pdev, VkFormat fmt) 1595{ 1596 if (pdev->emulate_etc2 && vk_format_description(fmt)->layout == UTIL_FORMAT_LAYOUT_ETC) 1597 return 2; 1598 return vk_format_get_plane_count(fmt); 1599} 1600 1601static void 1602radv_image_reset_layout(const struct radv_physical_device *pdev, struct radv_image *image) 1603{ 1604 image->size = 0; 1605 image->alignment = 1; 1606 1607 image->tc_compatible_cmask = 0; 1608 image->fce_pred_offset = image->dcc_pred_offset = 0; 1609 image->clear_value_offset = image->tc_compat_zrange_offset = 0; 1610 1611 unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk.format); 1612 for (unsigned i = 0; i < plane_count; ++i) { 1613 VkFormat format = radv_image_get_plane_format(pdev, image, i); 1614 if (vk_format_has_depth(format)) 1615 format = vk_format_depth_only(format); 1616 1617 uint64_t flags = image->planes[i].surface.flags; 1618 uint64_t modifier = image->planes[i].surface.modifier; 1619 memset(image->planes + i, 0, sizeof(image->planes[i])); 1620 1621 image->planes[i].surface.flags = flags; 1622 image->planes[i].surface.modifier = modifier; 1623 image->planes[i].surface.blk_w = vk_format_get_blockwidth(format); 1624 image->planes[i].surface.blk_h = vk_format_get_blockheight(format); 1625 image->planes[i].surface.bpe = vk_format_get_blocksize(format); 1626 1627 /* align byte per element on dword */ 1628 if (image->planes[i].surface.bpe == 3) { 1629 image->planes[i].surface.bpe = 4; 1630 } 1631 } 1632} 1633 1634VkResult 1635radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info, 1636 const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info, 1637 struct radv_image *image) 1638{ 1639 /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the 1640 * common internal case. */ 1641 create_info.vk_info = NULL; 1642 1643 struct ac_surf_info image_info = image->info; 1644 VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info); 1645 if (result != VK_SUCCESS) 1646 return result; 1647 1648 assert(!mod_info || mod_info->drmFormatModifierPlaneCount >= image->plane_count); 1649 1650 radv_image_reset_layout(device->physical_device, image); 1651 1652 unsigned plane_count = radv_get_internal_plane_count(device->physical_device, image->vk.format); 1653 for (unsigned plane = 0; plane < plane_count; ++plane) { 1654 struct ac_surf_info info = image_info; 1655 uint64_t offset; 1656 unsigned stride; 1657 1658 info.width = vk_format_get_plane_width(image->vk.format, plane, info.width); 1659 info.height = vk_format_get_plane_height(image->vk.format, plane, info.height); 1660 1661 if (create_info.no_metadata_planes || plane_count > 1) { 1662 image->planes[plane].surface.flags |= 1663 RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE; 1664 } 1665 1666 device->ws->surface_init(device->ws, &info, &image->planes[plane].surface); 1667 1668 if (plane == 0) { 1669 if (!radv_use_dcc_for_image_late(device, image)) 1670 ac_surface_zero_dcc_fields(&image->planes[0].surface); 1671 } 1672 1673 if (create_info.bo_metadata && !mod_info && 1674 !ac_surface_set_umd_metadata(&device->physical_device->rad_info, 1675 &image->planes[plane].surface, image_info.storage_samples, 1676 image_info.levels, create_info.bo_metadata->size_metadata, 1677 create_info.bo_metadata->metadata)) 1678 return VK_ERROR_INVALID_EXTERNAL_HANDLE; 1679 1680 if (!create_info.no_metadata_planes && !create_info.bo_metadata && plane_count == 1 && 1681 !mod_info) 1682 radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface); 1683 1684 if (mod_info) { 1685 if (mod_info->pPlaneLayouts[plane].rowPitch % image->planes[plane].surface.bpe || 1686 !mod_info->pPlaneLayouts[plane].rowPitch) 1687 return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT; 1688 1689 offset = mod_info->pPlaneLayouts[plane].offset; 1690 stride = mod_info->pPlaneLayouts[plane].rowPitch / image->planes[plane].surface.bpe; 1691 } else { 1692 offset = image->disjoint ? 0 : 1693 align64(image->size, 1 << image->planes[plane].surface.alignment_log2); 1694 stride = 0; /* 0 means no override */ 1695 } 1696 1697 if (!ac_surface_override_offset_stride(&device->physical_device->rad_info, 1698 &image->planes[plane].surface, image->info.levels, 1699 offset, stride)) 1700 return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT; 1701 1702 /* Validate DCC offsets in modifier layout. */ 1703 if (plane_count == 1 && mod_info) { 1704 unsigned mem_planes = ac_surface_get_nplanes(&image->planes[plane].surface); 1705 if (mod_info->drmFormatModifierPlaneCount != mem_planes) 1706 return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT; 1707 1708 for (unsigned i = 1; i < mem_planes; ++i) { 1709 if (ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level, 1710 &image->planes[plane].surface, i, 1711 0) != mod_info->pPlaneLayouts[i].offset) 1712 return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT; 1713 } 1714 } 1715 1716 image->size = MAX2(image->size, offset + image->planes[plane].surface.total_size); 1717 image->alignment = MAX2(image->alignment, 1 << image->planes[plane].surface.alignment_log2); 1718 1719 image->planes[plane].format = 1720 radv_image_get_plane_format(device->physical_device, image, plane); 1721 } 1722 1723 image->tc_compatible_cmask = 1724 radv_image_has_cmask(image) && radv_use_tc_compat_cmask_for_image(device, image); 1725 1726 image->l2_coherent = radv_image_is_l2_coherent(device, image); 1727 1728 image->support_comp_to_single = radv_image_use_comp_to_single(device, image); 1729 1730 radv_image_alloc_values(device, image); 1731 1732 assert(image->planes[0].surface.surf_size); 1733 assert(image->planes[0].surface.modifier == DRM_FORMAT_MOD_INVALID || 1734 ac_modifier_has_dcc(image->planes[0].surface.modifier) == radv_image_has_dcc(image)); 1735 return VK_SUCCESS; 1736} 1737 1738static void 1739radv_destroy_image(struct radv_device *device, const VkAllocationCallbacks *pAllocator, 1740 struct radv_image *image) 1741{ 1742 if ((image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bindings[0].bo) 1743 device->ws->buffer_destroy(device->ws, image->bindings[0].bo); 1744 1745 if (image->owned_memory != VK_NULL_HANDLE) { 1746 RADV_FROM_HANDLE(radv_device_memory, mem, image->owned_memory); 1747 radv_free_memory(device, pAllocator, mem); 1748 } 1749 1750 vk_image_finish(&image->vk); 1751 vk_free2(&device->vk.alloc, pAllocator, image); 1752} 1753 1754static void 1755radv_image_print_info(struct radv_device *device, struct radv_image *image) 1756{ 1757 fprintf(stderr, "Image:\n"); 1758 fprintf(stderr, 1759 " Info: size=%" PRIu64 ", alignment=%" PRIu32 ", " 1760 "width=%" PRIu32 ", height=%" PRIu32 ", " 1761 "array_size=%" PRIu32 ", levels=%" PRIu32 "\n", 1762 image->size, image->alignment, image->info.width, image->info.height, 1763 image->info.array_size, image->info.levels); 1764 for (unsigned i = 0; i < image->plane_count; ++i) { 1765 const struct radv_image_plane *plane = &image->planes[i]; 1766 const struct radeon_surf *surf = &plane->surface; 1767 const struct util_format_description *desc = vk_format_description(plane->format); 1768 uint64_t offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level, 1769 &plane->surface, 0, 0); 1770 1771 fprintf(stderr, " Plane[%u]: vkformat=%s, offset=%" PRIu64 "\n", i, desc->name, offset); 1772 1773 ac_surface_print_info(stderr, &device->physical_device->rad_info, surf); 1774 } 1775} 1776 1777static uint64_t 1778radv_select_modifier(const struct radv_device *dev, VkFormat format, 1779 const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list) 1780{ 1781 const struct radv_physical_device *pdev = dev->physical_device; 1782 unsigned mod_count; 1783 1784 assert(mod_list->drmFormatModifierCount); 1785 1786 /* We can allow everything here as it does not affect order and the application 1787 * is only allowed to specify modifiers that we support. */ 1788 const struct ac_modifier_options modifier_options = { 1789 .dcc = true, 1790 .dcc_retile = true, 1791 }; 1792 1793 ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format), 1794 &mod_count, NULL); 1795 1796 uint64_t *mods = calloc(mod_count, sizeof(*mods)); 1797 1798 /* If allocations fail, fall back to a dumber solution. */ 1799 if (!mods) 1800 return mod_list->pDrmFormatModifiers[0]; 1801 1802 ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format), 1803 &mod_count, mods); 1804 1805 for (unsigned i = 0; i < mod_count; ++i) { 1806 for (uint32_t j = 0; j < mod_list->drmFormatModifierCount; ++j) { 1807 if (mods[i] == mod_list->pDrmFormatModifiers[j]) { 1808 free(mods); 1809 return mod_list->pDrmFormatModifiers[j]; 1810 } 1811 } 1812 } 1813 unreachable("App specified an invalid modifier"); 1814} 1815 1816VkResult 1817radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info, 1818 const VkAllocationCallbacks *alloc, VkImage *pImage) 1819{ 1820 RADV_FROM_HANDLE(radv_device, device, _device); 1821 const VkImageCreateInfo *pCreateInfo = create_info->vk_info; 1822 uint64_t modifier = DRM_FORMAT_MOD_INVALID; 1823 struct radv_image *image = NULL; 1824 VkFormat format = radv_select_android_external_format(pCreateInfo->pNext, pCreateInfo->format); 1825 const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list = 1826 vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT); 1827 const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod = 1828 vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT); 1829 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); 1830 1831 unsigned plane_count = radv_get_internal_plane_count(device->physical_device, format); 1832 1833 const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count; 1834 1835 radv_assert(pCreateInfo->mipLevels > 0); 1836 radv_assert(pCreateInfo->arrayLayers > 0); 1837 radv_assert(pCreateInfo->samples > 0); 1838 radv_assert(pCreateInfo->extent.width > 0); 1839 radv_assert(pCreateInfo->extent.height > 0); 1840 radv_assert(pCreateInfo->extent.depth > 0); 1841 1842 image = 1843 vk_zalloc2(&device->vk.alloc, alloc, image_struct_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1844 if (!image) 1845 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1846 1847 vk_image_init(&device->vk, &image->vk, pCreateInfo); 1848 1849 image->info.width = pCreateInfo->extent.width; 1850 image->info.height = pCreateInfo->extent.height; 1851 image->info.depth = pCreateInfo->extent.depth; 1852 image->info.samples = pCreateInfo->samples; 1853 image->info.storage_samples = pCreateInfo->samples; 1854 image->info.array_size = pCreateInfo->arrayLayers; 1855 image->info.levels = pCreateInfo->mipLevels; 1856 image->info.num_channels = vk_format_get_nr_components(format); 1857 1858 image->plane_count = vk_format_get_plane_count(format); 1859 image->disjoint = image->plane_count > 1 && pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT; 1860 1861 image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE; 1862 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) { 1863 for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i) 1864 if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL || 1865 pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT) 1866 image->queue_family_mask |= (1u << RADV_MAX_QUEUE_FAMILIES) - 1u; 1867 else 1868 image->queue_family_mask |= 1u << vk_queue_to_radv(device->physical_device, 1869 pCreateInfo->pQueueFamilyIndices[i]); 1870 } 1871 1872 const VkExternalMemoryImageCreateInfo *external_info = 1873 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO); 1874 1875 image->shareable = external_info; 1876 if (!vk_format_is_depth_or_stencil(format) && !image->shareable && 1877 !(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) && 1878 pCreateInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1879 image->info.surf_index = &device->image_mrt_offset_counter; 1880 } 1881 1882 if (mod_list) 1883 modifier = radv_select_modifier(device, format, mod_list); 1884 else if (explicit_mod) 1885 modifier = explicit_mod->drmFormatModifier; 1886 1887 for (unsigned plane = 0; plane < plane_count; ++plane) { 1888 image->planes[plane].surface.flags = 1889 radv_get_surface_flags(device, image, plane, pCreateInfo, format); 1890 image->planes[plane].surface.modifier = modifier; 1891 } 1892 1893 bool delay_layout = 1894 external_info && (external_info->handleTypes & 1895 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID); 1896 1897 if (delay_layout) { 1898 *pImage = radv_image_to_handle(image); 1899 assert(!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)); 1900 return VK_SUCCESS; 1901 } 1902 1903 VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, image); 1904 if (result != VK_SUCCESS) { 1905 radv_destroy_image(device, alloc, image); 1906 return result; 1907 } 1908 1909 if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) { 1910 image->alignment = MAX2(image->alignment, 4096); 1911 image->size = align64(image->size, image->alignment); 1912 image->bindings[0].offset = 0; 1913 1914 result = 1915 device->ws->buffer_create(device->ws, image->size, image->alignment, 0, 1916 RADEON_FLAG_VIRTUAL, RADV_BO_PRIORITY_VIRTUAL, 0, 1917 &image->bindings[0].bo); 1918 if (result != VK_SUCCESS) { 1919 radv_destroy_image(device, alloc, image); 1920 return vk_error(device, result); 1921 } 1922 } 1923 1924 if (device->instance->debug_flags & RADV_DEBUG_IMG) { 1925 radv_image_print_info(device, image); 1926 } 1927 1928 *pImage = radv_image_to_handle(image); 1929 1930 return VK_SUCCESS; 1931} 1932 1933static void 1934radv_image_view_make_descriptor(struct radv_image_view *iview, struct radv_device *device, 1935 VkFormat vk_format, const VkComponentMapping *components, 1936 float min_lod, 1937 bool is_storage_image, bool disable_compression, 1938 bool enable_compression, unsigned plane_id, 1939 unsigned descriptor_plane_id, VkImageCreateFlags img_create_flags) 1940{ 1941 struct radv_image *image = iview->image; 1942 struct radv_image_plane *plane = &image->planes[plane_id]; 1943 bool is_stencil = iview->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT; 1944 uint32_t blk_w; 1945 union radv_descriptor *descriptor; 1946 uint32_t hw_level = 0; 1947 1948 if (is_storage_image) { 1949 descriptor = &iview->storage_descriptor; 1950 } else { 1951 descriptor = &iview->descriptor; 1952 } 1953 1954 assert(vk_format_get_plane_count(vk_format) == 1); 1955 assert(plane->surface.blk_w % vk_format_get_blockwidth(plane->format) == 0); 1956 blk_w = plane->surface.blk_w / vk_format_get_blockwidth(plane->format) * 1957 vk_format_get_blockwidth(vk_format); 1958 1959 if (device->physical_device->rad_info.gfx_level >= GFX9) 1960 hw_level = iview->vk.base_mip_level; 1961 radv_make_texture_descriptor( 1962 device, image, is_storage_image, iview->vk.view_type, vk_format, components, hw_level, 1963 hw_level + iview->vk.level_count - 1, iview->vk.base_array_layer, 1964 iview->vk.base_array_layer + iview->vk.layer_count - 1, 1965 vk_format_get_plane_width(image->vk.format, plane_id, iview->extent.width), 1966 vk_format_get_plane_height(image->vk.format, plane_id, iview->extent.height), 1967 iview->extent.depth, min_lod, descriptor->plane_descriptors[descriptor_plane_id], 1968 descriptor_plane_id || is_storage_image ? NULL : descriptor->fmask_descriptor, 1969 img_create_flags); 1970 1971 const struct legacy_surf_level *base_level_info = NULL; 1972 if (device->physical_device->rad_info.gfx_level <= GFX9) { 1973 if (is_stencil) 1974 base_level_info = &plane->surface.u.legacy.zs.stencil_level[iview->vk.base_mip_level]; 1975 else 1976 base_level_info = &plane->surface.u.legacy.level[iview->vk.base_mip_level]; 1977 } 1978 1979 bool enable_write_compression = radv_image_use_dcc_image_stores(device, image); 1980 if (is_storage_image && !(enable_write_compression || enable_compression)) 1981 disable_compression = true; 1982 si_set_mutable_tex_desc_fields(device, image, base_level_info, plane_id, iview->vk.base_mip_level, 1983 iview->vk.base_mip_level, blk_w, is_stencil, is_storage_image, 1984 disable_compression, enable_write_compression, 1985 descriptor->plane_descriptors[descriptor_plane_id]); 1986} 1987 1988static unsigned 1989radv_plane_from_aspect(VkImageAspectFlags mask) 1990{ 1991 switch (mask) { 1992 case VK_IMAGE_ASPECT_PLANE_1_BIT: 1993 case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT: 1994 return 1; 1995 case VK_IMAGE_ASPECT_PLANE_2_BIT: 1996 case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT: 1997 return 2; 1998 case VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT: 1999 return 3; 2000 default: 2001 return 0; 2002 } 2003} 2004 2005VkFormat 2006radv_get_aspect_format(struct radv_image *image, VkImageAspectFlags mask) 2007{ 2008 switch (mask) { 2009 case VK_IMAGE_ASPECT_PLANE_0_BIT: 2010 return image->planes[0].format; 2011 case VK_IMAGE_ASPECT_PLANE_1_BIT: 2012 return image->planes[1].format; 2013 case VK_IMAGE_ASPECT_PLANE_2_BIT: 2014 return image->planes[2].format; 2015 case VK_IMAGE_ASPECT_STENCIL_BIT: 2016 return vk_format_stencil_only(image->vk.format); 2017 case VK_IMAGE_ASPECT_DEPTH_BIT: 2018 return vk_format_depth_only(image->vk.format); 2019 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 2020 return vk_format_depth_only(image->vk.format); 2021 default: 2022 return image->vk.format; 2023 } 2024} 2025 2026/** 2027 * Determine if the given image view can be fast cleared. 2028 */ 2029static bool 2030radv_image_view_can_fast_clear(const struct radv_device *device, 2031 const struct radv_image_view *iview) 2032{ 2033 struct radv_image *image; 2034 2035 if (!iview) 2036 return false; 2037 image = iview->image; 2038 2039 /* Only fast clear if the image itself can be fast cleared. */ 2040 if (!radv_image_can_fast_clear(device, image)) 2041 return false; 2042 2043 /* Only fast clear if all layers are bound. */ 2044 if (iview->vk.base_array_layer > 0 || iview->vk.layer_count != image->info.array_size) 2045 return false; 2046 2047 /* Only fast clear if the view covers the whole image. */ 2048 if (!radv_image_extent_compare(image, &iview->extent)) 2049 return false; 2050 2051 return true; 2052} 2053 2054void 2055radv_image_view_init(struct radv_image_view *iview, struct radv_device *device, 2056 const VkImageViewCreateInfo *pCreateInfo, 2057 VkImageCreateFlags img_create_flags, 2058 const struct radv_image_view_extra_create_info *extra_create_info) 2059{ 2060 RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image); 2061 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; 2062 uint32_t plane_count = 1; 2063 float min_lod = 0.0f; 2064 2065 const struct VkImageViewMinLodCreateInfoEXT *min_lod_info = 2066 vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT); 2067 2068 if (min_lod_info) 2069 min_lod = min_lod_info->minLod; 2070 2071 bool from_client = extra_create_info && extra_create_info->from_client; 2072 vk_image_view_init(&device->vk, &iview->vk, !from_client, pCreateInfo); 2073 2074 switch (image->vk.image_type) { 2075 case VK_IMAGE_TYPE_1D: 2076 case VK_IMAGE_TYPE_2D: 2077 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= 2078 image->info.array_size); 2079 break; 2080 case VK_IMAGE_TYPE_3D: 2081 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= 2082 radv_minify(image->info.depth, range->baseMipLevel)); 2083 break; 2084 default: 2085 unreachable("bad VkImageType"); 2086 } 2087 iview->image = image; 2088 iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask); 2089 2090 /* If the image has an Android external format, pCreateInfo->format will be 2091 * VK_FORMAT_UNDEFINED. */ 2092 if (iview->vk.format == VK_FORMAT_UNDEFINED) { 2093 iview->vk.format = image->vk.format; 2094 iview->vk.view_format = image->vk.format; 2095 } 2096 2097 /* Split out the right aspect. Note that for internal meta code we sometimes 2098 * use an equivalent color format for the aspect so we first have to check 2099 * if we actually got depth/stencil formats. */ 2100 if (iview->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT) { 2101 if (vk_format_has_stencil(iview->vk.view_format)) 2102 iview->vk.view_format = vk_format_stencil_only(iview->vk.view_format); 2103 } else if (iview->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT) { 2104 if (vk_format_has_depth(iview->vk.view_format)) 2105 iview->vk.view_format = vk_format_depth_only(iview->vk.view_format); 2106 } 2107 2108 if (vk_format_get_plane_count(image->vk.format) > 1 && 2109 pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) { 2110 plane_count = vk_format_get_plane_count(iview->vk.format); 2111 } 2112 2113 if (device->physical_device->emulate_etc2 && 2114 vk_format_description(image->vk.format)->layout == UTIL_FORMAT_LAYOUT_ETC) { 2115 const struct util_format_description *desc = vk_format_description(iview->vk.format); 2116 if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) { 2117 iview->plane_id = 1; 2118 iview->vk.format = etc2_emulation_format(iview->vk.format); 2119 iview->vk.view_format = etc2_emulation_format(iview->vk.format); 2120 } 2121 2122 plane_count = 1; 2123 } 2124 2125 if (device->physical_device->rad_info.gfx_level >= GFX9) { 2126 iview->extent = (VkExtent3D){ 2127 .width = image->info.width, 2128 .height = image->info.height, 2129 .depth = image->info.depth, 2130 }; 2131 } else { 2132 iview->extent = iview->vk.extent; 2133 } 2134 2135 if (iview->vk.format != image->planes[iview->plane_id].format) { 2136 unsigned view_bw = vk_format_get_blockwidth(iview->vk.format); 2137 unsigned view_bh = vk_format_get_blockheight(iview->vk.format); 2138 unsigned img_bw = vk_format_get_blockwidth(image->planes[iview->plane_id].format); 2139 unsigned img_bh = vk_format_get_blockheight(image->planes[iview->plane_id].format); 2140 2141 iview->extent.width = round_up_u32(iview->extent.width * view_bw, img_bw); 2142 iview->extent.height = round_up_u32(iview->extent.height * view_bh, img_bh); 2143 2144 /* Comment ported from amdvlk - 2145 * If we have the following image: 2146 * Uncompressed pixels Compressed block sizes (4x4) 2147 * mip0: 22 x 22 6 x 6 2148 * mip1: 11 x 11 3 x 3 2149 * mip2: 5 x 5 2 x 2 2150 * mip3: 2 x 2 1 x 1 2151 * mip4: 1 x 1 1 x 1 2152 * 2153 * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and 2154 * the HW is calculating the degradation of the block sizes down the mip-chain as follows 2155 * (straight-up divide-by-two integer math): mip0: 6x6 mip1: 3x3 mip2: 1x1 mip3: 1x1 2156 * 2157 * This means that mip2 will be missing texels. 2158 * 2159 * Fix this by calculating the base mip's width and height, then convert 2160 * that, and round it back up to get the level 0 size. Clamp the 2161 * converted size between the original values, and the physical extent 2162 * of the base mipmap. 2163 * 2164 * On GFX10 we have to take care to not go over the physical extent 2165 * of the base mipmap as otherwise the GPU computes a different layout. 2166 * Note that the GPU does use the same base-mip dimensions for both a 2167 * block compatible format and the compressed format, so even if we take 2168 * the plain converted dimensions the physical layout is correct. 2169 */ 2170 if (device->physical_device->rad_info.gfx_level >= GFX9 && 2171 vk_format_is_compressed(image->vk.format) && !vk_format_is_compressed(iview->vk.format)) { 2172 /* If we have multiple levels in the view we should ideally take the last level, 2173 * but the mip calculation has a max(..., 1) so walking back to the base mip in an 2174 * useful way is hard. */ 2175 if (iview->vk.level_count > 1) { 2176 iview->extent.width = iview->image->planes[0].surface.u.gfx9.base_mip_width; 2177 iview->extent.height = iview->image->planes[0].surface.u.gfx9.base_mip_height; 2178 } else { 2179 unsigned lvl_width = radv_minify(image->info.width, range->baseMipLevel); 2180 unsigned lvl_height = radv_minify(image->info.height, range->baseMipLevel); 2181 2182 lvl_width = round_up_u32(lvl_width * view_bw, img_bw); 2183 lvl_height = round_up_u32(lvl_height * view_bh, img_bh); 2184 2185 lvl_width <<= range->baseMipLevel; 2186 lvl_height <<= range->baseMipLevel; 2187 2188 iview->extent.width = CLAMP(lvl_width, iview->extent.width, 2189 iview->image->planes[0].surface.u.gfx9.base_mip_width); 2190 iview->extent.height = CLAMP(lvl_height, iview->extent.height, 2191 iview->image->planes[0].surface.u.gfx9.base_mip_height); 2192 } 2193 } 2194 } 2195 2196 iview->support_fast_clear = radv_image_view_can_fast_clear(device, iview); 2197 iview->disable_dcc_mrt = extra_create_info ? extra_create_info->disable_dcc_mrt : false; 2198 2199 bool disable_compression = extra_create_info ? extra_create_info->disable_compression : false; 2200 bool enable_compression = extra_create_info ? extra_create_info->enable_compression : false; 2201 for (unsigned i = 0; i < plane_count; ++i) { 2202 VkFormat format = vk_format_get_plane_format(iview->vk.view_format, i); 2203 radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, false, 2204 disable_compression, enable_compression, iview->plane_id + i, 2205 i, img_create_flags); 2206 radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, true, 2207 disable_compression, enable_compression, iview->plane_id + i, 2208 i, img_create_flags); 2209 } 2210} 2211 2212void 2213radv_image_view_finish(struct radv_image_view *iview) 2214{ 2215 vk_image_view_finish(&iview->vk); 2216} 2217 2218bool 2219radv_layout_is_htile_compressed(const struct radv_device *device, const struct radv_image *image, 2220 VkImageLayout layout, bool in_render_loop, unsigned queue_mask) 2221{ 2222 switch (layout) { 2223 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 2224 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL: 2225 case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL: 2226 case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL: 2227 return radv_image_has_htile(image); 2228 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 2229 return radv_image_is_tc_compat_htile(image) || 2230 (radv_image_has_htile(image) && queue_mask == (1u << RADV_QUEUE_GENERAL)); 2231 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: 2232 case VK_IMAGE_LAYOUT_GENERAL: 2233 /* It should be safe to enable TC-compat HTILE with 2234 * VK_IMAGE_LAYOUT_GENERAL if we are not in a render loop and 2235 * if the image doesn't have the storage bit set. This 2236 * improves performance for apps that use GENERAL for the main 2237 * depth pass because this allows compression and this reduces 2238 * the number of decompressions from/to GENERAL. 2239 */ 2240 /* FIXME: Enabling TC-compat HTILE in GENERAL on the compute 2241 * queue is likely broken for eg. depth/stencil copies. 2242 */ 2243 if (radv_image_is_tc_compat_htile(image) && queue_mask & (1u << RADV_QUEUE_GENERAL) && 2244 !in_render_loop && !device->instance->disable_tc_compat_htile_in_general) { 2245 return true; 2246 } else { 2247 return false; 2248 } 2249 case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT: 2250 /* Do not compress HTILE with feedback loops because we can't read&write it without 2251 * introducing corruption. 2252 */ 2253 return false; 2254 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 2255 if (radv_image_is_tc_compat_htile(image) || 2256 (radv_image_has_htile(image) && 2257 !(image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | 2258 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))) { 2259 /* Keep HTILE compressed if the image is only going to 2260 * be used as a depth/stencil read-only attachment. 2261 */ 2262 return true; 2263 } else { 2264 return false; 2265 } 2266 break; 2267 default: 2268 return radv_image_is_tc_compat_htile(image); 2269 } 2270} 2271 2272bool 2273radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image, 2274 unsigned level, VkImageLayout layout, bool in_render_loop, 2275 unsigned queue_mask) 2276{ 2277 if (radv_dcc_enabled(image, level) && 2278 !radv_layout_dcc_compressed(device, image, level, layout, in_render_loop, queue_mask)) 2279 return false; 2280 2281 if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS)) 2282 return false; 2283 2284 if (layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && 2285 layout != VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL) 2286 return false; 2287 2288 /* Exclusive images with CMASK or DCC can always be fast-cleared on the gfx queue. Concurrent 2289 * images can only be fast-cleared if comp-to-single is supported because we don't yet support 2290 * FCE on the compute queue. 2291 */ 2292 return queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_use_comp_to_single(device, image); 2293} 2294 2295bool 2296radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image, 2297 unsigned level, VkImageLayout layout, bool in_render_loop, 2298 unsigned queue_mask) 2299{ 2300 if (!radv_dcc_enabled(image, level)) 2301 return false; 2302 2303 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && 2304 queue_mask & (1u << RADV_QUEUE_FOREIGN)) 2305 return true; 2306 2307 /* If the image is read-only, we can always just keep it compressed */ 2308 if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS)) 2309 return true; 2310 2311 /* Don't compress compute transfer dst when image stores are not supported. */ 2312 if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) && 2313 (queue_mask & (1u << RADV_QUEUE_COMPUTE)) && !radv_image_use_dcc_image_stores(device, image)) 2314 return false; 2315 2316 if (layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT) { 2317 /* Do not compress DCC with feedback loops because we can't read&write it without introducing 2318 * corruption. 2319 */ 2320 return false; 2321 } 2322 2323 return device->physical_device->rad_info.gfx_level >= GFX10 || layout != VK_IMAGE_LAYOUT_GENERAL; 2324} 2325 2326bool 2327radv_layout_fmask_compressed(const struct radv_device *device, const struct radv_image *image, 2328 VkImageLayout layout, unsigned queue_mask) 2329{ 2330 if (!radv_image_has_fmask(image)) 2331 return false; 2332 2333 /* Don't compress compute transfer dst because image stores ignore FMASK and it needs to be 2334 * expanded before. 2335 */ 2336 if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) && 2337 (queue_mask & (1u << RADV_QUEUE_COMPUTE))) 2338 return false; 2339 2340 /* Only compress concurrent images if TC-compat CMASK is enabled (no FMASK decompression). */ 2341 return layout != VK_IMAGE_LAYOUT_GENERAL && 2342 (queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_is_tc_compat_cmask(image)); 2343} 2344 2345unsigned 2346radv_image_queue_family_mask(const struct radv_image *image, 2347 enum radv_queue_family family, 2348 enum radv_queue_family queue_family) 2349{ 2350 if (!image->exclusive) 2351 return image->queue_family_mask; 2352 if (family == RADV_QUEUE_FOREIGN) 2353 return ((1u << RADV_MAX_QUEUE_FAMILIES) - 1u) | (1u << RADV_QUEUE_FOREIGN); 2354 if (family == RADV_QUEUE_IGNORED) 2355 return 1u << queue_family; 2356 return 1u << family; 2357} 2358 2359VKAPI_ATTR VkResult VKAPI_CALL 2360radv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo, 2361 const VkAllocationCallbacks *pAllocator, VkImage *pImage) 2362{ 2363#ifdef ANDROID 2364 const VkNativeBufferANDROID *gralloc_info = 2365 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID); 2366 2367 if (gralloc_info) 2368 return radv_image_from_gralloc(device, pCreateInfo, gralloc_info, pAllocator, pImage); 2369#endif 2370 2371 const struct wsi_image_create_info *wsi_info = 2372 vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA); 2373 bool scanout = wsi_info && wsi_info->scanout; 2374 bool prime_blit_src = wsi_info && wsi_info->buffer_blit_src; 2375 2376 return radv_image_create(device, 2377 &(struct radv_image_create_info){ 2378 .vk_info = pCreateInfo, 2379 .scanout = scanout, 2380 .prime_blit_src = prime_blit_src, 2381 }, 2382 pAllocator, pImage); 2383} 2384 2385VKAPI_ATTR void VKAPI_CALL 2386radv_DestroyImage(VkDevice _device, VkImage _image, const VkAllocationCallbacks *pAllocator) 2387{ 2388 RADV_FROM_HANDLE(radv_device, device, _device); 2389 RADV_FROM_HANDLE(radv_image, image, _image); 2390 2391 if (!image) 2392 return; 2393 2394 radv_destroy_image(device, pAllocator, image); 2395} 2396 2397VKAPI_ATTR void VKAPI_CALL 2398radv_GetImageSubresourceLayout(VkDevice _device, VkImage _image, 2399 const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout) 2400{ 2401 RADV_FROM_HANDLE(radv_image, image, _image); 2402 RADV_FROM_HANDLE(radv_device, device, _device); 2403 int level = pSubresource->mipLevel; 2404 int layer = pSubresource->arrayLayer; 2405 2406 unsigned plane_id = 0; 2407 if (vk_format_get_plane_count(image->vk.format) > 1) 2408 plane_id = radv_plane_from_aspect(pSubresource->aspectMask); 2409 2410 struct radv_image_plane *plane = &image->planes[plane_id]; 2411 struct radeon_surf *surface = &plane->surface; 2412 2413 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 2414 unsigned mem_plane_id = radv_plane_from_aspect(pSubresource->aspectMask); 2415 2416 assert(level == 0); 2417 assert(layer == 0); 2418 2419 pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level, 2420 surface, mem_plane_id, 0); 2421 pLayout->rowPitch = ac_surface_get_plane_stride(device->physical_device->rad_info.gfx_level, 2422 surface, mem_plane_id, level); 2423 pLayout->arrayPitch = 0; 2424 pLayout->depthPitch = 0; 2425 pLayout->size = ac_surface_get_plane_size(surface, mem_plane_id); 2426 } else if (device->physical_device->rad_info.gfx_level >= GFX9) { 2427 uint64_t level_offset = surface->is_linear ? surface->u.gfx9.offset[level] : 0; 2428 2429 pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level, 2430 &plane->surface, 0, layer) + 2431 level_offset; 2432 if (image->vk.format == VK_FORMAT_R32G32B32_UINT || 2433 image->vk.format == VK_FORMAT_R32G32B32_SINT || 2434 image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) { 2435 /* Adjust the number of bytes between each row because 2436 * the pitch is actually the number of components per 2437 * row. 2438 */ 2439 pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe / 3; 2440 } else { 2441 uint32_t pitch = 2442 surface->is_linear ? surface->u.gfx9.pitch[level] : surface->u.gfx9.surf_pitch; 2443 2444 assert(util_is_power_of_two_nonzero(surface->bpe)); 2445 pLayout->rowPitch = pitch * surface->bpe; 2446 } 2447 2448 pLayout->arrayPitch = surface->u.gfx9.surf_slice_size; 2449 pLayout->depthPitch = surface->u.gfx9.surf_slice_size; 2450 pLayout->size = surface->u.gfx9.surf_slice_size; 2451 if (image->vk.image_type == VK_IMAGE_TYPE_3D) 2452 pLayout->size *= u_minify(image->info.depth, level); 2453 } else { 2454 pLayout->offset = (uint64_t)surface->u.legacy.level[level].offset_256B * 256 + 2455 (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer; 2456 pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe; 2457 pLayout->arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4; 2458 pLayout->depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4; 2459 pLayout->size = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4; 2460 if (image->vk.image_type == VK_IMAGE_TYPE_3D) 2461 pLayout->size *= u_minify(image->info.depth, level); 2462 } 2463} 2464 2465VKAPI_ATTR VkResult VKAPI_CALL 2466radv_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device, VkImage _image, 2467 VkImageDrmFormatModifierPropertiesEXT *pProperties) 2468{ 2469 RADV_FROM_HANDLE(radv_image, image, _image); 2470 2471 pProperties->drmFormatModifier = image->planes[0].surface.modifier; 2472 return VK_SUCCESS; 2473} 2474 2475VKAPI_ATTR VkResult VKAPI_CALL 2476radv_CreateImageView(VkDevice _device, const VkImageViewCreateInfo *pCreateInfo, 2477 const VkAllocationCallbacks *pAllocator, VkImageView *pView) 2478{ 2479 RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image); 2480 RADV_FROM_HANDLE(radv_device, device, _device); 2481 struct radv_image_view *view; 2482 2483 view = 2484 vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2485 if (view == NULL) 2486 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2487 2488 radv_image_view_init(view, device, pCreateInfo, image->vk.create_flags, 2489 &(struct radv_image_view_extra_create_info){.from_client = true}); 2490 2491 *pView = radv_image_view_to_handle(view); 2492 2493 return VK_SUCCESS; 2494} 2495 2496VKAPI_ATTR void VKAPI_CALL 2497radv_DestroyImageView(VkDevice _device, VkImageView _iview, const VkAllocationCallbacks *pAllocator) 2498{ 2499 RADV_FROM_HANDLE(radv_device, device, _device); 2500 RADV_FROM_HANDLE(radv_image_view, iview, _iview); 2501 2502 if (!iview) 2503 return; 2504 2505 radv_image_view_finish(iview); 2506 vk_free2(&device->vk.alloc, pAllocator, iview); 2507} 2508 2509void 2510radv_buffer_view_init(struct radv_buffer_view *view, struct radv_device *device, 2511 const VkBufferViewCreateInfo *pCreateInfo) 2512{ 2513 RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer); 2514 2515 vk_object_base_init(&device->vk, &view->base, VK_OBJECT_TYPE_BUFFER_VIEW); 2516 2517 view->bo = buffer->bo; 2518 view->range = vk_buffer_range(&buffer->vk, pCreateInfo->offset, pCreateInfo->range); 2519 view->vk_format = pCreateInfo->format; 2520 2521 radv_make_buffer_descriptor(device, buffer, view->vk_format, pCreateInfo->offset, view->range, 2522 view->state); 2523} 2524 2525void 2526radv_buffer_view_finish(struct radv_buffer_view *view) 2527{ 2528 vk_object_base_finish(&view->base); 2529} 2530 2531VKAPI_ATTR VkResult VKAPI_CALL 2532radv_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo, 2533 const VkAllocationCallbacks *pAllocator, VkBufferView *pView) 2534{ 2535 RADV_FROM_HANDLE(radv_device, device, _device); 2536 struct radv_buffer_view *view; 2537 2538 view = 2539 vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 2540 if (!view) 2541 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2542 2543 radv_buffer_view_init(view, device, pCreateInfo); 2544 2545 *pView = radv_buffer_view_to_handle(view); 2546 2547 return VK_SUCCESS; 2548} 2549 2550VKAPI_ATTR void VKAPI_CALL 2551radv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, 2552 const VkAllocationCallbacks *pAllocator) 2553{ 2554 RADV_FROM_HANDLE(radv_device, device, _device); 2555 RADV_FROM_HANDLE(radv_buffer_view, view, bufferView); 2556 2557 if (!view) 2558 return; 2559 2560 radv_buffer_view_finish(view); 2561 vk_free2(&device->vk.alloc, pAllocator, view); 2562} 2563