1/* 2 * Copyright © 2015 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21 * IN THE SOFTWARE. 22 */ 23 24#include <assert.h> 25#include <stdbool.h> 26#include <string.h> 27#include <unistd.h> 28#include <fcntl.h> 29#include <sys/mman.h> 30#include "drm-uapi/drm_fourcc.h" 31 32#include "anv_private.h" 33#include "util/debug.h" 34#include "vk_util.h" 35#include "util/u_math.h" 36 37#include "vk_format.h" 38 39#define ANV_OFFSET_IMPLICIT UINT64_MAX 40 41static const enum isl_surf_dim 42vk_to_isl_surf_dim[] = { 43 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D, 44 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D, 45 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D, 46}; 47 48static uint64_t MUST_CHECK UNUSED 49memory_range_end(struct anv_image_memory_range memory_range) 50{ 51 assert(anv_is_aligned(memory_range.offset, memory_range.alignment)); 52 return memory_range.offset + memory_range.size; 53} 54 55/** 56 * Get binding for VkImagePlaneMemoryRequirementsInfo, 57 * VkBindImagePlaneMemoryInfo and VkDeviceImageMemoryRequirementsKHR. 58 */ 59static struct anv_image_binding * 60image_aspect_to_binding(struct anv_image *image, VkImageAspectFlags aspect) 61{ 62 uint32_t plane; 63 64 assert(image->disjoint); 65 66 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 67 /* Spec requires special aspects for modifier images. */ 68 assert(aspect >= VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT && 69 aspect <= VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT); 70 71 /* We don't advertise DISJOINT for modifiers with aux, and therefore we 72 * don't handle queries of the modifier's "aux plane" here. 73 */ 74 assert(!isl_drm_modifier_has_aux(image->vk.drm_format_mod)); 75 76 plane = aspect - VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT; 77 } else { 78 plane = anv_image_aspect_to_plane(image, aspect); 79 } 80 81 return &image->bindings[ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane]; 82} 83 84/** 85 * Extend the memory binding's range by appending a new memory range with `size` 86 * and `alignment` at `offset`. Return the appended range. 87 * 88 * Offset is ignored if ANV_OFFSET_IMPLICIT. 89 * 90 * The given binding must not be ANV_IMAGE_MEMORY_BINDING_MAIN. The function 91 * converts to MAIN as needed. 92 */ 93static VkResult MUST_CHECK 94image_binding_grow(const struct anv_device *device, 95 struct anv_image *image, 96 enum anv_image_memory_binding binding, 97 uint64_t offset, 98 uint64_t size, 99 uint32_t alignment, 100 struct anv_image_memory_range *out_range) 101{ 102 /* We overwrite 'offset' but need to remember if it was implicit. */ 103 const bool has_implicit_offset = (offset == ANV_OFFSET_IMPLICIT); 104 105 assert(size > 0); 106 assert(util_is_power_of_two_or_zero(alignment)); 107 108 switch (binding) { 109 case ANV_IMAGE_MEMORY_BINDING_MAIN: 110 /* The caller must not pre-translate BINDING_PLANE_i to BINDING_MAIN. */ 111 unreachable("ANV_IMAGE_MEMORY_BINDING_MAIN"); 112 case ANV_IMAGE_MEMORY_BINDING_PLANE_0: 113 case ANV_IMAGE_MEMORY_BINDING_PLANE_1: 114 case ANV_IMAGE_MEMORY_BINDING_PLANE_2: 115 if (!image->disjoint) 116 binding = ANV_IMAGE_MEMORY_BINDING_MAIN; 117 break; 118 case ANV_IMAGE_MEMORY_BINDING_PRIVATE: 119 assert(offset == ANV_OFFSET_IMPLICIT); 120 break; 121 case ANV_IMAGE_MEMORY_BINDING_END: 122 unreachable("ANV_IMAGE_MEMORY_BINDING_END"); 123 } 124 125 struct anv_image_memory_range *container = 126 &image->bindings[binding].memory_range; 127 128 if (has_implicit_offset) { 129 offset = align_u64(container->offset + container->size, alignment); 130 } else { 131 /* Offset must be validated because it comes from 132 * VkImageDrmFormatModifierExplicitCreateInfoEXT. 133 */ 134 if (unlikely(!anv_is_aligned(offset, alignment))) { 135 return vk_errorf(device, 136 VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, 137 "VkImageDrmFormatModifierExplicitCreateInfoEXT::" 138 "pPlaneLayouts[]::offset is misaligned"); 139 } 140 141 /* We require that surfaces be added in memory-order. This simplifies the 142 * layout validation required by 143 * VkImageDrmFormatModifierExplicitCreateInfoEXT, 144 */ 145 if (unlikely(offset < container->size)) { 146 return vk_errorf(device, 147 VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, 148 "VkImageDrmFormatModifierExplicitCreateInfoEXT::" 149 "pPlaneLayouts[]::offset is too small"); 150 } 151 } 152 153 if (__builtin_add_overflow(offset, size, &container->size)) { 154 if (has_implicit_offset) { 155 assert(!"overflow"); 156 return vk_errorf(device, VK_ERROR_UNKNOWN, 157 "internal error: overflow in %s", __func__); 158 } else { 159 return vk_errorf(device, 160 VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, 161 "VkImageDrmFormatModifierExplicitCreateInfoEXT::" 162 "pPlaneLayouts[]::offset is too large"); 163 } 164 } 165 166 container->alignment = MAX2(container->alignment, alignment); 167 168 *out_range = (struct anv_image_memory_range) { 169 .binding = binding, 170 .offset = offset, 171 .size = size, 172 .alignment = alignment, 173 }; 174 175 return VK_SUCCESS; 176} 177 178/** 179 * Adjust range 'a' to contain range 'b'. 180 * 181 * For simplicity's sake, the offset of 'a' must be 0 and remains 0. 182 * If 'a' and 'b' target different bindings, then no merge occurs. 183 */ 184static void 185memory_range_merge(struct anv_image_memory_range *a, 186 const struct anv_image_memory_range b) 187{ 188 if (b.size == 0) 189 return; 190 191 if (a->binding != b.binding) 192 return; 193 194 assert(a->offset == 0); 195 assert(anv_is_aligned(a->offset, a->alignment)); 196 assert(anv_is_aligned(b.offset, b.alignment)); 197 198 a->alignment = MAX2(a->alignment, b.alignment); 199 a->size = MAX2(a->size, b.offset + b.size); 200} 201 202static isl_surf_usage_flags_t 203choose_isl_surf_usage(VkImageCreateFlags vk_create_flags, 204 VkImageUsageFlags vk_usage, 205 isl_surf_usage_flags_t isl_extra_usage, 206 VkImageAspectFlagBits aspect) 207{ 208 isl_surf_usage_flags_t isl_usage = isl_extra_usage; 209 210 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) 211 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 212 213 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) 214 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 215 216 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 217 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 218 219 if (vk_create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 220 isl_usage |= ISL_SURF_USAGE_CUBE_BIT; 221 222 /* Even if we're only using it for transfer operations, clears to depth and 223 * stencil images happen as depth and stencil so they need the right ISL 224 * usage bits or else things will fall apart. 225 */ 226 switch (aspect) { 227 case VK_IMAGE_ASPECT_DEPTH_BIT: 228 isl_usage |= ISL_SURF_USAGE_DEPTH_BIT; 229 break; 230 case VK_IMAGE_ASPECT_STENCIL_BIT: 231 isl_usage |= ISL_SURF_USAGE_STENCIL_BIT; 232 break; 233 case VK_IMAGE_ASPECT_COLOR_BIT: 234 case VK_IMAGE_ASPECT_PLANE_0_BIT: 235 case VK_IMAGE_ASPECT_PLANE_1_BIT: 236 case VK_IMAGE_ASPECT_PLANE_2_BIT: 237 break; 238 default: 239 unreachable("bad VkImageAspect"); 240 } 241 242 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 243 /* blorp implements transfers by sampling from the source image. */ 244 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 245 } 246 247 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT && 248 aspect == VK_IMAGE_ASPECT_COLOR_BIT) { 249 /* blorp implements transfers by rendering into the destination image. 250 * Only request this with color images, as we deal with depth/stencil 251 * formats differently. */ 252 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 253 } 254 255 return isl_usage; 256} 257 258static isl_tiling_flags_t 259choose_isl_tiling_flags(const struct intel_device_info *devinfo, 260 const struct anv_image_create_info *anv_info, 261 const struct isl_drm_modifier_info *isl_mod_info, 262 bool legacy_scanout) 263{ 264 const VkImageCreateInfo *base_info = anv_info->vk_info; 265 isl_tiling_flags_t flags = 0; 266 267 assert((isl_mod_info != NULL) == 268 (base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)); 269 270 switch (base_info->tiling) { 271 default: 272 unreachable("bad VkImageTiling"); 273 case VK_IMAGE_TILING_OPTIMAL: 274 flags = ISL_TILING_ANY_MASK; 275 break; 276 case VK_IMAGE_TILING_LINEAR: 277 flags = ISL_TILING_LINEAR_BIT; 278 break; 279 case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT: 280 flags = 1 << isl_mod_info->tiling; 281 } 282 283 if (anv_info->isl_tiling_flags) { 284 assert(isl_mod_info == NULL); 285 flags &= anv_info->isl_tiling_flags; 286 } 287 288 if (legacy_scanout) { 289 isl_tiling_flags_t legacy_mask = ISL_TILING_LINEAR_BIT; 290 if (devinfo->has_tiling_uapi) 291 legacy_mask |= ISL_TILING_X_BIT; 292 flags &= legacy_mask; 293 } 294 295 assert(flags); 296 297 return flags; 298} 299 300/** 301 * Add the surface to the binding at the given offset. 302 * 303 * \see image_binding_grow() 304 */ 305static VkResult MUST_CHECK 306add_surface(struct anv_device *device, 307 struct anv_image *image, 308 struct anv_surface *surf, 309 enum anv_image_memory_binding binding, 310 uint64_t offset) 311{ 312 /* isl surface must be initialized */ 313 assert(surf->isl.size_B > 0); 314 315 return image_binding_grow(device, image, binding, offset, 316 surf->isl.size_B, 317 surf->isl.alignment_B, 318 &surf->memory_range); 319} 320 321/** 322 * Do hardware limitations require the image plane to use a shadow surface? 323 * 324 * If hardware limitations force us to use a shadow surface, then the same 325 * limitations may also constrain the tiling of the primary surface; therefore 326 * paramater @a inout_primary_tiling_flags. 327 * 328 * If the image plane is a separate stencil plane and if the user provided 329 * VkImageStencilUsageCreateInfoEXT, then @a usage must be stencilUsage. 330 * 331 * @see anv_image::planes[]::shadow_surface 332 */ 333static bool 334anv_image_plane_needs_shadow_surface(const struct intel_device_info *devinfo, 335 struct anv_format_plane plane_format, 336 VkImageTiling vk_tiling, 337 VkImageUsageFlags vk_plane_usage, 338 VkImageCreateFlags vk_create_flags, 339 isl_tiling_flags_t *inout_primary_tiling_flags) 340{ 341 if (devinfo->ver <= 8 && 342 (vk_create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) && 343 vk_tiling == VK_IMAGE_TILING_OPTIMAL) { 344 /* We must fallback to a linear surface because we may not be able to 345 * correctly handle the offsets if tiled. (On gfx9, 346 * RENDER_SURFACE_STATE::X/Y Offset are sufficient). To prevent garbage 347 * performance while texturing, we maintain a tiled shadow surface. 348 */ 349 assert(isl_format_is_compressed(plane_format.isl_format)); 350 351 if (inout_primary_tiling_flags) { 352 *inout_primary_tiling_flags = ISL_TILING_LINEAR_BIT; 353 } 354 355 return true; 356 } 357 358 if (devinfo->ver <= 7 && 359 plane_format.aspect == VK_IMAGE_ASPECT_STENCIL_BIT && 360 (vk_plane_usage & VK_IMAGE_USAGE_SAMPLED_BIT)) { 361 /* gfx7 can't sample from W-tiled surfaces. */ 362 return true; 363 } 364 365 return false; 366} 367 368bool 369anv_formats_ccs_e_compatible(const struct intel_device_info *devinfo, 370 VkImageCreateFlags create_flags, 371 VkFormat vk_format, 372 VkImageTiling vk_tiling, 373 const VkImageFormatListCreateInfoKHR *fmt_list) 374{ 375 enum isl_format format = 376 anv_get_isl_format(devinfo, vk_format, 377 VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling); 378 379 if (!isl_format_supports_ccs_e(devinfo, format)) 380 return false; 381 382 if (!(create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) 383 return true; 384 385 if (!fmt_list || fmt_list->viewFormatCount == 0) 386 return false; 387 388 for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) { 389 enum isl_format view_format = 390 anv_get_isl_format(devinfo, fmt_list->pViewFormats[i], 391 VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling); 392 393 if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format)) 394 return false; 395 } 396 397 return true; 398} 399 400/** 401 * For color images that have an auxiliary surface, request allocation for an 402 * additional buffer that mainly stores fast-clear values. Use of this buffer 403 * allows us to access the image's subresources while being aware of their 404 * fast-clear values in non-trivial cases (e.g., outside of a render pass in 405 * which a fast clear has occurred). 406 * 407 * In order to avoid having multiple clear colors for a single plane of an 408 * image (hence a single RENDER_SURFACE_STATE), we only allow fast-clears on 409 * the first slice (level 0, layer 0). At the time of our testing (Jan 17, 410 * 2018), there were no known applications which would benefit from fast- 411 * clearing more than just the first slice. 412 * 413 * The fast clear portion of the image is laid out in the following order: 414 * 415 * * 1 or 4 dwords (depending on hardware generation) for the clear color 416 * * 1 dword for the anv_fast_clear_type of the clear color 417 * * On gfx9+, 1 dword per level and layer of the image (3D levels count 418 * multiple layers) in level-major order for compression state. 419 * 420 * For the purpose of discoverability, the algorithm used to manage 421 * compression and fast-clears is described here: 422 * 423 * * On a transition from UNDEFINED or PREINITIALIZED to a defined layout, 424 * all of the values in the fast clear portion of the image are initialized 425 * to default values. 426 * 427 * * On fast-clear, the clear value is written into surface state and also 428 * into the buffer and the fast clear type is set appropriately. Both 429 * setting the fast-clear value in the buffer and setting the fast-clear 430 * type happen from the GPU using MI commands. 431 * 432 * * Whenever a render or blorp operation is performed with CCS_E, we call 433 * genX(cmd_buffer_mark_image_written) to set the compression state to 434 * true (which is represented by UINT32_MAX). 435 * 436 * * On pipeline barrier transitions, the worst-case transition is computed 437 * from the image layouts. The command streamer inspects the fast clear 438 * type and compression state dwords and constructs a predicate. The 439 * worst-case resolve is performed with the given predicate and the fast 440 * clear and compression state is set accordingly. 441 * 442 * See anv_layout_to_aux_usage and anv_layout_to_fast_clear_type functions for 443 * details on exactly what is allowed in what layouts. 444 * 445 * On gfx7-9, we do not have a concept of indirect clear colors in hardware. 446 * In order to deal with this, we have to do some clear color management. 447 * 448 * * For LOAD_OP_LOAD at the top of a renderpass, we have to copy the clear 449 * value from the buffer into the surface state with MI commands. 450 * 451 * * For any blorp operations, we pass the address to the clear value into 452 * blorp and it knows to copy the clear color. 453 */ 454static VkResult MUST_CHECK 455add_aux_state_tracking_buffer(struct anv_device *device, 456 struct anv_image *image, 457 uint32_t plane) 458{ 459 assert(image && device); 460 assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_NONE && 461 image->vk.aspects & (VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV | 462 VK_IMAGE_ASPECT_DEPTH_BIT)); 463 464 const unsigned clear_color_state_size = device->info.ver >= 10 ? 465 device->isl_dev.ss.clear_color_state_size : 466 device->isl_dev.ss.clear_value_size; 467 468 /* Clear color and fast clear type */ 469 unsigned state_size = clear_color_state_size + 4; 470 471 /* We only need to track compression on CCS_E surfaces. */ 472 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) { 473 if (image->vk.image_type == VK_IMAGE_TYPE_3D) { 474 for (uint32_t l = 0; l < image->vk.mip_levels; l++) 475 state_size += anv_minify(image->vk.extent.depth, l) * 4; 476 } else { 477 state_size += image->vk.mip_levels * image->vk.array_layers * 4; 478 } 479 } 480 481 enum anv_image_memory_binding binding = 482 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane; 483 484 if (image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID) 485 binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE; 486 487 /* We believe that 256B alignment may be sufficient, but we choose 4K due to 488 * lack of testing. And MI_LOAD/STORE operations require dword-alignment. 489 */ 490 return image_binding_grow(device, image, binding, 491 ANV_OFFSET_IMPLICIT, state_size, 4096, 492 &image->planes[plane].fast_clear_memory_range); 493} 494 495/** 496 * The return code indicates whether creation of the VkImage should continue 497 * or fail, not whether the creation of the aux surface succeeded. If the aux 498 * surface is not required (for example, by neither hardware nor DRM format 499 * modifier), then this may return VK_SUCCESS when creation of the aux surface 500 * fails. 501 * 502 * @param offset See add_surface() 503 */ 504static VkResult 505add_aux_surface_if_supported(struct anv_device *device, 506 struct anv_image *image, 507 uint32_t plane, 508 struct anv_format_plane plane_format, 509 const VkImageFormatListCreateInfoKHR *fmt_list, 510 uint64_t offset, 511 uint32_t stride, 512 isl_surf_usage_flags_t isl_extra_usage_flags) 513{ 514 VkImageAspectFlags aspect = plane_format.aspect; 515 VkResult result; 516 bool ok; 517 518 /* The aux surface must not be already added. */ 519 assert(!anv_surface_is_valid(&image->planes[plane].aux_surface)); 520 521 if ((isl_extra_usage_flags & ISL_SURF_USAGE_DISABLE_AUX_BIT)) 522 return VK_SUCCESS; 523 524 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 525 /* We don't advertise that depth buffers could be used as storage 526 * images. 527 */ 528 assert(!(image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT)); 529 530 /* Allow the user to control HiZ enabling. Disable by default on gfx7 531 * because resolves are not currently implemented pre-BDW. 532 */ 533 if (!(image->vk.usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 534 /* It will never be used as an attachment, HiZ is pointless. */ 535 return VK_SUCCESS; 536 } 537 538 if (device->info.ver == 7) { 539 anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Implement gfx7 HiZ"); 540 return VK_SUCCESS; 541 } 542 543 if (image->vk.mip_levels > 1) { 544 anv_perf_warn(VK_LOG_OBJS(&image->vk.base), "Enable multi-LOD HiZ"); 545 return VK_SUCCESS; 546 } 547 548 if (device->info.ver == 8 && image->vk.samples > 1) { 549 anv_perf_warn(VK_LOG_OBJS(&image->vk.base), 550 "Enable gfx8 multisampled HiZ"); 551 return VK_SUCCESS; 552 } 553 554 if (INTEL_DEBUG(DEBUG_NO_HIZ)) 555 return VK_SUCCESS; 556 557 ok = isl_surf_get_hiz_surf(&device->isl_dev, 558 &image->planes[plane].primary_surface.isl, 559 &image->planes[plane].aux_surface.isl); 560 if (!ok) 561 return VK_SUCCESS; 562 563 if (!isl_surf_supports_ccs(&device->isl_dev, 564 &image->planes[plane].primary_surface.isl, 565 &image->planes[plane].aux_surface.isl)) { 566 image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ; 567 } else if (image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | 568 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && 569 image->vk.samples == 1) { 570 /* If it's used as an input attachment or a texture and it's 571 * single-sampled (this is a requirement for HiZ+CCS write-through 572 * mode), use write-through mode so that we don't need to resolve 573 * before texturing. This will make depth testing a bit slower but 574 * texturing faster. 575 * 576 * TODO: This is a heuristic trade-off; we haven't tuned it at all. 577 */ 578 assert(device->info.ver >= 12); 579 image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS_WT; 580 } else { 581 assert(device->info.ver >= 12); 582 image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS; 583 } 584 585 result = add_surface(device, image, &image->planes[plane].aux_surface, 586 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane, 587 ANV_OFFSET_IMPLICIT); 588 if (result != VK_SUCCESS) 589 return result; 590 591 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT) 592 return add_aux_state_tracking_buffer(device, image, plane); 593 } else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) { 594 595 if (INTEL_DEBUG(DEBUG_NO_RBC)) 596 return VK_SUCCESS; 597 598 if (!isl_surf_supports_ccs(&device->isl_dev, 599 &image->planes[plane].primary_surface.isl, 600 NULL)) 601 return VK_SUCCESS; 602 603 image->planes[plane].aux_usage = ISL_AUX_USAGE_STC_CCS; 604 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->vk.samples == 1) { 605 if (image->n_planes != 1) { 606 /* Multiplanar images seem to hit a sampler bug with CCS and R16G16 607 * format. (Putting the clear state a page/4096bytes further fixes 608 * the issue). 609 */ 610 return VK_SUCCESS; 611 } 612 613 if ((image->vk.create_flags & VK_IMAGE_CREATE_ALIAS_BIT)) { 614 /* The image may alias a plane of a multiplanar image. Above we ban 615 * CCS on multiplanar images. 616 * 617 * We must also reject aliasing of any image that uses 618 * ANV_IMAGE_MEMORY_BINDING_PRIVATE. Since we're already rejecting all 619 * aliasing here, there's no need to further analyze if the image needs 620 * a private binding. 621 */ 622 return VK_SUCCESS; 623 } 624 625 if (!isl_format_supports_rendering(&device->info, 626 plane_format.isl_format)) { 627 /* Disable CCS because it is not useful (we can't render to the image 628 * with CCS enabled). While it may be technically possible to enable 629 * CCS for this case, we currently don't have things hooked up to get 630 * it working. 631 */ 632 anv_perf_warn(VK_LOG_OBJS(&image->vk.base), 633 "This image format doesn't support rendering. " 634 "Not allocating an CCS buffer."); 635 return VK_SUCCESS; 636 } 637 638 if (INTEL_DEBUG(DEBUG_NO_RBC)) 639 return VK_SUCCESS; 640 641 ok = isl_surf_get_ccs_surf(&device->isl_dev, 642 &image->planes[plane].primary_surface.isl, 643 NULL, 644 &image->planes[plane].aux_surface.isl, 645 stride); 646 if (!ok) 647 return VK_SUCCESS; 648 649 /* Choose aux usage */ 650 if (!(image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) && 651 anv_formats_ccs_e_compatible(&device->info, 652 image->vk.create_flags, 653 image->vk.format, 654 image->vk.tiling, 655 fmt_list)) { 656 /* For images created without MUTABLE_FORMAT_BIT set, we know that 657 * they will always be used with the original format. In particular, 658 * they will always be used with a format that supports color 659 * compression. If it's never used as a storage image, then it will 660 * only be used through the sampler or the as a render target. This 661 * means that it's safe to just leave compression on at all times for 662 * these formats. 663 */ 664 image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E; 665 } else if (device->info.ver >= 12) { 666 anv_perf_warn(VK_LOG_OBJS(&image->vk.base), 667 "The CCS_D aux mode is not yet handled on " 668 "Gfx12+. Not allocating a CCS buffer."); 669 image->planes[plane].aux_surface.isl.size_B = 0; 670 return VK_SUCCESS; 671 } else { 672 image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_D; 673 } 674 675 if (!device->physical->has_implicit_ccs) { 676 enum anv_image_memory_binding binding = 677 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane; 678 679 if (image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID && 680 !isl_drm_modifier_has_aux(image->vk.drm_format_mod)) 681 binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE; 682 683 result = add_surface(device, image, &image->planes[plane].aux_surface, 684 binding, offset); 685 if (result != VK_SUCCESS) 686 return result; 687 } 688 689 return add_aux_state_tracking_buffer(device, image, plane); 690 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->vk.samples > 1) { 691 assert(!(image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT)); 692 ok = isl_surf_get_mcs_surf(&device->isl_dev, 693 &image->planes[plane].primary_surface.isl, 694 &image->planes[plane].aux_surface.isl); 695 if (!ok) 696 return VK_SUCCESS; 697 698 image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS; 699 700 result = add_surface(device, image, &image->planes[plane].aux_surface, 701 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane, 702 ANV_OFFSET_IMPLICIT); 703 if (result != VK_SUCCESS) 704 return result; 705 706 return add_aux_state_tracking_buffer(device, image, plane); 707 } 708 709 return VK_SUCCESS; 710} 711 712static VkResult 713add_shadow_surface(struct anv_device *device, 714 struct anv_image *image, 715 uint32_t plane, 716 struct anv_format_plane plane_format, 717 uint32_t stride, 718 VkImageUsageFlags vk_plane_usage) 719{ 720 ASSERTED bool ok; 721 722 ok = isl_surf_init(&device->isl_dev, 723 &image->planes[plane].shadow_surface.isl, 724 .dim = vk_to_isl_surf_dim[image->vk.image_type], 725 .format = plane_format.isl_format, 726 .width = image->vk.extent.width, 727 .height = image->vk.extent.height, 728 .depth = image->vk.extent.depth, 729 .levels = image->vk.mip_levels, 730 .array_len = image->vk.array_layers, 731 .samples = image->vk.samples, 732 .min_alignment_B = 0, 733 .row_pitch_B = stride, 734 .usage = ISL_SURF_USAGE_TEXTURE_BIT | 735 (vk_plane_usage & ISL_SURF_USAGE_CUBE_BIT), 736 .tiling_flags = ISL_TILING_ANY_MASK); 737 738 /* isl_surf_init() will fail only if provided invalid input. Invalid input 739 * here is illegal in Vulkan. 740 */ 741 assert(ok); 742 743 return add_surface(device, image, &image->planes[plane].shadow_surface, 744 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane, 745 ANV_OFFSET_IMPLICIT); 746} 747 748/** 749 * Initialize the anv_image::*_surface selected by \a aspect. Then update the 750 * image's memory requirements (that is, the image's size and alignment). 751 * 752 * @param offset See add_surface() 753 */ 754static VkResult 755add_primary_surface(struct anv_device *device, 756 struct anv_image *image, 757 uint32_t plane, 758 struct anv_format_plane plane_format, 759 uint64_t offset, 760 uint32_t stride, 761 isl_tiling_flags_t isl_tiling_flags, 762 isl_surf_usage_flags_t isl_usage) 763{ 764 struct anv_surface *anv_surf = &image->planes[plane].primary_surface; 765 bool ok; 766 767 ok = isl_surf_init(&device->isl_dev, &anv_surf->isl, 768 .dim = vk_to_isl_surf_dim[image->vk.image_type], 769 .format = plane_format.isl_format, 770 .width = image->vk.extent.width / plane_format.denominator_scales[0], 771 .height = image->vk.extent.height / plane_format.denominator_scales[1], 772 .depth = image->vk.extent.depth, 773 .levels = image->vk.mip_levels, 774 .array_len = image->vk.array_layers, 775 .samples = image->vk.samples, 776 .min_alignment_B = 0, 777 .row_pitch_B = stride, 778 .usage = isl_usage, 779 .tiling_flags = isl_tiling_flags); 780 781 if (!ok) { 782 /* TODO: Should return 783 * VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT in come cases. 784 */ 785 return VK_ERROR_OUT_OF_DEVICE_MEMORY; 786 } 787 788 image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE; 789 790 return add_surface(device, image, anv_surf, 791 ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane, offset); 792} 793 794#ifndef NDEBUG 795static bool MUST_CHECK 796memory_range_is_aligned(struct anv_image_memory_range memory_range) 797{ 798 return anv_is_aligned(memory_range.offset, memory_range.alignment); 799} 800#endif 801 802struct check_memory_range_params { 803 struct anv_image_memory_range *accum_ranges; 804 const struct anv_surface *test_surface; 805 const struct anv_image_memory_range *test_range; 806 enum anv_image_memory_binding expect_binding; 807}; 808 809#define check_memory_range(...) \ 810 check_memory_range_s(&(struct check_memory_range_params) { __VA_ARGS__ }) 811 812static void UNUSED 813check_memory_range_s(const struct check_memory_range_params *p) 814{ 815 assert((p->test_surface == NULL) != (p->test_range == NULL)); 816 817 const struct anv_image_memory_range *test_range = 818 p->test_range ?: &p->test_surface->memory_range; 819 820 struct anv_image_memory_range *accum_range = 821 &p->accum_ranges[p->expect_binding]; 822 823 assert(test_range->binding == p->expect_binding); 824 assert(test_range->offset >= memory_range_end(*accum_range)); 825 assert(memory_range_is_aligned(*test_range)); 826 827 if (p->test_surface) { 828 assert(anv_surface_is_valid(p->test_surface)); 829 assert(p->test_surface->memory_range.alignment == 830 p->test_surface->isl.alignment_B); 831 } 832 833 memory_range_merge(accum_range, *test_range); 834} 835 836/** 837 * Validate the image's memory bindings *after* all its surfaces and memory 838 * ranges are final. 839 * 840 * For simplicity's sake, we do not validate free-form layout of the image's 841 * memory bindings. We validate the layout described in the comments of struct 842 * anv_image. 843 */ 844static void 845check_memory_bindings(const struct anv_device *device, 846 const struct anv_image *image) 847{ 848#ifdef DEBUG 849 /* As we inspect each part of the image, we merge the part's memory range 850 * into these accumulation ranges. 851 */ 852 struct anv_image_memory_range accum_ranges[ANV_IMAGE_MEMORY_BINDING_END]; 853 for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; ++i) { 854 accum_ranges[i] = (struct anv_image_memory_range) { 855 .binding = i, 856 }; 857 } 858 859 for (uint32_t p = 0; p < image->n_planes; ++p) { 860 const struct anv_image_plane *plane = &image->planes[p]; 861 862 /* The binding that must contain the plane's primary surface. */ 863 const enum anv_image_memory_binding primary_binding = image->disjoint 864 ? ANV_IMAGE_MEMORY_BINDING_PLANE_0 + p 865 : ANV_IMAGE_MEMORY_BINDING_MAIN; 866 867 /* Aliasing is incompatible with the private binding because it does not 868 * live in a VkDeviceMemory. 869 */ 870 assert(!(image->vk.create_flags & VK_IMAGE_CREATE_ALIAS_BIT) || 871 image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].memory_range.size == 0); 872 873 /* Check primary surface */ 874 check_memory_range(accum_ranges, 875 .test_surface = &plane->primary_surface, 876 .expect_binding = primary_binding); 877 878 /* Check shadow surface */ 879 if (anv_surface_is_valid(&plane->shadow_surface)) { 880 check_memory_range(accum_ranges, 881 .test_surface = &plane->shadow_surface, 882 .expect_binding = primary_binding); 883 } 884 885 /* Check aux_surface */ 886 if (anv_surface_is_valid(&plane->aux_surface)) { 887 enum anv_image_memory_binding binding = primary_binding; 888 889 if (image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID && 890 !isl_drm_modifier_has_aux(image->vk.drm_format_mod)) 891 binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE; 892 893 /* Display hardware requires that the aux surface start at 894 * a higher address than the primary surface. The 3D hardware 895 * doesn't care, but we enforce the display requirement in case 896 * the image is sent to display. 897 */ 898 check_memory_range(accum_ranges, 899 .test_surface = &plane->aux_surface, 900 .expect_binding = binding); 901 } 902 903 /* Check fast clear state */ 904 if (plane->fast_clear_memory_range.size > 0) { 905 enum anv_image_memory_binding binding = primary_binding; 906 907 if (image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID) 908 binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE; 909 910 /* We believe that 256B alignment may be sufficient, but we choose 4K 911 * due to lack of testing. And MI_LOAD/STORE operations require 912 * dword-alignment. 913 */ 914 assert(plane->fast_clear_memory_range.alignment == 4096); 915 check_memory_range(accum_ranges, 916 .test_range = &plane->fast_clear_memory_range, 917 .expect_binding = binding); 918 } 919 } 920#endif 921} 922 923/** 924 * Check that the fully-initialized anv_image is compatible with its DRM format 925 * modifier. 926 * 927 * Checking compatibility at the end of image creation is prudent, not 928 * superfluous, because usage of modifiers triggers numerous special cases 929 * throughout queries and image creation, and because 930 * vkGetPhysicalDeviceImageFormatProperties2 has difficulty detecting all 931 * incompatibilities. 932 * 933 * Return VK_ERROR_UNKNOWN if the incompatibility is difficult to detect in 934 * vkGetPhysicalDeviceImageFormatProperties2. Otherwise, assert fail. 935 * 936 * Ideally, if vkGetPhysicalDeviceImageFormatProperties2() succeeds with a given 937 * modifier, then vkCreateImage() produces an image that is compatible with the 938 * modifier. However, it is difficult to reconcile the two functions to agree 939 * due to their complexity. For example, isl_surf_get_ccs_surf() may 940 * unexpectedly fail in vkCreateImage(), eliminating the image's aux surface 941 * even when the modifier requires one. (Maybe we should reconcile the two 942 * functions despite the difficulty). 943 */ 944static VkResult MUST_CHECK 945check_drm_format_mod(const struct anv_device *device, 946 const struct anv_image *image) 947{ 948 /* Image must have a modifier if and only if it has modifier tiling. */ 949 assert((image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID) == 950 (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)); 951 952 if (image->vk.drm_format_mod == DRM_FORMAT_MOD_INVALID) 953 return VK_SUCCESS; 954 955 const struct isl_drm_modifier_info *isl_mod_info = 956 isl_drm_modifier_get_info(image->vk.drm_format_mod); 957 958 /* Driver must support the modifier. */ 959 assert(isl_drm_modifier_get_score(&device->info, isl_mod_info->modifier)); 960 961 /* Enforced by us, not the Vulkan spec. */ 962 assert(image->vk.image_type == VK_IMAGE_TYPE_2D); 963 assert(!(image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT)); 964 assert(!(image->vk.aspects & VK_IMAGE_ASPECT_STENCIL_BIT)); 965 assert(image->vk.mip_levels == 1); 966 assert(image->vk.array_layers == 1); 967 assert(image->vk.samples == 1); 968 969 for (int i = 0; i < image->n_planes; ++i) { 970 const struct anv_image_plane *plane = &image->planes[i]; 971 ASSERTED const struct isl_format_layout *isl_layout = 972 isl_format_get_layout(plane->primary_surface.isl.format); 973 974 /* Enforced by us, not the Vulkan spec. */ 975 assert(isl_layout->txc == ISL_TXC_NONE); 976 assert(isl_layout->colorspace == ISL_COLORSPACE_LINEAR || 977 isl_layout->colorspace == ISL_COLORSPACE_SRGB); 978 assert(!anv_surface_is_valid(&plane->shadow_surface)); 979 980 if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) { 981 /* Reject DISJOINT for consistency with the GL driver. */ 982 assert(!image->disjoint); 983 984 /* The modifier's required aux usage mandates the image's aux usage. 985 * The inverse, however, does not hold; if the modifier has no aux 986 * usage, then we may enable a private aux surface. 987 */ 988 if (plane->aux_usage != isl_mod_info->aux_usage) { 989 return vk_errorf(device, VK_ERROR_UNKNOWN, 990 "image with modifier unexpectedly has wrong aux " 991 "usage"); 992 } 993 } 994 } 995 996 return VK_SUCCESS; 997} 998 999/** 1000 * Use when the app does not provide 1001 * VkImageDrmFormatModifierExplicitCreateInfoEXT. 1002 */ 1003static VkResult MUST_CHECK 1004add_all_surfaces_implicit_layout( 1005 struct anv_device *device, 1006 struct anv_image *image, 1007 const VkImageFormatListCreateInfo *format_list_info, 1008 uint32_t stride, 1009 isl_tiling_flags_t isl_tiling_flags, 1010 const struct anv_image_create_info *create_info) 1011{ 1012 assert(create_info); 1013 const struct intel_device_info *devinfo = &device->info; 1014 isl_surf_usage_flags_t isl_extra_usage_flags = 1015 create_info->isl_extra_usage_flags; 1016 VkResult result; 1017 1018 u_foreach_bit(b, image->vk.aspects) { 1019 VkImageAspectFlagBits aspect = 1 << b; 1020 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 1021 const struct anv_format_plane plane_format = 1022 anv_get_format_plane(devinfo, image->vk.format, plane, image->vk.tiling); 1023 1024 VkImageUsageFlags vk_usage = vk_image_usage(&image->vk, aspect); 1025 isl_surf_usage_flags_t isl_usage = 1026 choose_isl_surf_usage(image->vk.create_flags, vk_usage, 1027 isl_extra_usage_flags, aspect); 1028 1029 /* Must call this before adding any surfaces because it may modify 1030 * isl_tiling_flags. 1031 */ 1032 bool needs_shadow = 1033 anv_image_plane_needs_shadow_surface(devinfo, plane_format, 1034 image->vk.tiling, vk_usage, 1035 image->vk.create_flags, 1036 &isl_tiling_flags); 1037 1038 result = add_primary_surface(device, image, plane, plane_format, 1039 ANV_OFFSET_IMPLICIT, stride, 1040 isl_tiling_flags, isl_usage); 1041 if (result != VK_SUCCESS) 1042 return result; 1043 1044 if (needs_shadow) { 1045 result = add_shadow_surface(device, image, plane, plane_format, 1046 stride, vk_usage); 1047 if (result != VK_SUCCESS) 1048 return result; 1049 } 1050 1051 /* Disable aux if image supports export without modifiers. */ 1052 if (image->vk.external_handle_types != 0 && 1053 image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) 1054 continue; 1055 1056 result = add_aux_surface_if_supported(device, image, plane, plane_format, 1057 format_list_info, 1058 ANV_OFFSET_IMPLICIT, stride, 1059 isl_extra_usage_flags); 1060 if (result != VK_SUCCESS) 1061 return result; 1062 } 1063 1064 return VK_SUCCESS; 1065} 1066 1067/** 1068 * Use when the app provides VkImageDrmFormatModifierExplicitCreateInfoEXT. 1069 */ 1070static VkResult 1071add_all_surfaces_explicit_layout( 1072 struct anv_device *device, 1073 struct anv_image *image, 1074 const VkImageFormatListCreateInfo *format_list_info, 1075 const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_info, 1076 isl_tiling_flags_t isl_tiling_flags, 1077 isl_surf_usage_flags_t isl_extra_usage_flags) 1078{ 1079 const struct intel_device_info *devinfo = &device->info; 1080 const uint32_t mod_plane_count = drm_info->drmFormatModifierPlaneCount; 1081 const bool mod_has_aux = 1082 isl_drm_modifier_has_aux(drm_info->drmFormatModifier); 1083 VkResult result; 1084 1085 /* About valid usage in the Vulkan spec: 1086 * 1087 * Unlike vanilla vkCreateImage, which produces undefined behavior on user 1088 * error, here the spec requires the implementation to return 1089 * VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT if the app provides 1090 * a bad plane layout. However, the spec does require 1091 * drmFormatModifierPlaneCount to be valid. 1092 * 1093 * Most validation of plane layout occurs in add_surface(). 1094 */ 1095 1096 /* We support a restricted set of images with modifiers. 1097 * 1098 * With aux usage, 1099 * - Format plane count must be 1. 1100 * - Memory plane count must be 2. 1101 * Without aux usage, 1102 * - Each format plane must map to a distint memory plane. 1103 * 1104 * For the other cases, currently there is no way to properly map memory 1105 * planes to format planes and aux planes due to the lack of defined ABI 1106 * for external multi-planar images. 1107 */ 1108 if (image->n_planes == 1) 1109 assert(image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT); 1110 else 1111 assert(!(image->vk.aspects & ~VK_IMAGE_ASPECT_PLANES_BITS_ANV)); 1112 1113 if (mod_has_aux) 1114 assert(image->n_planes == 1 && mod_plane_count == 2); 1115 else 1116 assert(image->n_planes == mod_plane_count); 1117 1118 /* Reject special values in the app-provided plane layouts. */ 1119 for (uint32_t i = 0; i < mod_plane_count; ++i) { 1120 if (drm_info->pPlaneLayouts[i].rowPitch == 0) { 1121 return vk_errorf(device, 1122 VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, 1123 "VkImageDrmFormatModifierExplicitCreateInfoEXT::" 1124 "pPlaneLayouts[%u]::rowPitch is 0", i); 1125 } 1126 1127 if (drm_info->pPlaneLayouts[i].offset == ANV_OFFSET_IMPLICIT) { 1128 return vk_errorf(device, 1129 VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT, 1130 "VkImageDrmFormatModifierExplicitCreateInfoEXT::" 1131 "pPlaneLayouts[%u]::offset is %" PRIu64, 1132 i, ANV_OFFSET_IMPLICIT); 1133 } 1134 } 1135 1136 u_foreach_bit(b, image->vk.aspects) { 1137 const VkImageAspectFlagBits aspect = 1 << b; 1138 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 1139 const struct anv_format_plane format_plane = 1140 anv_get_format_plane(devinfo, image->vk.format, plane, image->vk.tiling); 1141 const VkSubresourceLayout *primary_layout = &drm_info->pPlaneLayouts[plane]; 1142 1143 result = add_primary_surface(device, image, plane, 1144 format_plane, 1145 primary_layout->offset, 1146 primary_layout->rowPitch, 1147 isl_tiling_flags, 1148 isl_extra_usage_flags); 1149 if (result != VK_SUCCESS) 1150 return result; 1151 1152 if (!mod_has_aux) { 1153 /* Even though the modifier does not support aux, try to create 1154 * a driver-private aux to improve performance. 1155 */ 1156 result = add_aux_surface_if_supported(device, image, plane, 1157 format_plane, 1158 format_list_info, 1159 ANV_OFFSET_IMPLICIT, 0, 1160 isl_extra_usage_flags); 1161 if (result != VK_SUCCESS) 1162 return result; 1163 } else { 1164 const VkSubresourceLayout *aux_layout = &drm_info->pPlaneLayouts[1]; 1165 result = add_aux_surface_if_supported(device, image, plane, 1166 format_plane, 1167 format_list_info, 1168 aux_layout->offset, 1169 aux_layout->rowPitch, 1170 isl_extra_usage_flags); 1171 if (result != VK_SUCCESS) 1172 return result; 1173 } 1174 } 1175 1176 return VK_SUCCESS; 1177} 1178 1179static const struct isl_drm_modifier_info * 1180choose_drm_format_mod(const struct anv_physical_device *device, 1181 uint32_t modifier_count, const uint64_t *modifiers) 1182{ 1183 uint64_t best_mod = UINT64_MAX; 1184 uint32_t best_score = 0; 1185 1186 for (uint32_t i = 0; i < modifier_count; ++i) { 1187 uint32_t score = isl_drm_modifier_get_score(&device->info, modifiers[i]); 1188 if (score > best_score) { 1189 best_mod = modifiers[i]; 1190 best_score = score; 1191 } 1192 } 1193 1194 if (best_score > 0) 1195 return isl_drm_modifier_get_info(best_mod); 1196 else 1197 return NULL; 1198} 1199 1200static VkImageUsageFlags 1201anv_image_create_usage(const VkImageCreateInfo *pCreateInfo, 1202 VkImageUsageFlags usage) 1203{ 1204 /* Add TRANSFER_SRC usage for multisample attachment images. This is 1205 * because we might internally use the TRANSFER_SRC layout on them for 1206 * blorp operations associated with resolving those into other attachments 1207 * at the end of a subpass. 1208 * 1209 * Without this additional usage, we compute an incorrect AUX state in 1210 * anv_layout_to_aux_state(). 1211 */ 1212 if (pCreateInfo->samples > VK_SAMPLE_COUNT_1_BIT && 1213 (usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 1214 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))) 1215 usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT; 1216 return usage; 1217} 1218 1219static VkResult MUST_CHECK 1220alloc_private_binding(struct anv_device *device, 1221 struct anv_image *image, 1222 const VkImageCreateInfo *create_info) 1223{ 1224 struct anv_image_binding *binding = 1225 &image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE]; 1226 1227 if (binding->memory_range.size == 0) 1228 return VK_SUCCESS; 1229 1230 const VkImageSwapchainCreateInfoKHR *swapchain_info = 1231 vk_find_struct_const(create_info->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); 1232 1233 if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) { 1234 /* The image will be bound to swapchain memory. */ 1235 return VK_SUCCESS; 1236 } 1237 1238 return anv_device_alloc_bo(device, "image-binding-private", 1239 binding->memory_range.size, 0, 0, 1240 &binding->address.bo); 1241} 1242 1243VkResult 1244anv_image_init(struct anv_device *device, struct anv_image *image, 1245 const struct anv_image_create_info *create_info) 1246{ 1247 const VkImageCreateInfo *pCreateInfo = create_info->vk_info; 1248 const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_explicit_info = NULL; 1249 const struct isl_drm_modifier_info *isl_mod_info = NULL; 1250 VkResult r; 1251 1252 vk_image_init(&device->vk, &image->vk, pCreateInfo); 1253 1254 image->vk.usage = anv_image_create_usage(pCreateInfo, image->vk.usage); 1255 image->vk.stencil_usage = 1256 anv_image_create_usage(pCreateInfo, image->vk.stencil_usage); 1257 1258 if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1259 assert(!image->vk.wsi_legacy_scanout); 1260 mod_explicit_info = 1261 vk_find_struct_const(pCreateInfo->pNext, 1262 IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT); 1263 if (mod_explicit_info) { 1264 isl_mod_info = isl_drm_modifier_get_info(mod_explicit_info->drmFormatModifier); 1265 } else { 1266 const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list_info = 1267 vk_find_struct_const(pCreateInfo->pNext, 1268 IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT); 1269 isl_mod_info = choose_drm_format_mod(device->physical, 1270 mod_list_info->drmFormatModifierCount, 1271 mod_list_info->pDrmFormatModifiers); 1272 } 1273 1274 assert(isl_mod_info); 1275 assert(image->vk.drm_format_mod == DRM_FORMAT_MOD_INVALID); 1276 image->vk.drm_format_mod = isl_mod_info->modifier; 1277 } 1278 1279 for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; ++i) { 1280 image->bindings[i] = (struct anv_image_binding) { 1281 .memory_range = { .binding = i }, 1282 }; 1283 } 1284 1285 /* In case of AHardwareBuffer import, we don't know the layout yet */ 1286 if (image->vk.external_handle_types & 1287 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) { 1288 image->from_ahb = true; 1289 return VK_SUCCESS; 1290 } 1291 1292 image->n_planes = anv_get_format_planes(image->vk.format); 1293 1294 /* The Vulkan 1.2.165 glossary says: 1295 * 1296 * A disjoint image consists of multiple disjoint planes, and is created 1297 * with the VK_IMAGE_CREATE_DISJOINT_BIT bit set. 1298 */ 1299 image->disjoint = image->n_planes > 1 && 1300 (pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT); 1301 1302 const isl_tiling_flags_t isl_tiling_flags = 1303 choose_isl_tiling_flags(&device->info, create_info, isl_mod_info, 1304 image->vk.wsi_legacy_scanout); 1305 1306 const VkImageFormatListCreateInfoKHR *fmt_list = 1307 vk_find_struct_const(pCreateInfo->pNext, 1308 IMAGE_FORMAT_LIST_CREATE_INFO_KHR); 1309 1310 if (mod_explicit_info) { 1311 r = add_all_surfaces_explicit_layout(device, image, fmt_list, 1312 mod_explicit_info, isl_tiling_flags, 1313 create_info->isl_extra_usage_flags); 1314 } else { 1315 r = add_all_surfaces_implicit_layout(device, image, fmt_list, 0, 1316 isl_tiling_flags, 1317 create_info); 1318 } 1319 1320 if (r != VK_SUCCESS) 1321 goto fail; 1322 1323 r = alloc_private_binding(device, image, pCreateInfo); 1324 if (r != VK_SUCCESS) 1325 goto fail; 1326 1327 check_memory_bindings(device, image); 1328 1329 r = check_drm_format_mod(device, image); 1330 if (r != VK_SUCCESS) 1331 goto fail; 1332 1333 return VK_SUCCESS; 1334 1335fail: 1336 vk_image_finish(&image->vk); 1337 return r; 1338} 1339 1340void 1341anv_image_finish(struct anv_image *image) 1342{ 1343 struct anv_device *device = 1344 container_of(image->vk.base.device, struct anv_device, vk); 1345 1346 if (image->from_gralloc) { 1347 assert(!image->disjoint); 1348 assert(image->n_planes == 1); 1349 assert(image->planes[0].primary_surface.memory_range.binding == 1350 ANV_IMAGE_MEMORY_BINDING_MAIN); 1351 assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo != NULL); 1352 anv_device_release_bo(device, image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo); 1353 } 1354 1355 struct anv_bo *private_bo = image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address.bo; 1356 if (private_bo) 1357 anv_device_release_bo(device, private_bo); 1358 1359 vk_image_finish(&image->vk); 1360} 1361 1362static struct anv_image * 1363anv_swapchain_get_image(VkSwapchainKHR swapchain, 1364 uint32_t index) 1365{ 1366 uint32_t n_images = index + 1; 1367 VkImage *images = malloc(sizeof(*images) * n_images); 1368 VkResult result = wsi_common_get_images(swapchain, &n_images, images); 1369 1370 if (result != VK_SUCCESS && result != VK_INCOMPLETE) { 1371 free(images); 1372 return NULL; 1373 } 1374 1375 ANV_FROM_HANDLE(anv_image, image, images[index]); 1376 free(images); 1377 1378 return image; 1379} 1380 1381static VkResult 1382anv_image_init_from_swapchain(struct anv_device *device, 1383 struct anv_image *image, 1384 const VkImageCreateInfo *pCreateInfo, 1385 const VkImageSwapchainCreateInfoKHR *swapchain_info) 1386{ 1387 struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0); 1388 assert(swapchain_image); 1389 1390 VkImageCreateInfo local_create_info = *pCreateInfo; 1391 local_create_info.pNext = NULL; 1392 1393 /* Added by wsi code. */ 1394 local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 1395 1396 /* The spec requires TILING_OPTIMAL as input, but the swapchain image may 1397 * privately use a different tiling. See spec anchor 1398 * #swapchain-wsi-image-create-info . 1399 */ 1400 assert(local_create_info.tiling == VK_IMAGE_TILING_OPTIMAL); 1401 local_create_info.tiling = swapchain_image->vk.tiling; 1402 1403 VkImageDrmFormatModifierListCreateInfoEXT local_modifier_info = { 1404 .sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT, 1405 .drmFormatModifierCount = 1, 1406 .pDrmFormatModifiers = &swapchain_image->vk.drm_format_mod, 1407 }; 1408 1409 if (swapchain_image->vk.drm_format_mod != DRM_FORMAT_MOD_INVALID) 1410 __vk_append_struct(&local_create_info, &local_modifier_info); 1411 1412 assert(swapchain_image->vk.image_type == local_create_info.imageType); 1413 assert(swapchain_image->vk.format == local_create_info.format); 1414 assert(swapchain_image->vk.extent.width == local_create_info.extent.width); 1415 assert(swapchain_image->vk.extent.height == local_create_info.extent.height); 1416 assert(swapchain_image->vk.extent.depth == local_create_info.extent.depth); 1417 assert(swapchain_image->vk.array_layers == local_create_info.arrayLayers); 1418 assert(swapchain_image->vk.samples == local_create_info.samples); 1419 assert(swapchain_image->vk.tiling == local_create_info.tiling); 1420 assert(swapchain_image->vk.usage == local_create_info.usage); 1421 1422 return anv_image_init(device, image, 1423 &(struct anv_image_create_info) { 1424 .vk_info = &local_create_info, 1425 }); 1426} 1427 1428static VkResult 1429anv_image_init_from_create_info(struct anv_device *device, 1430 struct anv_image *image, 1431 const VkImageCreateInfo *pCreateInfo) 1432{ 1433 const VkNativeBufferANDROID *gralloc_info = 1434 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID); 1435 if (gralloc_info) 1436 return anv_image_init_from_gralloc(device, image, pCreateInfo, 1437 gralloc_info); 1438 1439#ifndef VK_USE_PLATFORM_ANDROID_KHR 1440 /* Ignore swapchain creation info on Android. Since we don't have an 1441 * implementation in Mesa, we're guaranteed to access an Android object 1442 * incorrectly. 1443 */ 1444 const VkImageSwapchainCreateInfoKHR *swapchain_info = 1445 vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); 1446 if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) { 1447 return anv_image_init_from_swapchain(device, image, pCreateInfo, 1448 swapchain_info); 1449 } 1450#endif 1451 1452 return anv_image_init(device, image, 1453 &(struct anv_image_create_info) { 1454 .vk_info = pCreateInfo, 1455 }); 1456} 1457 1458VkResult anv_CreateImage( 1459 VkDevice _device, 1460 const VkImageCreateInfo* pCreateInfo, 1461 const VkAllocationCallbacks* pAllocator, 1462 VkImage* pImage) 1463{ 1464 ANV_FROM_HANDLE(anv_device, device, _device); 1465 1466 struct anv_image *image = 1467 vk_object_zalloc(&device->vk, pAllocator, sizeof(*image), 1468 VK_OBJECT_TYPE_IMAGE); 1469 if (!image) 1470 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 1471 1472 VkResult result = anv_image_init_from_create_info(device, image, 1473 pCreateInfo); 1474 if (result != VK_SUCCESS) { 1475 vk_object_free(&device->vk, pAllocator, image); 1476 return result; 1477 } 1478 1479 *pImage = anv_image_to_handle(image); 1480 1481 return result; 1482} 1483 1484void 1485anv_DestroyImage(VkDevice _device, VkImage _image, 1486 const VkAllocationCallbacks *pAllocator) 1487{ 1488 ANV_FROM_HANDLE(anv_device, device, _device); 1489 ANV_FROM_HANDLE(anv_image, image, _image); 1490 1491 if (!image) 1492 return; 1493 1494 assert(&device->vk == image->vk.base.device); 1495 anv_image_finish(image); 1496 1497 vk_free2(&device->vk.alloc, pAllocator, image); 1498} 1499 1500/* We are binding AHardwareBuffer. Get a description, resolve the 1501 * format and prepare anv_image properly. 1502 */ 1503static void 1504resolve_ahw_image(struct anv_device *device, 1505 struct anv_image *image, 1506 struct anv_device_memory *mem) 1507{ 1508#if defined(ANDROID) && ANDROID_API_LEVEL >= 26 1509 assert(mem->ahw); 1510 AHardwareBuffer_Desc desc; 1511 AHardwareBuffer_describe(mem->ahw, &desc); 1512 VkResult result; 1513 1514 /* Check tiling. */ 1515 int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle); 1516 VkImageTiling vk_tiling; 1517 isl_tiling_flags_t isl_tiling_flags = 0; 1518 1519 switch (i915_tiling) { 1520 case I915_TILING_NONE: 1521 vk_tiling = VK_IMAGE_TILING_LINEAR; 1522 isl_tiling_flags = ISL_TILING_LINEAR_BIT; 1523 break; 1524 case I915_TILING_X: 1525 vk_tiling = VK_IMAGE_TILING_OPTIMAL; 1526 isl_tiling_flags = ISL_TILING_X_BIT; 1527 break; 1528 case I915_TILING_Y: 1529 vk_tiling = VK_IMAGE_TILING_OPTIMAL; 1530 isl_tiling_flags = ISL_TILING_Y0_BIT; 1531 break; 1532 case -1: 1533 default: 1534 unreachable("Invalid tiling flags."); 1535 } 1536 1537 assert(vk_tiling == VK_IMAGE_TILING_LINEAR || 1538 vk_tiling == VK_IMAGE_TILING_OPTIMAL); 1539 1540 /* Check format. */ 1541 VkFormat vk_format = vk_format_from_android(desc.format, desc.usage); 1542 enum isl_format isl_fmt = anv_get_isl_format(&device->info, 1543 vk_format, 1544 VK_IMAGE_ASPECT_COLOR_BIT, 1545 vk_tiling); 1546 assert(isl_fmt != ISL_FORMAT_UNSUPPORTED); 1547 1548 /* Handle RGB(X)->RGBA fallback. */ 1549 switch (desc.format) { 1550 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: 1551 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: 1552 if (isl_format_is_rgb(isl_fmt)) 1553 isl_fmt = isl_format_rgb_to_rgba(isl_fmt); 1554 break; 1555 } 1556 1557 /* Now we are able to fill anv_image fields properly and create 1558 * isl_surface for it. 1559 */ 1560 vk_image_set_format(&image->vk, vk_format); 1561 image->n_planes = anv_get_format_planes(image->vk.format); 1562 1563 uint32_t stride = desc.stride * 1564 (isl_format_get_layout(isl_fmt)->bpb / 8); 1565 1566 struct anv_image_create_info create_info = { 1567 .isl_extra_usage_flags = ISL_SURF_USAGE_DISABLE_AUX_BIT, 1568 }; 1569 1570 result = add_all_surfaces_implicit_layout(device, image, NULL, stride, 1571 isl_tiling_flags, 1572 &create_info); 1573 assert(result == VK_SUCCESS); 1574#endif 1575} 1576 1577void 1578anv_image_get_memory_requirements(struct anv_device *device, 1579 struct anv_image *image, 1580 VkImageAspectFlags aspects, 1581 VkMemoryRequirements2 *pMemoryRequirements) 1582{ 1583 /* The Vulkan spec (git aaed022) says: 1584 * 1585 * memoryTypeBits is a bitfield and contains one bit set for every 1586 * supported memory type for the resource. The bit `1<<i` is set if and 1587 * only if the memory type `i` in the VkPhysicalDeviceMemoryProperties 1588 * structure for the physical device is supported. 1589 * 1590 * All types are currently supported for images. 1591 */ 1592 uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1; 1593 1594 vk_foreach_struct(ext, pMemoryRequirements->pNext) { 1595 switch (ext->sType) { 1596 case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: { 1597 VkMemoryDedicatedRequirements *requirements = (void *)ext; 1598 if (image->vk.wsi_legacy_scanout || image->from_ahb) { 1599 /* If we need to set the tiling for external consumers, we need a 1600 * dedicated allocation. 1601 * 1602 * See also anv_AllocateMemory. 1603 */ 1604 requirements->prefersDedicatedAllocation = true; 1605 requirements->requiresDedicatedAllocation = true; 1606 } else { 1607 requirements->prefersDedicatedAllocation = false; 1608 requirements->requiresDedicatedAllocation = false; 1609 } 1610 break; 1611 } 1612 1613 default: 1614 anv_debug_ignored_stype(ext->sType); 1615 break; 1616 } 1617 } 1618 1619 /* If the image is disjoint, then we must return the memory requirements for 1620 * the single plane specified in VkImagePlaneMemoryRequirementsInfo. If 1621 * non-disjoint, then exactly one set of memory requirements exists for the 1622 * whole image. 1623 * 1624 * This is enforced by the Valid Usage for VkImageMemoryRequirementsInfo2, 1625 * which requires that the app provide VkImagePlaneMemoryRequirementsInfo if 1626 * and only if the image is disjoint (that is, multi-planar format and 1627 * VK_IMAGE_CREATE_DISJOINT_BIT). 1628 */ 1629 const struct anv_image_binding *binding; 1630 if (image->disjoint) { 1631 assert(util_bitcount(aspects) == 1); 1632 assert(aspects & image->vk.aspects); 1633 binding = image_aspect_to_binding(image, aspects); 1634 } else { 1635 assert(aspects == image->vk.aspects); 1636 binding = &image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN]; 1637 } 1638 1639 pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) { 1640 .size = binding->memory_range.size, 1641 .alignment = binding->memory_range.alignment, 1642 .memoryTypeBits = memory_types, 1643 }; 1644} 1645 1646void anv_GetImageMemoryRequirements2( 1647 VkDevice _device, 1648 const VkImageMemoryRequirementsInfo2* pInfo, 1649 VkMemoryRequirements2* pMemoryRequirements) 1650{ 1651 ANV_FROM_HANDLE(anv_device, device, _device); 1652 ANV_FROM_HANDLE(anv_image, image, pInfo->image); 1653 1654 VkImageAspectFlags aspects = image->vk.aspects; 1655 1656 vk_foreach_struct_const(ext, pInfo->pNext) { 1657 switch (ext->sType) { 1658 case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO: { 1659 assert(image->disjoint); 1660 const VkImagePlaneMemoryRequirementsInfo *plane_reqs = 1661 (const VkImagePlaneMemoryRequirementsInfo *) ext; 1662 aspects = plane_reqs->planeAspect; 1663 break; 1664 } 1665 1666 default: 1667 anv_debug_ignored_stype(ext->sType); 1668 break; 1669 } 1670 } 1671 1672 anv_image_get_memory_requirements(device, image, aspects, 1673 pMemoryRequirements); 1674} 1675 1676void anv_GetDeviceImageMemoryRequirementsKHR( 1677 VkDevice _device, 1678 const VkDeviceImageMemoryRequirementsKHR* pInfo, 1679 VkMemoryRequirements2* pMemoryRequirements) 1680{ 1681 ANV_FROM_HANDLE(anv_device, device, _device); 1682 struct anv_image image = { 0 }; 1683 1684 ASSERTED VkResult result = 1685 anv_image_init_from_create_info(device, &image, pInfo->pCreateInfo); 1686 assert(result == VK_SUCCESS); 1687 1688 VkImageAspectFlags aspects = 1689 image.disjoint ? pInfo->planeAspect : image.vk.aspects; 1690 1691 anv_image_get_memory_requirements(device, &image, aspects, 1692 pMemoryRequirements); 1693} 1694 1695void anv_GetImageSparseMemoryRequirements( 1696 VkDevice device, 1697 VkImage image, 1698 uint32_t* pSparseMemoryRequirementCount, 1699 VkSparseImageMemoryRequirements* pSparseMemoryRequirements) 1700{ 1701 *pSparseMemoryRequirementCount = 0; 1702} 1703 1704void anv_GetImageSparseMemoryRequirements2( 1705 VkDevice device, 1706 const VkImageSparseMemoryRequirementsInfo2* pInfo, 1707 uint32_t* pSparseMemoryRequirementCount, 1708 VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) 1709{ 1710 *pSparseMemoryRequirementCount = 0; 1711} 1712 1713void anv_GetDeviceImageSparseMemoryRequirementsKHR( 1714 VkDevice device, 1715 const VkDeviceImageMemoryRequirementsKHR* pInfo, 1716 uint32_t* pSparseMemoryRequirementCount, 1717 VkSparseImageMemoryRequirements2* pSparseMemoryRequirements) 1718{ 1719 *pSparseMemoryRequirementCount = 0; 1720} 1721 1722VkResult anv_BindImageMemory2( 1723 VkDevice _device, 1724 uint32_t bindInfoCount, 1725 const VkBindImageMemoryInfo* pBindInfos) 1726{ 1727 ANV_FROM_HANDLE(anv_device, device, _device); 1728 1729 for (uint32_t i = 0; i < bindInfoCount; i++) { 1730 const VkBindImageMemoryInfo *bind_info = &pBindInfos[i]; 1731 ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory); 1732 ANV_FROM_HANDLE(anv_image, image, bind_info->image); 1733 bool did_bind = false; 1734 1735 /* Resolve will alter the image's aspects, do this first. */ 1736 if (mem && mem->ahw) 1737 resolve_ahw_image(device, image, mem); 1738 1739 vk_foreach_struct_const(s, bind_info->pNext) { 1740 switch (s->sType) { 1741 case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: { 1742 const VkBindImagePlaneMemoryInfo *plane_info = 1743 (const VkBindImagePlaneMemoryInfo *) s; 1744 1745 /* Workaround for possible spec bug. 1746 * 1747 * Unlike VkImagePlaneMemoryRequirementsInfo, which requires that 1748 * the image be disjoint (that is, multi-planar format and 1749 * VK_IMAGE_CREATE_DISJOINT_BIT), VkBindImagePlaneMemoryInfo allows 1750 * the image to be non-disjoint and requires only that the image 1751 * have the DISJOINT flag. In this case, regardless of the value of 1752 * VkImagePlaneMemoryRequirementsInfo::planeAspect, the behavior is 1753 * the same as if VkImagePlaneMemoryRequirementsInfo were omitted. 1754 */ 1755 if (!image->disjoint) 1756 break; 1757 1758 struct anv_image_binding *binding = 1759 image_aspect_to_binding(image, plane_info->planeAspect); 1760 1761 binding->address = (struct anv_address) { 1762 .bo = mem->bo, 1763 .offset = bind_info->memoryOffset, 1764 }; 1765 1766 did_bind = true; 1767 break; 1768 } 1769 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: { 1770 /* Ignore this struct on Android, we cannot access swapchain 1771 * structures threre. 1772 */ 1773#ifndef VK_USE_PLATFORM_ANDROID_KHR 1774 const VkBindImageMemorySwapchainInfoKHR *swapchain_info = 1775 (const VkBindImageMemorySwapchainInfoKHR *) s; 1776 struct anv_image *swapchain_image = 1777 anv_swapchain_get_image(swapchain_info->swapchain, 1778 swapchain_info->imageIndex); 1779 assert(swapchain_image); 1780 assert(image->vk.aspects == swapchain_image->vk.aspects); 1781 assert(mem == NULL); 1782 1783 for (int j = 0; j < ARRAY_SIZE(image->bindings); ++j) 1784 image->bindings[j].address = swapchain_image->bindings[j].address; 1785 1786 /* We must bump the private binding's bo's refcount because, unlike the other 1787 * bindings, its lifetime is not application-managed. 1788 */ 1789 struct anv_bo *private_bo = 1790 image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address.bo; 1791 if (private_bo) 1792 anv_bo_ref(private_bo); 1793 1794 did_bind = true; 1795#endif 1796 break; 1797 } 1798#pragma GCC diagnostic push 1799#pragma GCC diagnostic ignored "-Wswitch" 1800 case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID: { 1801 const VkNativeBufferANDROID *gralloc_info = 1802 (const VkNativeBufferANDROID *)s; 1803 VkResult result = anv_image_bind_from_gralloc(device, image, 1804 gralloc_info); 1805 if (result != VK_SUCCESS) 1806 return result; 1807 did_bind = true; 1808 break; 1809 } 1810#pragma GCC diagnostic pop 1811 default: 1812 anv_debug_ignored_stype(s->sType); 1813 break; 1814 } 1815 } 1816 1817 if (!did_bind) { 1818 assert(!image->disjoint); 1819 1820 image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address = 1821 (struct anv_address) { 1822 .bo = mem->bo, 1823 .offset = bind_info->memoryOffset, 1824 }; 1825 1826 did_bind = true; 1827 } 1828 1829 /* On platforms that use implicit CCS, if the plane's bo lacks implicit 1830 * CCS then disable compression on the plane. 1831 */ 1832 for (int p = 0; p < image->n_planes; ++p) { 1833 enum anv_image_memory_binding binding = 1834 image->planes[p].primary_surface.memory_range.binding; 1835 const struct anv_bo *bo = 1836 image->bindings[binding].address.bo; 1837 1838 if (bo && !bo->has_implicit_ccs && 1839 device->physical->has_implicit_ccs) 1840 image->planes[p].aux_usage = ISL_AUX_USAGE_NONE; 1841 } 1842 } 1843 1844 return VK_SUCCESS; 1845} 1846 1847void anv_GetImageSubresourceLayout( 1848 VkDevice device, 1849 VkImage _image, 1850 const VkImageSubresource* subresource, 1851 VkSubresourceLayout* layout) 1852{ 1853 ANV_FROM_HANDLE(anv_image, image, _image); 1854 const struct anv_surface *surface; 1855 1856 assert(__builtin_popcount(subresource->aspectMask) == 1); 1857 1858 /* The Vulkan spec requires that aspectMask be 1859 * VK_IMAGE_ASPECT_MEMORY_PLANE_i_BIT_EXT if tiling is 1860 * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT. 1861 * 1862 * For swapchain images, the Vulkan spec says that every swapchain image has 1863 * tiling VK_IMAGE_TILING_OPTIMAL, but we may choose 1864 * VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT internally. Vulkan doesn't allow 1865 * vkGetImageSubresourceLayout for images with VK_IMAGE_TILING_OPTIMAL, 1866 * therefore it's invalid for the application to call this on a swapchain 1867 * image. The WSI code, however, knows when it has internally created 1868 * a swapchain image with VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT, 1869 * so it _should_ correctly use VK_IMAGE_ASPECT_MEMORY_PLANE_* in that case. 1870 * But it incorrectly uses VK_IMAGE_ASPECT_PLANE_*, so we have a temporary 1871 * workaround. 1872 */ 1873 if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) { 1874 /* TODO(chadv): Drop this workaround when WSI gets fixed. */ 1875 uint32_t mem_plane; 1876 switch (subresource->aspectMask) { 1877 case VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT: 1878 case VK_IMAGE_ASPECT_PLANE_0_BIT: 1879 mem_plane = 0; 1880 break; 1881 case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT: 1882 case VK_IMAGE_ASPECT_PLANE_1_BIT: 1883 mem_plane = 1; 1884 break; 1885 case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT: 1886 case VK_IMAGE_ASPECT_PLANE_2_BIT: 1887 mem_plane = 2; 1888 break; 1889 default: 1890 unreachable("bad VkImageAspectFlags"); 1891 } 1892 1893 if (mem_plane == 1 && isl_drm_modifier_has_aux(image->vk.drm_format_mod)) { 1894 assert(image->n_planes == 1); 1895 /* If the memory binding differs between primary and aux, then the 1896 * returned offset will be incorrect. 1897 */ 1898 assert(image->planes[0].aux_surface.memory_range.binding == 1899 image->planes[0].primary_surface.memory_range.binding); 1900 surface = &image->planes[0].aux_surface; 1901 } else { 1902 assert(mem_plane < image->n_planes); 1903 surface = &image->planes[mem_plane].primary_surface; 1904 } 1905 } else { 1906 const uint32_t plane = 1907 anv_image_aspect_to_plane(image, subresource->aspectMask); 1908 surface = &image->planes[plane].primary_surface; 1909 } 1910 1911 layout->offset = surface->memory_range.offset; 1912 layout->rowPitch = surface->isl.row_pitch_B; 1913 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl); 1914 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl); 1915 1916 if (subresource->mipLevel > 0 || subresource->arrayLayer > 0) { 1917 assert(surface->isl.tiling == ISL_TILING_LINEAR); 1918 1919 uint64_t offset_B; 1920 isl_surf_get_image_offset_B_tile_sa(&surface->isl, 1921 subresource->mipLevel, 1922 subresource->arrayLayer, 1923 0 /* logical_z_offset_px */, 1924 &offset_B, NULL, NULL); 1925 layout->offset += offset_B; 1926 layout->size = layout->rowPitch * anv_minify(image->vk.extent.height, 1927 subresource->mipLevel) * 1928 image->vk.extent.depth; 1929 } else { 1930 layout->size = surface->memory_range.size; 1931 } 1932} 1933 1934/** 1935 * This function returns the assumed isl_aux_state for a given VkImageLayout. 1936 * Because Vulkan image layouts don't map directly to isl_aux_state enums, the 1937 * returned enum is the assumed worst case. 1938 * 1939 * @param devinfo The device information of the Intel GPU. 1940 * @param image The image that may contain a collection of buffers. 1941 * @param aspect The aspect of the image to be accessed. 1942 * @param layout The current layout of the image aspect(s). 1943 * 1944 * @return The primary buffer that should be used for the given layout. 1945 */ 1946enum isl_aux_state ATTRIBUTE_PURE 1947anv_layout_to_aux_state(const struct intel_device_info * const devinfo, 1948 const struct anv_image * const image, 1949 const VkImageAspectFlagBits aspect, 1950 const VkImageLayout layout) 1951{ 1952 /* Validate the inputs. */ 1953 1954 /* The devinfo is needed as the optimal buffer varies across generations. */ 1955 assert(devinfo != NULL); 1956 1957 /* The layout of a NULL image is not properly defined. */ 1958 assert(image != NULL); 1959 1960 /* The aspect must be exactly one of the image aspects. */ 1961 assert(util_bitcount(aspect) == 1 && (aspect & image->vk.aspects)); 1962 1963 /* Determine the optimal buffer. */ 1964 1965 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 1966 1967 /* If we don't have an aux buffer then aux state makes no sense */ 1968 const enum isl_aux_usage aux_usage = image->planes[plane].aux_usage; 1969 assert(aux_usage != ISL_AUX_USAGE_NONE); 1970 1971 /* All images that use an auxiliary surface are required to be tiled. */ 1972 assert(image->planes[plane].primary_surface.isl.tiling != ISL_TILING_LINEAR); 1973 1974 /* Handle a few special cases */ 1975 switch (layout) { 1976 /* Invalid layouts */ 1977 case VK_IMAGE_LAYOUT_MAX_ENUM: 1978 unreachable("Invalid image layout."); 1979 1980 /* Undefined layouts 1981 * 1982 * The pre-initialized layout is equivalent to the undefined layout for 1983 * optimally-tiled images. We can only do color compression (CCS or HiZ) 1984 * on tiled images. 1985 */ 1986 case VK_IMAGE_LAYOUT_UNDEFINED: 1987 case VK_IMAGE_LAYOUT_PREINITIALIZED: 1988 return ISL_AUX_STATE_AUX_INVALID; 1989 1990 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: { 1991 assert(image->vk.aspects == VK_IMAGE_ASPECT_COLOR_BIT); 1992 1993 enum isl_aux_state aux_state = 1994 isl_drm_modifier_get_default_aux_state(image->vk.drm_format_mod); 1995 1996 switch (aux_state) { 1997 default: 1998 assert(!"unexpected isl_aux_state"); 1999 case ISL_AUX_STATE_AUX_INVALID: 2000 /* The modifier does not support compression. But, if we arrived 2001 * here, then we have enabled compression on it anyway, in which case 2002 * we must resolve the aux surface before we release ownership to the 2003 * presentation engine (because, having no modifier, the presentation 2004 * engine will not be aware of the aux surface). The presentation 2005 * engine will not access the aux surface (because it is unware of 2006 * it), and so the aux surface will still be resolved when we 2007 * re-acquire ownership. 2008 * 2009 * Therefore, at ownership transfers in either direction, there does 2010 * exist an aux surface despite the lack of modifier and its state is 2011 * pass-through. 2012 */ 2013 return ISL_AUX_STATE_PASS_THROUGH; 2014 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR: 2015 return ISL_AUX_STATE_COMPRESSED_NO_CLEAR; 2016 } 2017 } 2018 2019 default: 2020 break; 2021 } 2022 2023 const bool read_only = vk_image_layout_is_read_only(layout, aspect); 2024 2025 const VkImageUsageFlags image_aspect_usage = 2026 vk_image_usage(&image->vk, aspect); 2027 const VkImageUsageFlags usage = 2028 vk_image_layout_to_usage_flags(layout, aspect) & image_aspect_usage; 2029 2030 bool aux_supported = true; 2031 bool clear_supported = isl_aux_usage_has_fast_clears(aux_usage); 2032 2033 const struct isl_format_layout *fmtl = 2034 isl_format_get_layout(image->planes[plane].primary_surface.isl.format); 2035 2036 /* Disabling CCS for the following case avoids failures in: 2037 * - dEQP-VK.drm_format_modifiers.export_import.* 2038 * - dEQP-VK.synchronization* 2039 */ 2040 if (usage & (VK_IMAGE_USAGE_TRANSFER_DST_BIT | 2041 VK_IMAGE_USAGE_TRANSFER_SRC_BIT) && fmtl->bpb <= 16 && 2042 aux_usage == ISL_AUX_USAGE_CCS_E && devinfo->ver >= 12) { 2043 aux_supported = false; 2044 clear_supported = false; 2045 } 2046 2047 if ((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !read_only) { 2048 /* This image could be used as both an input attachment and a render 2049 * target (depth, stencil, or color) at the same time and this can cause 2050 * corruption. 2051 * 2052 * We currently only disable aux in this way for depth even though we 2053 * disable it for color in GL. 2054 * 2055 * TODO: Should we be disabling this in more cases? 2056 */ 2057 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT && devinfo->ver <= 9) { 2058 aux_supported = false; 2059 clear_supported = false; 2060 } 2061 } 2062 2063 if (usage & VK_IMAGE_USAGE_STORAGE_BIT) { 2064 aux_supported = false; 2065 clear_supported = false; 2066 } 2067 2068 if (usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT | 2069 VK_IMAGE_USAGE_SAMPLED_BIT | 2070 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) { 2071 switch (aux_usage) { 2072 case ISL_AUX_USAGE_HIZ: 2073 if (!anv_can_sample_with_hiz(devinfo, image)) { 2074 aux_supported = false; 2075 clear_supported = false; 2076 } 2077 break; 2078 2079 case ISL_AUX_USAGE_HIZ_CCS: 2080 aux_supported = false; 2081 clear_supported = false; 2082 break; 2083 2084 case ISL_AUX_USAGE_HIZ_CCS_WT: 2085 break; 2086 2087 case ISL_AUX_USAGE_CCS_D: 2088 aux_supported = false; 2089 clear_supported = false; 2090 break; 2091 2092 case ISL_AUX_USAGE_MCS: 2093 if (!anv_can_sample_mcs_with_clear(devinfo, image)) 2094 clear_supported = false; 2095 break; 2096 2097 case ISL_AUX_USAGE_CCS_E: 2098 case ISL_AUX_USAGE_STC_CCS: 2099 break; 2100 2101 default: 2102 unreachable("Unsupported aux usage"); 2103 } 2104 } 2105 2106 switch (aux_usage) { 2107 case ISL_AUX_USAGE_HIZ: 2108 case ISL_AUX_USAGE_HIZ_CCS: 2109 case ISL_AUX_USAGE_HIZ_CCS_WT: 2110 if (aux_supported) { 2111 assert(clear_supported); 2112 return ISL_AUX_STATE_COMPRESSED_CLEAR; 2113 } else if (read_only) { 2114 return ISL_AUX_STATE_RESOLVED; 2115 } else { 2116 return ISL_AUX_STATE_AUX_INVALID; 2117 } 2118 2119 case ISL_AUX_USAGE_CCS_D: 2120 /* We only support clear in exactly one state */ 2121 if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { 2122 assert(aux_supported); 2123 assert(clear_supported); 2124 return ISL_AUX_STATE_PARTIAL_CLEAR; 2125 } else { 2126 return ISL_AUX_STATE_PASS_THROUGH; 2127 } 2128 2129 case ISL_AUX_USAGE_CCS_E: 2130 if (aux_supported) { 2131 assert(clear_supported); 2132 return ISL_AUX_STATE_COMPRESSED_CLEAR; 2133 } else { 2134 return ISL_AUX_STATE_PASS_THROUGH; 2135 } 2136 2137 case ISL_AUX_USAGE_MCS: 2138 assert(aux_supported); 2139 if (clear_supported) { 2140 return ISL_AUX_STATE_COMPRESSED_CLEAR; 2141 } else { 2142 return ISL_AUX_STATE_COMPRESSED_NO_CLEAR; 2143 } 2144 2145 case ISL_AUX_USAGE_STC_CCS: 2146 assert(aux_supported); 2147 assert(!clear_supported); 2148 return ISL_AUX_STATE_COMPRESSED_NO_CLEAR; 2149 2150 default: 2151 unreachable("Unsupported aux usage"); 2152 } 2153} 2154 2155/** 2156 * This function determines the optimal buffer to use for a given 2157 * VkImageLayout and other pieces of information needed to make that 2158 * determination. This does not determine the optimal buffer to use 2159 * during a resolve operation. 2160 * 2161 * @param devinfo The device information of the Intel GPU. 2162 * @param image The image that may contain a collection of buffers. 2163 * @param aspect The aspect of the image to be accessed. 2164 * @param usage The usage which describes how the image will be accessed. 2165 * @param layout The current layout of the image aspect(s). 2166 * 2167 * @return The primary buffer that should be used for the given layout. 2168 */ 2169enum isl_aux_usage ATTRIBUTE_PURE 2170anv_layout_to_aux_usage(const struct intel_device_info * const devinfo, 2171 const struct anv_image * const image, 2172 const VkImageAspectFlagBits aspect, 2173 const VkImageUsageFlagBits usage, 2174 const VkImageLayout layout) 2175{ 2176 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 2177 2178 /* If there is no auxiliary surface allocated, we must use the one and only 2179 * main buffer. 2180 */ 2181 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) 2182 return ISL_AUX_USAGE_NONE; 2183 2184 enum isl_aux_state aux_state = 2185 anv_layout_to_aux_state(devinfo, image, aspect, layout); 2186 2187 switch (aux_state) { 2188 case ISL_AUX_STATE_CLEAR: 2189 unreachable("We never use this state"); 2190 2191 case ISL_AUX_STATE_PARTIAL_CLEAR: 2192 assert(image->vk.aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 2193 assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D); 2194 assert(image->vk.samples == 1); 2195 return ISL_AUX_USAGE_CCS_D; 2196 2197 case ISL_AUX_STATE_COMPRESSED_CLEAR: 2198 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR: 2199 return image->planes[plane].aux_usage; 2200 2201 case ISL_AUX_STATE_RESOLVED: 2202 /* We can only use RESOLVED in read-only layouts because any write will 2203 * either land us in AUX_INVALID or COMPRESSED_NO_CLEAR. We can do 2204 * writes in PASS_THROUGH without destroying it so that is allowed. 2205 */ 2206 assert(vk_image_layout_is_read_only(layout, aspect)); 2207 assert(util_is_power_of_two_or_zero(usage)); 2208 if (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) { 2209 /* If we have valid HiZ data and are using the image as a read-only 2210 * depth/stencil attachment, we should enable HiZ so that we can get 2211 * faster depth testing. 2212 */ 2213 return image->planes[plane].aux_usage; 2214 } else { 2215 return ISL_AUX_USAGE_NONE; 2216 } 2217 2218 case ISL_AUX_STATE_PASS_THROUGH: 2219 case ISL_AUX_STATE_AUX_INVALID: 2220 return ISL_AUX_USAGE_NONE; 2221 } 2222 2223 unreachable("Invalid isl_aux_state"); 2224} 2225 2226/** 2227 * This function returns the level of unresolved fast-clear support of the 2228 * given image in the given VkImageLayout. 2229 * 2230 * @param devinfo The device information of the Intel GPU. 2231 * @param image The image that may contain a collection of buffers. 2232 * @param aspect The aspect of the image to be accessed. 2233 * @param usage The usage which describes how the image will be accessed. 2234 * @param layout The current layout of the image aspect(s). 2235 */ 2236enum anv_fast_clear_type ATTRIBUTE_PURE 2237anv_layout_to_fast_clear_type(const struct intel_device_info * const devinfo, 2238 const struct anv_image * const image, 2239 const VkImageAspectFlagBits aspect, 2240 const VkImageLayout layout) 2241{ 2242 if (INTEL_DEBUG(DEBUG_NO_FAST_CLEAR)) 2243 return ANV_FAST_CLEAR_NONE; 2244 2245 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 2246 2247 /* If there is no auxiliary surface allocated, there are no fast-clears */ 2248 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) 2249 return ANV_FAST_CLEAR_NONE; 2250 2251 /* We don't support MSAA fast-clears on Ivybridge or Bay Trail because they 2252 * lack the MI ALU which we need to determine the predicates. 2253 */ 2254 if (devinfo->verx10 == 70 && image->vk.samples > 1) 2255 return ANV_FAST_CLEAR_NONE; 2256 2257 enum isl_aux_state aux_state = 2258 anv_layout_to_aux_state(devinfo, image, aspect, layout); 2259 2260 switch (aux_state) { 2261 case ISL_AUX_STATE_CLEAR: 2262 unreachable("We never use this state"); 2263 2264 case ISL_AUX_STATE_PARTIAL_CLEAR: 2265 case ISL_AUX_STATE_COMPRESSED_CLEAR: 2266 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 2267 return ANV_FAST_CLEAR_DEFAULT_VALUE; 2268 } else if (devinfo->ver >= 12 && 2269 image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) { 2270 /* On TGL, if a block of fragment shader outputs match the surface's 2271 * clear color, the HW may convert them to fast-clears (see HSD 2272 * 14010672564). This can lead to rendering corruptions if not 2273 * handled properly. We restrict the clear color to zero to avoid 2274 * issues that can occur with: 2275 * - Texture view rendering (including blorp_copy calls) 2276 * - Images with multiple levels or array layers 2277 */ 2278 return ANV_FAST_CLEAR_DEFAULT_VALUE; 2279 } else if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) { 2280 /* When we're in a render pass we have the clear color data from the 2281 * VkRenderPassBeginInfo and we can use arbitrary clear colors. They 2282 * must get partially resolved before we leave the render pass. 2283 */ 2284 return ANV_FAST_CLEAR_ANY; 2285 } else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS || 2286 image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) { 2287 if (devinfo->ver >= 11) { 2288 /* On ICL and later, the sampler hardware uses a copy of the clear 2289 * value that is encoded as a pixel value. Therefore, we can use 2290 * any clear color we like for sampling. 2291 */ 2292 return ANV_FAST_CLEAR_ANY; 2293 } else { 2294 /* If the image has MCS or CCS_E enabled all the time then we can 2295 * use fast-clear as long as the clear color is the default value 2296 * of zero since this is the default value we program into every 2297 * surface state used for texturing. 2298 */ 2299 return ANV_FAST_CLEAR_DEFAULT_VALUE; 2300 } 2301 } else { 2302 return ANV_FAST_CLEAR_NONE; 2303 } 2304 2305 case ISL_AUX_STATE_COMPRESSED_NO_CLEAR: 2306 case ISL_AUX_STATE_RESOLVED: 2307 case ISL_AUX_STATE_PASS_THROUGH: 2308 case ISL_AUX_STATE_AUX_INVALID: 2309 return ANV_FAST_CLEAR_NONE; 2310 } 2311 2312 unreachable("Invalid isl_aux_state"); 2313} 2314 2315 2316static struct anv_state 2317alloc_surface_state(struct anv_device *device) 2318{ 2319 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64); 2320} 2321 2322static enum isl_channel_select 2323remap_swizzle(VkComponentSwizzle swizzle, 2324 struct isl_swizzle format_swizzle) 2325{ 2326 switch (swizzle) { 2327 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO; 2328 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE; 2329 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r; 2330 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g; 2331 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b; 2332 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a; 2333 default: 2334 unreachable("Invalid swizzle"); 2335 } 2336} 2337 2338void 2339anv_image_fill_surface_state(struct anv_device *device, 2340 const struct anv_image *image, 2341 VkImageAspectFlagBits aspect, 2342 const struct isl_view *view_in, 2343 isl_surf_usage_flags_t view_usage, 2344 enum isl_aux_usage aux_usage, 2345 const union isl_color_value *clear_color, 2346 enum anv_image_view_state_flags flags, 2347 struct anv_surface_state *state_inout, 2348 struct brw_image_param *image_param_out) 2349{ 2350 const uint32_t plane = anv_image_aspect_to_plane(image, aspect); 2351 2352 const struct anv_surface *surface = &image->planes[plane].primary_surface, 2353 *aux_surface = &image->planes[plane].aux_surface; 2354 2355 struct isl_view view = *view_in; 2356 view.usage |= view_usage; 2357 2358 /* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a 2359 * compressed surface with a shadow surface, we use the shadow instead of 2360 * the primary surface. The shadow surface will be tiled, unlike the main 2361 * surface, so it should get significantly better performance. 2362 */ 2363 if (anv_surface_is_valid(&image->planes[plane].shadow_surface) && 2364 isl_format_is_compressed(view.format) && 2365 (flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) { 2366 assert(isl_format_is_compressed(surface->isl.format)); 2367 assert(surface->isl.tiling == ISL_TILING_LINEAR); 2368 assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR); 2369 surface = &image->planes[plane].shadow_surface; 2370 } 2371 2372 /* For texturing from stencil on gfx7, we have to sample from a shadow 2373 * surface because we don't support W-tiling in the sampler. 2374 */ 2375 if (anv_surface_is_valid(&image->planes[plane].shadow_surface) && 2376 aspect == VK_IMAGE_ASPECT_STENCIL_BIT) { 2377 assert(device->info.ver == 7); 2378 assert(view_usage & ISL_SURF_USAGE_TEXTURE_BIT); 2379 surface = &image->planes[plane].shadow_surface; 2380 } 2381 2382 if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT) 2383 view.swizzle = anv_swizzle_for_render(view.swizzle); 2384 2385 /* On Ivy Bridge and Bay Trail we do the swizzle in the shader */ 2386 if (device->info.verx10 == 70) 2387 view.swizzle = ISL_SWIZZLE_IDENTITY; 2388 2389 /* If this is a HiZ buffer we can sample from with a programmable clear 2390 * value (SKL+), define the clear value to the optimal constant. 2391 */ 2392 union isl_color_value default_clear_color = { .u32 = { 0, } }; 2393 if (device->info.ver >= 9 && aspect == VK_IMAGE_ASPECT_DEPTH_BIT) 2394 default_clear_color.f32[0] = ANV_HZ_FC_VAL; 2395 if (!clear_color) 2396 clear_color = &default_clear_color; 2397 2398 const struct anv_address address = 2399 anv_image_address(image, &surface->memory_range); 2400 2401 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && 2402 (flags & ANV_IMAGE_VIEW_STATE_STORAGE_LOWERED) && 2403 !isl_has_matching_typed_storage_image_format(&device->info, 2404 view.format)) { 2405 /* In this case, we are a writeable storage buffer which needs to be 2406 * lowered to linear. All tiling and offset calculations will be done in 2407 * the shader. 2408 */ 2409 assert(aux_usage == ISL_AUX_USAGE_NONE); 2410 isl_buffer_fill_state(&device->isl_dev, state_inout->state.map, 2411 .address = anv_address_physical(address), 2412 .size_B = surface->isl.size_B, 2413 .format = ISL_FORMAT_RAW, 2414 .swizzle = ISL_SWIZZLE_IDENTITY, 2415 .stride_B = 1, 2416 .mocs = anv_mocs(device, address.bo, view_usage)); 2417 state_inout->address = address, 2418 state_inout->aux_address = ANV_NULL_ADDRESS; 2419 state_inout->clear_address = ANV_NULL_ADDRESS; 2420 } else { 2421 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && 2422 (flags & ANV_IMAGE_VIEW_STATE_STORAGE_LOWERED)) { 2423 /* Typed surface reads support a very limited subset of the shader 2424 * image formats. Translate it into the closest format the hardware 2425 * supports. 2426 */ 2427 assert(aux_usage == ISL_AUX_USAGE_NONE); 2428 view.format = isl_lower_storage_image_format(&device->info, 2429 view.format); 2430 } 2431 2432 const struct isl_surf *isl_surf = &surface->isl; 2433 2434 struct isl_surf tmp_surf; 2435 uint64_t offset_B = 0; 2436 uint32_t tile_x_sa = 0, tile_y_sa = 0; 2437 if (isl_format_is_compressed(surface->isl.format) && 2438 !isl_format_is_compressed(view.format)) { 2439 /* We're creating an uncompressed view of a compressed surface. This 2440 * is allowed but only for a single level/layer. 2441 */ 2442 assert(surface->isl.samples == 1); 2443 assert(view.levels == 1); 2444 assert(view.array_len == 1); 2445 2446 ASSERTED bool ok = 2447 isl_surf_get_uncompressed_surf(&device->isl_dev, isl_surf, &view, 2448 &tmp_surf, &view, 2449 &offset_B, &tile_x_sa, &tile_y_sa); 2450 assert(ok); 2451 isl_surf = &tmp_surf; 2452 2453 if (device->info.ver <= 8) { 2454 assert(surface->isl.tiling == ISL_TILING_LINEAR); 2455 assert(tile_x_sa == 0); 2456 assert(tile_y_sa == 0); 2457 } 2458 } 2459 2460 state_inout->address = anv_address_add(address, offset_B); 2461 2462 struct anv_address aux_address = ANV_NULL_ADDRESS; 2463 if (aux_usage != ISL_AUX_USAGE_NONE) 2464 aux_address = anv_image_address(image, &aux_surface->memory_range); 2465 state_inout->aux_address = aux_address; 2466 2467 struct anv_address clear_address = ANV_NULL_ADDRESS; 2468 if (device->info.ver >= 10 && isl_aux_usage_has_fast_clears(aux_usage)) { 2469 clear_address = anv_image_get_clear_color_addr(device, image, aspect); 2470 } 2471 state_inout->clear_address = clear_address; 2472 2473 isl_surf_fill_state(&device->isl_dev, state_inout->state.map, 2474 .surf = isl_surf, 2475 .view = &view, 2476 .address = anv_address_physical(state_inout->address), 2477 .clear_color = *clear_color, 2478 .aux_surf = &aux_surface->isl, 2479 .aux_usage = aux_usage, 2480 .aux_address = anv_address_physical(aux_address), 2481 .clear_address = anv_address_physical(clear_address), 2482 .use_clear_address = !anv_address_is_null(clear_address), 2483 .mocs = anv_mocs(device, state_inout->address.bo, 2484 view_usage), 2485 .x_offset_sa = tile_x_sa, 2486 .y_offset_sa = tile_y_sa); 2487 2488 /* With the exception of gfx8, the bottom 12 bits of the MCS base address 2489 * are used to store other information. This should be ok, however, 2490 * because the surface buffer addresses are always 4K page aligned. 2491 */ 2492 if (!anv_address_is_null(aux_address)) { 2493 uint32_t *aux_addr_dw = state_inout->state.map + 2494 device->isl_dev.ss.aux_addr_offset; 2495 assert((aux_address.offset & 0xfff) == 0); 2496 state_inout->aux_address.offset |= *aux_addr_dw & 0xfff; 2497 } 2498 2499 if (device->info.ver >= 10 && clear_address.bo) { 2500 uint32_t *clear_addr_dw = state_inout->state.map + 2501 device->isl_dev.ss.clear_color_state_offset; 2502 assert((clear_address.offset & 0x3f) == 0); 2503 state_inout->clear_address.offset |= *clear_addr_dw & 0x3f; 2504 } 2505 } 2506 2507 if (image_param_out) { 2508 assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT); 2509 isl_surf_fill_image_param(&device->isl_dev, image_param_out, 2510 &surface->isl, &view); 2511 } 2512} 2513 2514static uint32_t 2515anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask) 2516{ 2517 anv_assert_valid_aspect_set(aspect_mask); 2518 return util_bitcount(aspect_mask); 2519} 2520 2521VkResult 2522anv_CreateImageView(VkDevice _device, 2523 const VkImageViewCreateInfo *pCreateInfo, 2524 const VkAllocationCallbacks *pAllocator, 2525 VkImageView *pView) 2526{ 2527 ANV_FROM_HANDLE(anv_device, device, _device); 2528 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); 2529 struct anv_image_view *iview; 2530 2531 iview = vk_image_view_create(&device->vk, pCreateInfo, 2532 pAllocator, sizeof(*iview)); 2533 if (iview == NULL) 2534 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2535 2536 iview->image = image; 2537 iview->n_planes = anv_image_aspect_get_planes(iview->vk.aspects); 2538 2539 /* Check if a conversion info was passed. */ 2540 const struct anv_format *conv_format = NULL; 2541 const VkSamplerYcbcrConversionInfo *conv_info = 2542 vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO); 2543 2544#ifdef ANDROID 2545 /* If image has an external format, the pNext chain must contain an 2546 * instance of VKSamplerYcbcrConversionInfo with a conversion object 2547 * created with the same external format as image." 2548 */ 2549 assert(!image->vk.android_external_format || conv_info); 2550#endif 2551 2552 if (conv_info) { 2553 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion); 2554 conv_format = conversion->format; 2555 } 2556 2557#ifdef ANDROID 2558 /* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */ 2559 assert(!image->vk.android_external_format || 2560 pCreateInfo->format == VK_FORMAT_UNDEFINED); 2561#endif 2562 2563 /* Format is undefined, this can happen when using external formats. Set 2564 * view format from the passed conversion info. 2565 */ 2566 if (iview->vk.format == VK_FORMAT_UNDEFINED && conv_format) 2567 iview->vk.format = conv_format->vk_format; 2568 2569 /* Now go through the underlying image selected planes and map them to 2570 * planes in the image view. 2571 */ 2572 anv_foreach_image_aspect_bit(iaspect_bit, image, iview->vk.aspects) { 2573 const uint32_t iplane = 2574 anv_aspect_to_plane(image->vk.aspects, 1UL << iaspect_bit); 2575 const uint32_t vplane = 2576 anv_aspect_to_plane(iview->vk.aspects, 1UL << iaspect_bit); 2577 struct anv_format_plane format; 2578 format = anv_get_format_plane(&device->info, iview->vk.format, 2579 vplane, image->vk.tiling); 2580 2581 iview->planes[vplane].image_plane = iplane; 2582 2583 iview->planes[vplane].isl = (struct isl_view) { 2584 .format = format.isl_format, 2585 .base_level = iview->vk.base_mip_level, 2586 .levels = iview->vk.level_count, 2587 .base_array_layer = iview->vk.base_array_layer, 2588 .array_len = iview->vk.layer_count, 2589 .swizzle = { 2590 .r = remap_swizzle(iview->vk.swizzle.r, format.swizzle), 2591 .g = remap_swizzle(iview->vk.swizzle.g, format.swizzle), 2592 .b = remap_swizzle(iview->vk.swizzle.b, format.swizzle), 2593 .a = remap_swizzle(iview->vk.swizzle.a, format.swizzle), 2594 }, 2595 }; 2596 2597 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) { 2598 iview->planes[vplane].isl.base_array_layer = 0; 2599 iview->planes[vplane].isl.array_len = iview->vk.extent.depth; 2600 } 2601 2602 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE || 2603 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { 2604 iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT; 2605 } else { 2606 iview->planes[vplane].isl.usage = 0; 2607 } 2608 2609 if (iview->vk.usage & VK_IMAGE_USAGE_SAMPLED_BIT || 2610 (iview->vk.usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT && 2611 !(iview->vk.aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV))) { 2612 iview->planes[vplane].optimal_sampler_surface_state.state = alloc_surface_state(device); 2613 iview->planes[vplane].general_sampler_surface_state.state = alloc_surface_state(device); 2614 2615 enum isl_aux_usage general_aux_usage = 2616 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit, 2617 VK_IMAGE_USAGE_SAMPLED_BIT, 2618 VK_IMAGE_LAYOUT_GENERAL); 2619 enum isl_aux_usage optimal_aux_usage = 2620 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit, 2621 VK_IMAGE_USAGE_SAMPLED_BIT, 2622 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 2623 2624 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 2625 &iview->planes[vplane].isl, 2626 ISL_SURF_USAGE_TEXTURE_BIT, 2627 optimal_aux_usage, NULL, 2628 ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL, 2629 &iview->planes[vplane].optimal_sampler_surface_state, 2630 NULL); 2631 2632 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 2633 &iview->planes[vplane].isl, 2634 ISL_SURF_USAGE_TEXTURE_BIT, 2635 general_aux_usage, NULL, 2636 0, 2637 &iview->planes[vplane].general_sampler_surface_state, 2638 NULL); 2639 } 2640 2641 /* NOTE: This one needs to go last since it may stomp isl_view.format */ 2642 if (iview->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) { 2643 iview->planes[vplane].storage_surface_state.state = alloc_surface_state(device); 2644 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 2645 &iview->planes[vplane].isl, 2646 ISL_SURF_USAGE_STORAGE_BIT, 2647 ISL_AUX_USAGE_NONE, NULL, 2648 0, 2649 &iview->planes[vplane].storage_surface_state, 2650 NULL); 2651 2652 if (isl_is_storage_image_format(format.isl_format)) { 2653 iview->planes[vplane].lowered_storage_surface_state.state = 2654 alloc_surface_state(device); 2655 2656 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 2657 &iview->planes[vplane].isl, 2658 ISL_SURF_USAGE_STORAGE_BIT, 2659 ISL_AUX_USAGE_NONE, NULL, 2660 ANV_IMAGE_VIEW_STATE_STORAGE_LOWERED, 2661 &iview->planes[vplane].lowered_storage_surface_state, 2662 &iview->planes[vplane].lowered_storage_image_param); 2663 } else { 2664 /* In this case, we support the format but, because there's no 2665 * SPIR-V format specifier corresponding to it, we only support it 2666 * if the hardware can do it natively. This is possible for some 2667 * reads but for most writes. Instead of hanging if someone gets 2668 * it wrong, we give them a NULL descriptor. 2669 */ 2670 assert(isl_format_supports_typed_writes(&device->info, 2671 format.isl_format)); 2672 iview->planes[vplane].lowered_storage_surface_state.state = 2673 device->null_surface_state; 2674 } 2675 } 2676 } 2677 2678 *pView = anv_image_view_to_handle(iview); 2679 2680 return VK_SUCCESS; 2681} 2682 2683void 2684anv_DestroyImageView(VkDevice _device, VkImageView _iview, 2685 const VkAllocationCallbacks *pAllocator) 2686{ 2687 ANV_FROM_HANDLE(anv_device, device, _device); 2688 ANV_FROM_HANDLE(anv_image_view, iview, _iview); 2689 2690 if (!iview) 2691 return; 2692 2693 for (uint32_t plane = 0; plane < iview->n_planes; plane++) { 2694 /* Check offset instead of alloc_size because this they might be 2695 * device->null_surface_state which always has offset == 0. We don't 2696 * own that one so we don't want to accidentally free it. 2697 */ 2698 if (iview->planes[plane].optimal_sampler_surface_state.state.offset) { 2699 anv_state_pool_free(&device->surface_state_pool, 2700 iview->planes[plane].optimal_sampler_surface_state.state); 2701 } 2702 2703 if (iview->planes[plane].general_sampler_surface_state.state.offset) { 2704 anv_state_pool_free(&device->surface_state_pool, 2705 iview->planes[plane].general_sampler_surface_state.state); 2706 } 2707 2708 if (iview->planes[plane].storage_surface_state.state.offset) { 2709 anv_state_pool_free(&device->surface_state_pool, 2710 iview->planes[plane].storage_surface_state.state); 2711 } 2712 2713 if (iview->planes[plane].lowered_storage_surface_state.state.offset) { 2714 anv_state_pool_free(&device->surface_state_pool, 2715 iview->planes[plane].lowered_storage_surface_state.state); 2716 } 2717 } 2718 2719 vk_image_view_destroy(&device->vk, pAllocator, &iview->vk); 2720} 2721 2722 2723VkResult 2724anv_CreateBufferView(VkDevice _device, 2725 const VkBufferViewCreateInfo *pCreateInfo, 2726 const VkAllocationCallbacks *pAllocator, 2727 VkBufferView *pView) 2728{ 2729 ANV_FROM_HANDLE(anv_device, device, _device); 2730 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer); 2731 struct anv_buffer_view *view; 2732 2733 view = vk_object_alloc(&device->vk, pAllocator, sizeof(*view), 2734 VK_OBJECT_TYPE_BUFFER_VIEW); 2735 if (!view) 2736 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 2737 2738 /* TODO: Handle the format swizzle? */ 2739 2740 view->format = anv_get_isl_format(&device->info, pCreateInfo->format, 2741 VK_IMAGE_ASPECT_COLOR_BIT, 2742 VK_IMAGE_TILING_LINEAR); 2743 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8; 2744 view->range = anv_buffer_get_range(buffer, pCreateInfo->offset, 2745 pCreateInfo->range); 2746 view->range = align_down_npot_u32(view->range, format_bs); 2747 2748 view->address = anv_address_add(buffer->address, pCreateInfo->offset); 2749 2750 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { 2751 view->surface_state = alloc_surface_state(device); 2752 2753 anv_fill_buffer_surface_state(device, view->surface_state, 2754 view->format, ISL_SURF_USAGE_TEXTURE_BIT, 2755 view->address, view->range, format_bs); 2756 } else { 2757 view->surface_state = (struct anv_state){ 0 }; 2758 } 2759 2760 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { 2761 view->storage_surface_state = alloc_surface_state(device); 2762 view->lowered_storage_surface_state = alloc_surface_state(device); 2763 2764 anv_fill_buffer_surface_state(device, view->storage_surface_state, 2765 view->format, ISL_SURF_USAGE_STORAGE_BIT, 2766 view->address, view->range, 2767 isl_format_get_layout(view->format)->bpb / 8); 2768 2769 enum isl_format lowered_format = 2770 isl_has_matching_typed_storage_image_format(&device->info, 2771 view->format) ? 2772 isl_lower_storage_image_format(&device->info, view->format) : 2773 ISL_FORMAT_RAW; 2774 2775 anv_fill_buffer_surface_state(device, view->lowered_storage_surface_state, 2776 lowered_format, ISL_SURF_USAGE_STORAGE_BIT, 2777 view->address, view->range, 2778 (lowered_format == ISL_FORMAT_RAW ? 1 : 2779 isl_format_get_layout(lowered_format)->bpb / 8)); 2780 2781 isl_buffer_fill_image_param(&device->isl_dev, 2782 &view->lowered_storage_image_param, 2783 view->format, view->range); 2784 } else { 2785 view->storage_surface_state = (struct anv_state){ 0 }; 2786 view->lowered_storage_surface_state = (struct anv_state){ 0 }; 2787 } 2788 2789 *pView = anv_buffer_view_to_handle(view); 2790 2791 return VK_SUCCESS; 2792} 2793 2794void 2795anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, 2796 const VkAllocationCallbacks *pAllocator) 2797{ 2798 ANV_FROM_HANDLE(anv_device, device, _device); 2799 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView); 2800 2801 if (!view) 2802 return; 2803 2804 if (view->surface_state.alloc_size > 0) 2805 anv_state_pool_free(&device->surface_state_pool, 2806 view->surface_state); 2807 2808 if (view->storage_surface_state.alloc_size > 0) 2809 anv_state_pool_free(&device->surface_state_pool, 2810 view->storage_surface_state); 2811 2812 if (view->lowered_storage_surface_state.alloc_size > 0) 2813 anv_state_pool_free(&device->surface_state_pool, 2814 view->lowered_storage_surface_state); 2815 2816 vk_object_free(&device->vk, pAllocator, view); 2817} 2818