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_info.h" 38 39static isl_surf_usage_flags_t 40choose_isl_surf_usage(VkImageCreateFlags vk_create_flags, 41 VkImageUsageFlags vk_usage, 42 isl_surf_usage_flags_t isl_extra_usage, 43 VkImageAspectFlagBits aspect) 44{ 45 isl_surf_usage_flags_t isl_usage = isl_extra_usage; 46 47 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) 48 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 49 50 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) 51 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 52 53 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 54 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 55 56 if (vk_create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 57 isl_usage |= ISL_SURF_USAGE_CUBE_BIT; 58 59 /* Even if we're only using it for transfer operations, clears to depth and 60 * stencil images happen as depth and stencil so they need the right ISL 61 * usage bits or else things will fall apart. 62 */ 63 switch (aspect) { 64 case VK_IMAGE_ASPECT_DEPTH_BIT: 65 isl_usage |= ISL_SURF_USAGE_DEPTH_BIT; 66 break; 67 case VK_IMAGE_ASPECT_STENCIL_BIT: 68 isl_usage |= ISL_SURF_USAGE_STENCIL_BIT; 69 break; 70 case VK_IMAGE_ASPECT_COLOR_BIT: 71 case VK_IMAGE_ASPECT_PLANE_0_BIT: 72 case VK_IMAGE_ASPECT_PLANE_1_BIT: 73 case VK_IMAGE_ASPECT_PLANE_2_BIT: 74 break; 75 default: 76 unreachable("bad VkImageAspect"); 77 } 78 79 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 80 /* blorp implements transfers by sampling from the source image. */ 81 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 82 } 83 84 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT && 85 aspect == VK_IMAGE_ASPECT_COLOR_BIT) { 86 /* blorp implements transfers by rendering into the destination image. 87 * Only request this with color images, as we deal with depth/stencil 88 * formats differently. */ 89 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 90 } 91 92 return isl_usage; 93} 94 95static isl_tiling_flags_t 96choose_isl_tiling_flags(const struct anv_image_create_info *anv_info, 97 const struct isl_drm_modifier_info *isl_mod_info, 98 bool legacy_scanout) 99{ 100 const VkImageCreateInfo *base_info = anv_info->vk_info; 101 isl_tiling_flags_t flags = 0; 102 103 switch (base_info->tiling) { 104 default: 105 unreachable("bad VkImageTiling"); 106 case VK_IMAGE_TILING_OPTIMAL: 107 flags = ISL_TILING_ANY_MASK; 108 break; 109 case VK_IMAGE_TILING_LINEAR: 110 flags = ISL_TILING_LINEAR_BIT; 111 break; 112 } 113 114 if (anv_info->isl_tiling_flags) 115 flags &= anv_info->isl_tiling_flags; 116 117 if (legacy_scanout) 118 flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT; 119 120 if (isl_mod_info) 121 flags &= 1 << isl_mod_info->tiling; 122 123 assert(flags); 124 125 return flags; 126} 127 128static struct anv_surface * 129get_surface(struct anv_image *image, VkImageAspectFlagBits aspect) 130{ 131 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); 132 return &image->planes[plane].surface; 133} 134 135static void 136add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane) 137{ 138 assert(surf->isl.size_B > 0); /* isl surface must be initialized */ 139 140 if (image->disjoint) { 141 surf->offset = align_u32(image->planes[plane].size, 142 surf->isl.alignment_B); 143 /* Plane offset is always 0 when it's disjoint. */ 144 } else { 145 surf->offset = align_u32(image->size, surf->isl.alignment_B); 146 /* Determine plane's offset only once when the first surface is added. */ 147 if (image->planes[plane].size == 0) 148 image->planes[plane].offset = image->size; 149 } 150 151 image->size = surf->offset + surf->isl.size_B; 152 image->planes[plane].size = (surf->offset + surf->isl.size_B) - image->planes[plane].offset; 153 154 image->alignment = MAX2(image->alignment, surf->isl.alignment_B); 155 image->planes[plane].alignment = MAX2(image->planes[plane].alignment, 156 surf->isl.alignment_B); 157} 158 159 160static bool 161all_formats_ccs_e_compatible(const struct gen_device_info *devinfo, 162 const VkImageFormatListCreateInfoKHR *fmt_list, 163 struct anv_image *image) 164{ 165 enum isl_format format = 166 anv_get_isl_format(devinfo, image->vk_format, 167 VK_IMAGE_ASPECT_COLOR_BIT, image->tiling); 168 169 if (!isl_format_supports_ccs_e(devinfo, format)) 170 return false; 171 172 if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT)) 173 return true; 174 175 if (!fmt_list || fmt_list->viewFormatCount == 0) 176 return false; 177 178 for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) { 179 enum isl_format view_format = 180 anv_get_isl_format(devinfo, fmt_list->pViewFormats[i], 181 VK_IMAGE_ASPECT_COLOR_BIT, image->tiling); 182 183 if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format)) 184 return false; 185 } 186 187 return true; 188} 189 190/** 191 * For color images that have an auxiliary surface, request allocation for an 192 * additional buffer that mainly stores fast-clear values. Use of this buffer 193 * allows us to access the image's subresources while being aware of their 194 * fast-clear values in non-trivial cases (e.g., outside of a render pass in 195 * which a fast clear has occurred). 196 * 197 * In order to avoid having multiple clear colors for a single plane of an 198 * image (hence a single RENDER_SURFACE_STATE), we only allow fast-clears on 199 * the first slice (level 0, layer 0). At the time of our testing (Jan 17, 200 * 2018), there were no known applications which would benefit from fast- 201 * clearing more than just the first slice. 202 * 203 * The fast clear portion of the image is laid out in the following order: 204 * 205 * * 1 or 4 dwords (depending on hardware generation) for the clear color 206 * * 1 dword for the anv_fast_clear_type of the clear color 207 * * On gen9+, 1 dword per level and layer of the image (3D levels count 208 * multiple layers) in level-major order for compression state. 209 * 210 * For the purpose of discoverability, the algorithm used to manage 211 * compression and fast-clears is described here: 212 * 213 * * On a transition from UNDEFINED or PREINITIALIZED to a defined layout, 214 * all of the values in the fast clear portion of the image are initialized 215 * to default values. 216 * 217 * * On fast-clear, the clear value is written into surface state and also 218 * into the buffer and the fast clear type is set appropriately. Both 219 * setting the fast-clear value in the buffer and setting the fast-clear 220 * type happen from the GPU using MI commands. 221 * 222 * * Whenever a render or blorp operation is performed with CCS_E, we call 223 * genX(cmd_buffer_mark_image_written) to set the compression state to 224 * true (which is represented by UINT32_MAX). 225 * 226 * * On pipeline barrier transitions, the worst-case transition is computed 227 * from the image layouts. The command streamer inspects the fast clear 228 * type and compression state dwords and constructs a predicate. The 229 * worst-case resolve is performed with the given predicate and the fast 230 * clear and compression state is set accordingly. 231 * 232 * See anv_layout_to_aux_usage and anv_layout_to_fast_clear_type functions for 233 * details on exactly what is allowed in what layouts. 234 * 235 * On gen7-9, we do not have a concept of indirect clear colors in hardware. 236 * In order to deal with this, we have to do some clear color management. 237 * 238 * * For LOAD_OP_LOAD at the top of a renderpass, we have to copy the clear 239 * value from the buffer into the surface state with MI commands. 240 * 241 * * For any blorp operations, we pass the address to the clear value into 242 * blorp and it knows to copy the clear color. 243 */ 244static void 245add_aux_state_tracking_buffer(struct anv_image *image, 246 uint32_t plane, 247 const struct anv_device *device) 248{ 249 assert(image && device); 250 assert(image->planes[plane].aux_surface.isl.size_B > 0 && 251 image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 252 253 /* Compressed images must be tiled and therefore everything should be 4K 254 * aligned. The CCS has the same alignment requirements. This is good 255 * because we need at least dword-alignment for MI_LOAD/STORE operations. 256 */ 257 assert(image->alignment % 4 == 0); 258 assert((image->planes[plane].offset + image->planes[plane].size) % 4 == 0); 259 260 /* This buffer should be at the very end of the plane. */ 261 if (image->disjoint) { 262 assert(image->planes[plane].size == 263 (image->planes[plane].offset + image->planes[plane].size)); 264 } else { 265 assert(image->size == 266 (image->planes[plane].offset + image->planes[plane].size)); 267 } 268 269 const unsigned clear_color_state_size = device->info.gen >= 10 ? 270 device->isl_dev.ss.clear_color_state_size : 271 device->isl_dev.ss.clear_value_size; 272 273 /* Clear color and fast clear type */ 274 unsigned state_size = clear_color_state_size + 4; 275 276 /* We only need to track compression on CCS_E surfaces. */ 277 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) { 278 if (image->type == VK_IMAGE_TYPE_3D) { 279 for (uint32_t l = 0; l < image->levels; l++) 280 state_size += anv_minify(image->extent.depth, l) * 4; 281 } else { 282 state_size += image->levels * image->array_size * 4; 283 } 284 } 285 286 image->planes[plane].fast_clear_state_offset = 287 image->planes[plane].offset + image->planes[plane].size; 288 289 image->planes[plane].size += state_size; 290 image->size += state_size; 291} 292 293/** 294 * Initialize the anv_image::*_surface selected by \a aspect. Then update the 295 * image's memory requirements (that is, the image's size and alignment). 296 */ 297static VkResult 298make_surface(const struct anv_device *dev, 299 struct anv_image *image, 300 uint32_t stride, 301 isl_tiling_flags_t tiling_flags, 302 isl_surf_usage_flags_t isl_extra_usage_flags, 303 VkImageAspectFlagBits aspect) 304{ 305 bool ok; 306 307 static const enum isl_surf_dim vk_to_isl_surf_dim[] = { 308 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D, 309 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D, 310 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D, 311 }; 312 313 image->extent = anv_sanitize_image_extent(image->type, image->extent); 314 315 const unsigned plane = anv_image_aspect_to_plane(image->aspects, aspect); 316 const struct anv_format_plane plane_format = 317 anv_get_format_plane(&dev->info, image->vk_format, aspect, image->tiling); 318 struct anv_surface *anv_surf = &image->planes[plane].surface; 319 320 const isl_surf_usage_flags_t usage = 321 choose_isl_surf_usage(image->create_flags, image->usage, 322 isl_extra_usage_flags, aspect); 323 324 /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to 325 * fall back to linear on Broadwell and earlier because we aren't 326 * guaranteed that we can handle offsets correctly. On Sky Lake, the 327 * horizontal and vertical alignments are sufficiently high that we can 328 * just use RENDER_SURFACE_STATE::X/Y Offset. 329 */ 330 bool needs_shadow = false; 331 if (dev->info.gen <= 8 && 332 (image->create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) && 333 image->tiling == VK_IMAGE_TILING_OPTIMAL) { 334 assert(isl_format_is_compressed(plane_format.isl_format)); 335 tiling_flags = ISL_TILING_LINEAR_BIT; 336 needs_shadow = true; 337 } 338 339 ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl, 340 .dim = vk_to_isl_surf_dim[image->type], 341 .format = plane_format.isl_format, 342 .width = image->extent.width / plane_format.denominator_scales[0], 343 .height = image->extent.height / plane_format.denominator_scales[1], 344 .depth = image->extent.depth, 345 .levels = image->levels, 346 .array_len = image->array_size, 347 .samples = image->samples, 348 .min_alignment_B = 0, 349 .row_pitch_B = stride, 350 .usage = usage, 351 .tiling_flags = tiling_flags); 352 353 if (!ok) 354 return VK_ERROR_OUT_OF_DEVICE_MEMORY; 355 356 image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE; 357 358 add_surface(image, anv_surf, plane); 359 360 /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to 361 * create an identical tiled shadow surface for use while texturing so we 362 * don't get garbage performance. 363 */ 364 if (needs_shadow) { 365 assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT); 366 assert(tiling_flags == ISL_TILING_LINEAR_BIT); 367 368 ok = isl_surf_init(&dev->isl_dev, &image->planes[plane].shadow_surface.isl, 369 .dim = vk_to_isl_surf_dim[image->type], 370 .format = plane_format.isl_format, 371 .width = image->extent.width, 372 .height = image->extent.height, 373 .depth = image->extent.depth, 374 .levels = image->levels, 375 .array_len = image->array_size, 376 .samples = image->samples, 377 .min_alignment_B = 0, 378 .row_pitch_B = stride, 379 .usage = usage, 380 .tiling_flags = ISL_TILING_ANY_MASK); 381 382 /* isl_surf_init() will fail only if provided invalid input. Invalid input 383 * is illegal in Vulkan. 384 */ 385 assert(ok); 386 387 add_surface(image, &image->planes[plane].shadow_surface, plane); 388 } 389 390 /* Add a HiZ surface to a depth buffer that will be used for rendering. 391 */ 392 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 393 /* We don't advertise that depth buffers could be used as storage 394 * images. 395 */ 396 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT)); 397 398 /* Allow the user to control HiZ enabling. Disable by default on gen7 399 * because resolves are not currently implemented pre-BDW. 400 */ 401 if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 402 /* It will never be used as an attachment, HiZ is pointless. */ 403 } else if (dev->info.gen == 7) { 404 anv_perf_warn(dev->instance, image, "Implement gen7 HiZ"); 405 } else if (image->levels > 1) { 406 anv_perf_warn(dev->instance, image, "Enable multi-LOD HiZ"); 407 } else if (image->array_size > 1) { 408 anv_perf_warn(dev->instance, image, 409 "Implement multi-arrayLayer HiZ clears and resolves"); 410 } else if (dev->info.gen == 8 && image->samples > 1) { 411 anv_perf_warn(dev->instance, image, "Enable gen8 multisampled HiZ"); 412 } else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) { 413 assert(image->planes[plane].aux_surface.isl.size_B == 0); 414 ok = isl_surf_get_hiz_surf(&dev->isl_dev, 415 &image->planes[plane].surface.isl, 416 &image->planes[plane].aux_surface.isl); 417 assert(ok); 418 add_surface(image, &image->planes[plane].aux_surface, plane); 419 image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ; 420 } 421 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples == 1) { 422 /* TODO: Disallow compression with : 423 * 424 * 1) non multiplanar images (We appear to hit a sampler bug with 425 * CCS & R16G16 format. Putting the clear state a page/4096bytes 426 * further fixes the issue). 427 * 428 * 2) alias images, because they might be aliases of images 429 * described in 1) 430 * 431 * 3) compression disabled by debug 432 */ 433 const bool allow_compression = 434 image->n_planes == 1 && 435 (image->create_flags & VK_IMAGE_CREATE_ALIAS_BIT) == 0 && 436 likely((INTEL_DEBUG & DEBUG_NO_RBC) == 0); 437 438 if (allow_compression) { 439 assert(image->planes[plane].aux_surface.isl.size_B == 0); 440 ok = isl_surf_get_ccs_surf(&dev->isl_dev, 441 &image->planes[plane].surface.isl, 442 &image->planes[plane].aux_surface.isl, 0); 443 if (ok) { 444 445 /* Disable CCS when it is not useful (i.e., when you can't render 446 * to the image with CCS enabled). 447 */ 448 if (!isl_format_supports_rendering(&dev->info, 449 plane_format.isl_format)) { 450 /* While it may be technically possible to enable CCS for this 451 * image, we currently don't have things hooked up to get it 452 * working. 453 */ 454 anv_perf_warn(dev->instance, image, 455 "This image format doesn't support rendering. " 456 "Not allocating an CCS buffer."); 457 image->planes[plane].aux_surface.isl.size_B = 0; 458 return VK_SUCCESS; 459 } 460 461 add_surface(image, &image->planes[plane].aux_surface, plane); 462 add_aux_state_tracking_buffer(image, plane, dev); 463 464 /* For images created without MUTABLE_FORMAT_BIT set, we know that 465 * they will always be used with the original format. In 466 * particular, they will always be used with a format that 467 * supports color compression. If it's never used as a storage 468 * image, then it will only be used through the sampler or the as 469 * a render target. This means that it's safe to just leave 470 * compression on at all times for these formats. 471 */ 472 if (!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT) && 473 image->ccs_e_compatible) { 474 image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E; 475 } 476 } 477 } 478 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) { 479 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT)); 480 assert(image->planes[plane].aux_surface.isl.size_B == 0); 481 ok = isl_surf_get_mcs_surf(&dev->isl_dev, 482 &image->planes[plane].surface.isl, 483 &image->planes[plane].aux_surface.isl); 484 if (ok) { 485 add_surface(image, &image->planes[plane].aux_surface, plane); 486 add_aux_state_tracking_buffer(image, plane, dev); 487 image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS; 488 } 489 } 490 491 assert((image->planes[plane].offset + image->planes[plane].size) == image->size); 492 493 /* Upper bound of the last surface should be smaller than the plane's 494 * size. 495 */ 496 assert((MAX2(image->planes[plane].surface.offset, 497 image->planes[plane].aux_surface.offset) + 498 (image->planes[plane].aux_surface.isl.size_B > 0 ? 499 image->planes[plane].aux_surface.isl.size_B : 500 image->planes[plane].surface.isl.size_B)) <= 501 (image->planes[plane].offset + image->planes[plane].size)); 502 503 if (image->planes[plane].aux_surface.isl.size_B) { 504 /* assert(image->planes[plane].fast_clear_state_offset == */ 505 /* (image->planes[plane].aux_surface.offset + image->planes[plane].aux_surface.isl.size_B)); */ 506 assert(image->planes[plane].fast_clear_state_offset < 507 (image->planes[plane].offset + image->planes[plane].size)); 508 } 509 510 return VK_SUCCESS; 511} 512 513static uint32_t 514score_drm_format_mod(uint64_t modifier) 515{ 516 switch (modifier) { 517 case DRM_FORMAT_MOD_LINEAR: return 1; 518 case I915_FORMAT_MOD_X_TILED: return 2; 519 case I915_FORMAT_MOD_Y_TILED: return 3; 520 case I915_FORMAT_MOD_Y_TILED_CCS: return 4; 521 default: unreachable("bad DRM format modifier"); 522 } 523} 524 525static const struct isl_drm_modifier_info * 526choose_drm_format_mod(const struct anv_physical_device *device, 527 uint32_t modifier_count, const uint64_t *modifiers) 528{ 529 uint64_t best_mod = UINT64_MAX; 530 uint32_t best_score = 0; 531 532 for (uint32_t i = 0; i < modifier_count; ++i) { 533 uint32_t score = score_drm_format_mod(modifiers[i]); 534 if (score > best_score) { 535 best_mod = modifiers[i]; 536 best_score = score; 537 } 538 } 539 540 if (best_score > 0) 541 return isl_drm_modifier_get_info(best_mod); 542 else 543 return NULL; 544} 545 546VkResult 547anv_image_create(VkDevice _device, 548 const struct anv_image_create_info *create_info, 549 const VkAllocationCallbacks* alloc, 550 VkImage *pImage) 551{ 552 ANV_FROM_HANDLE(anv_device, device, _device); 553 const VkImageCreateInfo *pCreateInfo = create_info->vk_info; 554 const struct isl_drm_modifier_info *isl_mod_info = NULL; 555 struct anv_image *image = NULL; 556 VkResult r; 557 558 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); 559 560 const struct wsi_image_create_info *wsi_info = 561 vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA); 562 if (wsi_info && wsi_info->modifier_count > 0) { 563 isl_mod_info = choose_drm_format_mod(&device->instance->physicalDevice, 564 wsi_info->modifier_count, 565 wsi_info->modifiers); 566 assert(isl_mod_info); 567 } 568 569 anv_assert(pCreateInfo->mipLevels > 0); 570 anv_assert(pCreateInfo->arrayLayers > 0); 571 anv_assert(pCreateInfo->samples > 0); 572 anv_assert(pCreateInfo->extent.width > 0); 573 anv_assert(pCreateInfo->extent.height > 0); 574 anv_assert(pCreateInfo->extent.depth > 0); 575 576 image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8, 577 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 578 if (!image) 579 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 580 581 image->type = pCreateInfo->imageType; 582 image->extent = pCreateInfo->extent; 583 image->vk_format = pCreateInfo->format; 584 image->format = anv_get_format(pCreateInfo->format); 585 image->aspects = vk_format_aspects(image->vk_format); 586 image->levels = pCreateInfo->mipLevels; 587 image->array_size = pCreateInfo->arrayLayers; 588 image->samples = pCreateInfo->samples; 589 image->usage = pCreateInfo->usage; 590 image->create_flags = pCreateInfo->flags; 591 image->tiling = pCreateInfo->tiling; 592 image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT; 593 image->needs_set_tiling = wsi_info && wsi_info->scanout; 594 image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier : 595 DRM_FORMAT_MOD_INVALID; 596 597 /* In case of external format, We don't know format yet, 598 * so skip the rest for now. 599 */ 600 if (create_info->external_format) { 601 image->external_format = true; 602 *pImage = anv_image_to_handle(image); 603 return VK_SUCCESS; 604 } 605 606 const struct anv_format *format = anv_get_format(image->vk_format); 607 assert(format != NULL); 608 609 const isl_tiling_flags_t isl_tiling_flags = 610 choose_isl_tiling_flags(create_info, isl_mod_info, 611 image->needs_set_tiling); 612 613 image->n_planes = format->n_planes; 614 615 const VkImageFormatListCreateInfoKHR *fmt_list = 616 vk_find_struct_const(pCreateInfo->pNext, 617 IMAGE_FORMAT_LIST_CREATE_INFO_KHR); 618 619 image->ccs_e_compatible = 620 all_formats_ccs_e_compatible(&device->info, fmt_list, image); 621 622 uint32_t b; 623 for_each_bit(b, image->aspects) { 624 r = make_surface(device, image, create_info->stride, isl_tiling_flags, 625 create_info->isl_extra_usage_flags, (1 << b)); 626 if (r != VK_SUCCESS) 627 goto fail; 628 } 629 630 *pImage = anv_image_to_handle(image); 631 632 return VK_SUCCESS; 633 634fail: 635 if (image) 636 vk_free2(&device->alloc, alloc, image); 637 638 return r; 639} 640 641static struct anv_image * 642anv_swapchain_get_image(VkSwapchainKHR swapchain, 643 uint32_t index) 644{ 645 uint32_t n_images = index + 1; 646 VkImage *images = malloc(sizeof(*images) * n_images); 647 VkResult result = wsi_common_get_images(swapchain, &n_images, images); 648 649 if (result != VK_SUCCESS && result != VK_INCOMPLETE) { 650 free(images); 651 return NULL; 652 } 653 654 ANV_FROM_HANDLE(anv_image, image, images[index]); 655 free(images); 656 657 return image; 658} 659 660static VkResult 661anv_image_from_swapchain(VkDevice device, 662 const VkImageCreateInfo *pCreateInfo, 663 const VkImageSwapchainCreateInfoKHR *swapchain_info, 664 const VkAllocationCallbacks *pAllocator, 665 VkImage *pImage) 666{ 667 struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0); 668 assert(swapchain_image); 669 670 assert(swapchain_image->type == pCreateInfo->imageType); 671 assert(swapchain_image->vk_format == pCreateInfo->format); 672 assert(swapchain_image->extent.width == pCreateInfo->extent.width); 673 assert(swapchain_image->extent.height == pCreateInfo->extent.height); 674 assert(swapchain_image->extent.depth == pCreateInfo->extent.depth); 675 assert(swapchain_image->array_size == pCreateInfo->arrayLayers); 676 /* Color attachment is added by the wsi code. */ 677 assert(swapchain_image->usage == (pCreateInfo->usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)); 678 679 VkImageCreateInfo local_create_info; 680 local_create_info = *pCreateInfo; 681 local_create_info.pNext = NULL; 682 /* The following parameters are implictly selected by the wsi code. */ 683 local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL; 684 local_create_info.samples = VK_SAMPLE_COUNT_1_BIT; 685 local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; 686 687 /* If the image has a particular modifier, specify that modifier. */ 688 struct wsi_image_create_info local_wsi_info = { 689 .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA, 690 .modifier_count = 1, 691 .modifiers = &swapchain_image->drm_format_mod, 692 }; 693 if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID) 694 __vk_append_struct(&local_create_info, &local_wsi_info); 695 696 return anv_image_create(device, 697 &(struct anv_image_create_info) { 698 .vk_info = &local_create_info, 699 .external_format = swapchain_image->external_format, 700 }, 701 pAllocator, 702 pImage); 703} 704 705VkResult 706anv_CreateImage(VkDevice device, 707 const VkImageCreateInfo *pCreateInfo, 708 const VkAllocationCallbacks *pAllocator, 709 VkImage *pImage) 710{ 711 const struct VkExternalMemoryImageCreateInfo *create_info = 712 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO); 713 714 if (create_info && (create_info->handleTypes & 715 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID)) 716 return anv_image_from_external(device, pCreateInfo, create_info, 717 pAllocator, pImage); 718 719 const VkNativeBufferANDROID *gralloc_info = 720 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID); 721 if (gralloc_info) 722 return anv_image_from_gralloc(device, pCreateInfo, gralloc_info, 723 pAllocator, pImage); 724 725 const VkImageSwapchainCreateInfoKHR *swapchain_info = 726 vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR); 727 if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) 728 return anv_image_from_swapchain(device, pCreateInfo, swapchain_info, 729 pAllocator, pImage); 730 731 return anv_image_create(device, 732 &(struct anv_image_create_info) { 733 .vk_info = pCreateInfo, 734 }, 735 pAllocator, 736 pImage); 737} 738 739void 740anv_DestroyImage(VkDevice _device, VkImage _image, 741 const VkAllocationCallbacks *pAllocator) 742{ 743 ANV_FROM_HANDLE(anv_device, device, _device); 744 ANV_FROM_HANDLE(anv_image, image, _image); 745 746 if (!image) 747 return; 748 749 for (uint32_t p = 0; p < image->n_planes; ++p) { 750 if (image->planes[p].bo_is_owned) { 751 assert(image->planes[p].address.bo != NULL); 752 anv_bo_cache_release(device, &device->bo_cache, 753 image->planes[p].address.bo); 754 } 755 } 756 757 vk_free2(&device->alloc, pAllocator, image); 758} 759 760static void anv_image_bind_memory_plane(struct anv_device *device, 761 struct anv_image *image, 762 uint32_t plane, 763 struct anv_device_memory *memory, 764 uint32_t memory_offset) 765{ 766 assert(!image->planes[plane].bo_is_owned); 767 768 if (!memory) { 769 image->planes[plane].address = ANV_NULL_ADDRESS; 770 return; 771 } 772 773 image->planes[plane].address = (struct anv_address) { 774 .bo = memory->bo, 775 .offset = memory_offset, 776 }; 777} 778 779/* We are binding AHardwareBuffer. Get a description, resolve the 780 * format and prepare anv_image properly. 781 */ 782static void 783resolve_ahw_image(struct anv_device *device, 784 struct anv_image *image, 785 struct anv_device_memory *mem) 786{ 787#if defined(ANDROID) && ANDROID_API_LEVEL >= 26 788 assert(mem->ahw); 789 AHardwareBuffer_Desc desc; 790 AHardwareBuffer_describe(mem->ahw, &desc); 791 792 /* Check tiling. */ 793 int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle); 794 VkImageTiling vk_tiling; 795 isl_tiling_flags_t isl_tiling_flags = 0; 796 797 switch (i915_tiling) { 798 case I915_TILING_NONE: 799 vk_tiling = VK_IMAGE_TILING_LINEAR; 800 isl_tiling_flags = ISL_TILING_LINEAR_BIT; 801 break; 802 case I915_TILING_X: 803 vk_tiling = VK_IMAGE_TILING_OPTIMAL; 804 isl_tiling_flags = ISL_TILING_X_BIT; 805 break; 806 case I915_TILING_Y: 807 vk_tiling = VK_IMAGE_TILING_OPTIMAL; 808 isl_tiling_flags = ISL_TILING_Y0_BIT; 809 break; 810 case -1: 811 default: 812 unreachable("Invalid tiling flags."); 813 } 814 815 assert(vk_tiling == VK_IMAGE_TILING_LINEAR || 816 vk_tiling == VK_IMAGE_TILING_OPTIMAL); 817 818 /* Check format. */ 819 VkFormat vk_format = vk_format_from_android(desc.format, desc.usage); 820 enum isl_format isl_fmt = anv_get_isl_format(&device->info, 821 vk_format, 822 VK_IMAGE_ASPECT_COLOR_BIT, 823 vk_tiling); 824 assert(isl_fmt != ISL_FORMAT_UNSUPPORTED); 825 826 /* Handle RGB(X)->RGBA fallback. */ 827 switch (desc.format) { 828 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM: 829 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM: 830 if (isl_format_is_rgb(isl_fmt)) 831 isl_fmt = isl_format_rgb_to_rgba(isl_fmt); 832 break; 833 } 834 835 /* Now we are able to fill anv_image fields properly and create 836 * isl_surface for it. 837 */ 838 image->vk_format = vk_format; 839 image->format = anv_get_format(vk_format); 840 image->aspects = vk_format_aspects(image->vk_format); 841 image->n_planes = image->format->n_planes; 842 image->ccs_e_compatible = false; 843 844 uint32_t stride = desc.stride * 845 (isl_format_get_layout(isl_fmt)->bpb / 8); 846 847 uint32_t b; 848 for_each_bit(b, image->aspects) { 849 VkResult r = make_surface(device, image, stride, isl_tiling_flags, 850 ISL_SURF_USAGE_DISABLE_AUX_BIT, (1 << b)); 851 assert(r == VK_SUCCESS); 852 } 853#endif 854} 855 856VkResult anv_BindImageMemory( 857 VkDevice _device, 858 VkImage _image, 859 VkDeviceMemory _memory, 860 VkDeviceSize memoryOffset) 861{ 862 ANV_FROM_HANDLE(anv_device, device, _device); 863 ANV_FROM_HANDLE(anv_device_memory, mem, _memory); 864 ANV_FROM_HANDLE(anv_image, image, _image); 865 866 if (mem->ahw) 867 resolve_ahw_image(device, image, mem); 868 869 uint32_t aspect_bit; 870 anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) { 871 uint32_t plane = 872 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit); 873 anv_image_bind_memory_plane(device, image, plane, mem, memoryOffset); 874 } 875 876 return VK_SUCCESS; 877} 878 879VkResult anv_BindImageMemory2( 880 VkDevice _device, 881 uint32_t bindInfoCount, 882 const VkBindImageMemoryInfo* pBindInfos) 883{ 884 ANV_FROM_HANDLE(anv_device, device, _device); 885 886 for (uint32_t i = 0; i < bindInfoCount; i++) { 887 const VkBindImageMemoryInfo *bind_info = &pBindInfos[i]; 888 ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory); 889 ANV_FROM_HANDLE(anv_image, image, bind_info->image); 890 891 /* Resolve will alter the image's aspects, do this first. */ 892 if (mem && mem->ahw) 893 resolve_ahw_image(device, image, mem); 894 895 VkImageAspectFlags aspects = image->aspects; 896 vk_foreach_struct_const(s, bind_info->pNext) { 897 switch (s->sType) { 898 case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: { 899 const VkBindImagePlaneMemoryInfo *plane_info = 900 (const VkBindImagePlaneMemoryInfo *) s; 901 902 aspects = plane_info->planeAspect; 903 break; 904 } 905 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: { 906 const VkBindImageMemorySwapchainInfoKHR *swapchain_info = 907 (const VkBindImageMemorySwapchainInfoKHR *) s; 908 struct anv_image *swapchain_image = 909 anv_swapchain_get_image(swapchain_info->swapchain, 910 swapchain_info->imageIndex); 911 assert(swapchain_image); 912 assert(image->aspects == swapchain_image->aspects); 913 assert(mem == NULL); 914 915 uint32_t aspect_bit; 916 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) { 917 uint32_t plane = 918 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit); 919 struct anv_device_memory mem = { 920 .bo = swapchain_image->planes[plane].address.bo, 921 }; 922 anv_image_bind_memory_plane(device, image, plane, 923 &mem, bind_info->memoryOffset); 924 } 925 break; 926 } 927 default: 928 anv_debug_ignored_stype(s->sType); 929 break; 930 } 931 } 932 933 /* VkBindImageMemorySwapchainInfoKHR requires memory to be 934 * VK_NULL_HANDLE. In such case, just carry one with the next bind 935 * item. 936 */ 937 if (!mem) 938 continue; 939 940 uint32_t aspect_bit; 941 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) { 942 uint32_t plane = 943 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit); 944 anv_image_bind_memory_plane(device, image, plane, 945 mem, bind_info->memoryOffset); 946 } 947 } 948 949 return VK_SUCCESS; 950} 951 952void anv_GetImageSubresourceLayout( 953 VkDevice device, 954 VkImage _image, 955 const VkImageSubresource* subresource, 956 VkSubresourceLayout* layout) 957{ 958 ANV_FROM_HANDLE(anv_image, image, _image); 959 960 const struct anv_surface *surface; 961 if (subresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT && 962 image->drm_format_mod != DRM_FORMAT_MOD_INVALID && 963 isl_drm_modifier_has_aux(image->drm_format_mod)) 964 surface = &image->planes[0].aux_surface; 965 else 966 surface = get_surface(image, subresource->aspectMask); 967 968 assert(__builtin_popcount(subresource->aspectMask) == 1); 969 970 layout->offset = surface->offset; 971 layout->rowPitch = surface->isl.row_pitch_B; 972 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl); 973 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl); 974 975 if (subresource->mipLevel > 0 || subresource->arrayLayer > 0) { 976 assert(surface->isl.tiling == ISL_TILING_LINEAR); 977 978 uint32_t offset_B; 979 isl_surf_get_image_offset_B_tile_sa(&surface->isl, 980 subresource->mipLevel, 981 subresource->arrayLayer, 982 0 /* logical_z_offset_px */, 983 &offset_B, NULL, NULL); 984 layout->offset += offset_B; 985 layout->size = layout->rowPitch * anv_minify(image->extent.height, 986 subresource->mipLevel); 987 } else { 988 layout->size = surface->isl.size_B; 989 } 990} 991 992/** 993 * This function determines the optimal buffer to use for a given 994 * VkImageLayout and other pieces of information needed to make that 995 * determination. This does not determine the optimal buffer to use 996 * during a resolve operation. 997 * 998 * @param devinfo The device information of the Intel GPU. 999 * @param image The image that may contain a collection of buffers. 1000 * @param aspect The aspect of the image to be accessed. 1001 * @param layout The current layout of the image aspect(s). 1002 * 1003 * @return The primary buffer that should be used for the given layout. 1004 */ 1005enum isl_aux_usage 1006anv_layout_to_aux_usage(const struct gen_device_info * const devinfo, 1007 const struct anv_image * const image, 1008 const VkImageAspectFlagBits aspect, 1009 const VkImageLayout layout) 1010{ 1011 /* Validate the inputs. */ 1012 1013 /* The devinfo is needed as the optimal buffer varies across generations. */ 1014 assert(devinfo != NULL); 1015 1016 /* The layout of a NULL image is not properly defined. */ 1017 assert(image != NULL); 1018 1019 /* The aspect must be exactly one of the image aspects. */ 1020 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects)); 1021 1022 /* Determine the optimal buffer. */ 1023 1024 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); 1025 1026 /* If there is no auxiliary surface allocated, we must use the one and only 1027 * main buffer. 1028 */ 1029 if (image->planes[plane].aux_surface.isl.size_B == 0) 1030 return ISL_AUX_USAGE_NONE; 1031 1032 /* All images that use an auxiliary surface are required to be tiled. */ 1033 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL); 1034 1035 /* Stencil has no aux */ 1036 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT); 1037 1038 switch (layout) { 1039 1040 /* Invalid Layouts */ 1041 case VK_IMAGE_LAYOUT_RANGE_SIZE: 1042 case VK_IMAGE_LAYOUT_MAX_ENUM: 1043 unreachable("Invalid image layout."); 1044 1045 /* Undefined layouts 1046 * 1047 * The pre-initialized layout is equivalent to the undefined layout for 1048 * optimally-tiled images. We can only do color compression (CCS or HiZ) 1049 * on tiled images. 1050 */ 1051 case VK_IMAGE_LAYOUT_UNDEFINED: 1052 case VK_IMAGE_LAYOUT_PREINITIALIZED: 1053 return ISL_AUX_USAGE_NONE; 1054 1055 1056 /* Transfer Layouts 1057 */ 1058 case VK_IMAGE_LAYOUT_GENERAL: 1059 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL: 1060 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL: 1061 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 1062 /* This buffer could be a depth buffer used in a transfer operation. 1063 * BLORP currently doesn't use HiZ for transfer operations so we must 1064 * use the main buffer for this layout. TODO: Enable HiZ in BLORP. 1065 */ 1066 assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_HIZ); 1067 return ISL_AUX_USAGE_NONE; 1068 } else { 1069 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 1070 return image->planes[plane].aux_usage; 1071 } 1072 1073 1074 /* Sampling Layouts */ 1075 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 1076 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: 1077 assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0); 1078 /* Fall-through */ 1079 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 1080 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 1081 if (anv_can_sample_with_hiz(devinfo, image)) 1082 return ISL_AUX_USAGE_HIZ; 1083 else 1084 return ISL_AUX_USAGE_NONE; 1085 } else { 1086 return image->planes[plane].aux_usage; 1087 } 1088 1089 1090 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: { 1091 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); 1092 1093 /* When handing the image off to the presentation engine, we need to 1094 * ensure that things are properly resolved. For images with no 1095 * modifier, we assume that they follow the old rules and always need 1096 * a full resolve because the PE doesn't understand any form of 1097 * compression. For images with modifiers, we use the aux usage from 1098 * the modifier. 1099 */ 1100 const struct isl_drm_modifier_info *mod_info = 1101 isl_drm_modifier_get_info(image->drm_format_mod); 1102 return mod_info ? mod_info->aux_usage : ISL_AUX_USAGE_NONE; 1103 } 1104 1105 1106 /* Rendering Layouts */ 1107 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 1108 assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 1109 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) { 1110 assert(image->samples == 1); 1111 return ISL_AUX_USAGE_CCS_D; 1112 } else { 1113 assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_CCS_D); 1114 return image->planes[plane].aux_usage; 1115 } 1116 1117 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL: 1118 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: 1119 assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT); 1120 return ISL_AUX_USAGE_HIZ; 1121 1122 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: 1123 unreachable("VK_KHR_shared_presentable_image is unsupported"); 1124 1125 case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT: 1126 unreachable("VK_EXT_fragment_density_map is unsupported"); 1127 1128 case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV: 1129 unreachable("VK_NV_shading_rate_image is unsupported"); 1130 } 1131 1132 /* If the layout isn't recognized in the exhaustive switch above, the 1133 * VkImageLayout value is not defined in vulkan.h. 1134 */ 1135 unreachable("layout is not a VkImageLayout enumeration member."); 1136} 1137 1138/** 1139 * This function returns the level of unresolved fast-clear support of the 1140 * given image in the given VkImageLayout. 1141 * 1142 * @param devinfo The device information of the Intel GPU. 1143 * @param image The image that may contain a collection of buffers. 1144 * @param aspect The aspect of the image to be accessed. 1145 * @param layout The current layout of the image aspect(s). 1146 */ 1147enum anv_fast_clear_type 1148anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo, 1149 const struct anv_image * const image, 1150 const VkImageAspectFlagBits aspect, 1151 const VkImageLayout layout) 1152{ 1153 /* The aspect must be exactly one of the image aspects. */ 1154 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects)); 1155 1156 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); 1157 1158 /* If there is no auxiliary surface allocated, there are no fast-clears */ 1159 if (image->planes[plane].aux_surface.isl.size_B == 0) 1160 return ANV_FAST_CLEAR_NONE; 1161 1162 /* All images that use an auxiliary surface are required to be tiled. */ 1163 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL); 1164 1165 /* Stencil has no aux */ 1166 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT); 1167 1168 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 1169 /* For depth images (with HiZ), the layout supports fast-clears if and 1170 * only if it supports HiZ. However, we only support fast-clears to the 1171 * default depth value. 1172 */ 1173 enum isl_aux_usage aux_usage = 1174 anv_layout_to_aux_usage(devinfo, image, aspect, layout); 1175 return aux_usage == ISL_AUX_USAGE_HIZ ? 1176 ANV_FAST_CLEAR_DEFAULT_VALUE : ANV_FAST_CLEAR_NONE; 1177 } 1178 1179 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV); 1180 1181 /* We don't support MSAA fast-clears on Ivybridge or Bay Trail because they 1182 * lack the MI ALU which we need to determine the predicates. 1183 */ 1184 if (devinfo->gen == 7 && !devinfo->is_haswell && image->samples > 1) 1185 return ANV_FAST_CLEAR_NONE; 1186 1187 switch (layout) { 1188 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL: 1189 return ANV_FAST_CLEAR_ANY; 1190 1191 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: { 1192 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); 1193#ifndef NDEBUG 1194 /* We do not yet support any modifiers which support clear color so we 1195 * just always return NONE. One day, this will change. 1196 */ 1197 const struct isl_drm_modifier_info *mod_info = 1198 isl_drm_modifier_get_info(image->drm_format_mod); 1199 assert(!mod_info || !mod_info->supports_clear_color); 1200#endif 1201 return ANV_FAST_CLEAR_NONE; 1202 } 1203 1204 default: 1205 /* If the image has MCS or CCS_E enabled all the time then we can use 1206 * fast-clear as long as the clear color is the default value of zero 1207 * since this is the default value we program into every surface state 1208 * used for texturing. 1209 */ 1210 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS || 1211 image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) 1212 return ANV_FAST_CLEAR_DEFAULT_VALUE; 1213 else 1214 return ANV_FAST_CLEAR_NONE; 1215 } 1216} 1217 1218 1219static struct anv_state 1220alloc_surface_state(struct anv_device *device) 1221{ 1222 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64); 1223} 1224 1225static enum isl_channel_select 1226remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component, 1227 struct isl_swizzle format_swizzle) 1228{ 1229 if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY) 1230 swizzle = component; 1231 1232 switch (swizzle) { 1233 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO; 1234 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE; 1235 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r; 1236 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g; 1237 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b; 1238 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a; 1239 default: 1240 unreachable("Invalid swizzle"); 1241 } 1242} 1243 1244void 1245anv_image_fill_surface_state(struct anv_device *device, 1246 const struct anv_image *image, 1247 VkImageAspectFlagBits aspect, 1248 const struct isl_view *view_in, 1249 isl_surf_usage_flags_t view_usage, 1250 enum isl_aux_usage aux_usage, 1251 const union isl_color_value *clear_color, 1252 enum anv_image_view_state_flags flags, 1253 struct anv_surface_state *state_inout, 1254 struct brw_image_param *image_param_out) 1255{ 1256 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect); 1257 1258 const struct anv_surface *surface = &image->planes[plane].surface, 1259 *aux_surface = &image->planes[plane].aux_surface; 1260 1261 struct isl_view view = *view_in; 1262 view.usage |= view_usage; 1263 1264 /* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a 1265 * compressed surface with a shadow surface, we use the shadow instead of 1266 * the primary surface. The shadow surface will be tiled, unlike the main 1267 * surface, so it should get significantly better performance. 1268 */ 1269 if (image->planes[plane].shadow_surface.isl.size_B > 0 && 1270 isl_format_is_compressed(view.format) && 1271 (flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) { 1272 assert(isl_format_is_compressed(surface->isl.format)); 1273 assert(surface->isl.tiling == ISL_TILING_LINEAR); 1274 assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR); 1275 surface = &image->planes[plane].shadow_surface; 1276 } 1277 1278 if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT) 1279 view.swizzle = anv_swizzle_for_render(view.swizzle); 1280 1281 /* On Ivy Bridge and Bay Trail we do the swizzle in the shader */ 1282 if (device->info.gen == 7 && !device->info.is_haswell) 1283 view.swizzle = ISL_SWIZZLE_IDENTITY; 1284 1285 /* If this is a HiZ buffer we can sample from with a programmable clear 1286 * value (SKL+), define the clear value to the optimal constant. 1287 */ 1288 union isl_color_value default_clear_color = { .u32 = { 0, } }; 1289 if (device->info.gen >= 9 && aux_usage == ISL_AUX_USAGE_HIZ) 1290 default_clear_color.f32[0] = ANV_HZ_FC_VAL; 1291 if (!clear_color) 1292 clear_color = &default_clear_color; 1293 1294 const struct anv_address address = 1295 anv_address_add(image->planes[plane].address, surface->offset); 1296 1297 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && 1298 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) && 1299 !isl_has_matching_typed_storage_image_format(&device->info, 1300 view.format)) { 1301 /* In this case, we are a writeable storage buffer which needs to be 1302 * lowered to linear. All tiling and offset calculations will be done in 1303 * the shader. 1304 */ 1305 assert(aux_usage == ISL_AUX_USAGE_NONE); 1306 isl_buffer_fill_state(&device->isl_dev, state_inout->state.map, 1307 .address = anv_address_physical(address), 1308 .size_B = surface->isl.size_B, 1309 .format = ISL_FORMAT_RAW, 1310 .swizzle = ISL_SWIZZLE_IDENTITY, 1311 .stride_B = 1, 1312 .mocs = anv_mocs_for_bo(device, address.bo)); 1313 state_inout->address = address, 1314 state_inout->aux_address = ANV_NULL_ADDRESS; 1315 state_inout->clear_address = ANV_NULL_ADDRESS; 1316 } else { 1317 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT && 1318 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) { 1319 /* Typed surface reads support a very limited subset of the shader 1320 * image formats. Translate it into the closest format the hardware 1321 * supports. 1322 */ 1323 assert(aux_usage == ISL_AUX_USAGE_NONE); 1324 view.format = isl_lower_storage_image_format(&device->info, 1325 view.format); 1326 } 1327 1328 const struct isl_surf *isl_surf = &surface->isl; 1329 1330 struct isl_surf tmp_surf; 1331 uint32_t offset_B = 0, tile_x_sa = 0, tile_y_sa = 0; 1332 if (isl_format_is_compressed(surface->isl.format) && 1333 !isl_format_is_compressed(view.format)) { 1334 /* We're creating an uncompressed view of a compressed surface. This 1335 * is allowed but only for a single level/layer. 1336 */ 1337 assert(surface->isl.samples == 1); 1338 assert(view.levels == 1); 1339 assert(view.array_len == 1); 1340 1341 isl_surf_get_image_surf(&device->isl_dev, isl_surf, 1342 view.base_level, 1343 surface->isl.dim == ISL_SURF_DIM_3D ? 1344 0 : view.base_array_layer, 1345 surface->isl.dim == ISL_SURF_DIM_3D ? 1346 view.base_array_layer : 0, 1347 &tmp_surf, 1348 &offset_B, &tile_x_sa, &tile_y_sa); 1349 1350 /* The newly created image represents the one subimage we're 1351 * referencing with this view so it only has one array slice and 1352 * miplevel. 1353 */ 1354 view.base_array_layer = 0; 1355 view.base_level = 0; 1356 1357 /* We're making an uncompressed view here. The image dimensions need 1358 * to be scaled down by the block size. 1359 */ 1360 const struct isl_format_layout *fmtl = 1361 isl_format_get_layout(surface->isl.format); 1362 tmp_surf.logical_level0_px = 1363 isl_surf_get_logical_level0_el(&tmp_surf); 1364 tmp_surf.phys_level0_sa = isl_surf_get_phys_level0_el(&tmp_surf); 1365 tmp_surf.format = view.format; 1366 tile_x_sa /= fmtl->bw; 1367 tile_y_sa /= fmtl->bh; 1368 1369 isl_surf = &tmp_surf; 1370 1371 if (device->info.gen <= 8) { 1372 assert(surface->isl.tiling == ISL_TILING_LINEAR); 1373 assert(tile_x_sa == 0); 1374 assert(tile_y_sa == 0); 1375 } 1376 } 1377 1378 state_inout->address = anv_address_add(address, offset_B); 1379 1380 struct anv_address aux_address = ANV_NULL_ADDRESS; 1381 if (aux_usage != ISL_AUX_USAGE_NONE) { 1382 aux_address = anv_address_add(image->planes[plane].address, 1383 aux_surface->offset); 1384 } 1385 state_inout->aux_address = aux_address; 1386 1387 struct anv_address clear_address = ANV_NULL_ADDRESS; 1388 if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE) { 1389 if (aux_usage == ISL_AUX_USAGE_HIZ) { 1390 clear_address = (struct anv_address) { 1391 .bo = &device->hiz_clear_bo, 1392 .offset = 0, 1393 }; 1394 } else { 1395 clear_address = anv_image_get_clear_color_addr(device, image, aspect); 1396 } 1397 } 1398 state_inout->clear_address = clear_address; 1399 1400 isl_surf_fill_state(&device->isl_dev, state_inout->state.map, 1401 .surf = isl_surf, 1402 .view = &view, 1403 .address = anv_address_physical(state_inout->address), 1404 .clear_color = *clear_color, 1405 .aux_surf = &aux_surface->isl, 1406 .aux_usage = aux_usage, 1407 .aux_address = anv_address_physical(aux_address), 1408 .clear_address = anv_address_physical(clear_address), 1409 .use_clear_address = !anv_address_is_null(clear_address), 1410 .mocs = anv_mocs_for_bo(device, 1411 state_inout->address.bo), 1412 .x_offset_sa = tile_x_sa, 1413 .y_offset_sa = tile_y_sa); 1414 1415 /* With the exception of gen8, the bottom 12 bits of the MCS base address 1416 * are used to store other information. This should be ok, however, 1417 * because the surface buffer addresses are always 4K page aligned. 1418 */ 1419 uint32_t *aux_addr_dw = state_inout->state.map + 1420 device->isl_dev.ss.aux_addr_offset; 1421 assert((aux_address.offset & 0xfff) == 0); 1422 state_inout->aux_address.offset |= *aux_addr_dw & 0xfff; 1423 1424 if (device->info.gen >= 10 && clear_address.bo) { 1425 uint32_t *clear_addr_dw = state_inout->state.map + 1426 device->isl_dev.ss.clear_color_state_offset; 1427 assert((clear_address.offset & 0x3f) == 0); 1428 state_inout->clear_address.offset |= *clear_addr_dw & 0x3f; 1429 } 1430 } 1431 1432 if (image_param_out) { 1433 assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT); 1434 isl_surf_fill_image_param(&device->isl_dev, image_param_out, 1435 &surface->isl, &view); 1436 } 1437} 1438 1439static VkImageAspectFlags 1440remap_aspect_flags(VkImageAspectFlags view_aspects) 1441{ 1442 if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) { 1443 if (util_bitcount(view_aspects) == 1) 1444 return VK_IMAGE_ASPECT_COLOR_BIT; 1445 1446 VkImageAspectFlags color_aspects = 0; 1447 for (uint32_t i = 0; i < util_bitcount(view_aspects); i++) 1448 color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT << i; 1449 return color_aspects; 1450 } 1451 /* No special remapping needed for depth & stencil aspects. */ 1452 return view_aspects; 1453} 1454 1455static uint32_t 1456anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask) 1457{ 1458 uint32_t planes = 0; 1459 1460 if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT | 1461 VK_IMAGE_ASPECT_DEPTH_BIT | 1462 VK_IMAGE_ASPECT_STENCIL_BIT | 1463 VK_IMAGE_ASPECT_PLANE_0_BIT)) 1464 planes++; 1465 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT) 1466 planes++; 1467 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT) 1468 planes++; 1469 1470 if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 && 1471 (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0) 1472 planes++; 1473 1474 return planes; 1475} 1476 1477VkResult 1478anv_CreateImageView(VkDevice _device, 1479 const VkImageViewCreateInfo *pCreateInfo, 1480 const VkAllocationCallbacks *pAllocator, 1481 VkImageView *pView) 1482{ 1483 ANV_FROM_HANDLE(anv_device, device, _device); 1484 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); 1485 struct anv_image_view *iview; 1486 1487 iview = vk_zalloc2(&device->alloc, pAllocator, sizeof(*iview), 8, 1488 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1489 if (iview == NULL) 1490 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 1491 1492 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; 1493 1494 assert(range->layerCount > 0); 1495 assert(range->baseMipLevel < image->levels); 1496 1497 /* Check if a conversion info was passed. */ 1498 const struct anv_format *conv_format = NULL; 1499 const struct VkSamplerYcbcrConversionInfo *conv_info = 1500 vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO); 1501 1502 /* If image has an external format, the pNext chain must contain an instance of 1503 * VKSamplerYcbcrConversionInfo with a conversion object created with the same 1504 * external format as image." 1505 */ 1506 assert(!image->external_format || conv_info); 1507 1508 if (conv_info) { 1509 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion); 1510 conv_format = conversion->format; 1511 } 1512 1513 const VkImageViewUsageCreateInfo *usage_info = 1514 vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO); 1515 VkImageUsageFlags view_usage = usage_info ? usage_info->usage : image->usage; 1516 /* View usage should be a subset of image usage */ 1517 assert((view_usage & ~image->usage) == 0); 1518 assert(view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT | 1519 VK_IMAGE_USAGE_STORAGE_BIT | 1520 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 1521 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | 1522 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)); 1523 1524 switch (image->type) { 1525 default: 1526 unreachable("bad VkImageType"); 1527 case VK_IMAGE_TYPE_1D: 1528 case VK_IMAGE_TYPE_2D: 1529 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size); 1530 break; 1531 case VK_IMAGE_TYPE_3D: 1532 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 1533 <= anv_minify(image->extent.depth, range->baseMipLevel)); 1534 break; 1535 } 1536 1537 /* First expand aspects to the image's ones (for example 1538 * VK_IMAGE_ASPECT_COLOR_BIT will be converted to 1539 * VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT | 1540 * VK_IMAGE_ASPECT_PLANE_2_BIT for an image of format 1541 * VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM. 1542 */ 1543 VkImageAspectFlags expanded_aspects = 1544 anv_image_expand_aspects(image, range->aspectMask); 1545 1546 iview->image = image; 1547 1548 /* Remap the expanded aspects for the image view. For example if only 1549 * VK_IMAGE_ASPECT_PLANE_1_BIT was given in range->aspectMask, we will 1550 * convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of 1551 * the image view, it only has a single plane. 1552 */ 1553 iview->aspect_mask = remap_aspect_flags(expanded_aspects); 1554 iview->n_planes = anv_image_aspect_get_planes(iview->aspect_mask); 1555 iview->vk_format = pCreateInfo->format; 1556 1557 /* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */ 1558 assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED); 1559 1560 /* Format is undefined, this can happen when using external formats. Set 1561 * view format from the passed conversion info. 1562 */ 1563 if (iview->vk_format == VK_FORMAT_UNDEFINED && conv_format) 1564 iview->vk_format = conv_format->vk_format; 1565 1566 iview->extent = (VkExtent3D) { 1567 .width = anv_minify(image->extent.width , range->baseMipLevel), 1568 .height = anv_minify(image->extent.height, range->baseMipLevel), 1569 .depth = anv_minify(image->extent.depth , range->baseMipLevel), 1570 }; 1571 1572 /* Now go through the underlying image selected planes (computed in 1573 * expanded_aspects) and map them to planes in the image view. 1574 */ 1575 uint32_t iaspect_bit, vplane = 0; 1576 anv_foreach_image_aspect_bit(iaspect_bit, image, expanded_aspects) { 1577 uint32_t iplane = 1578 anv_image_aspect_to_plane(image->aspects, 1UL << iaspect_bit); 1579 VkImageAspectFlags vplane_aspect = 1580 anv_plane_to_aspect(iview->aspect_mask, vplane); 1581 struct anv_format_plane format = 1582 anv_get_format_plane(&device->info, iview->vk_format, 1583 vplane_aspect, image->tiling); 1584 1585 iview->planes[vplane].image_plane = iplane; 1586 1587 iview->planes[vplane].isl = (struct isl_view) { 1588 .format = format.isl_format, 1589 .base_level = range->baseMipLevel, 1590 .levels = anv_get_levelCount(image, range), 1591 .base_array_layer = range->baseArrayLayer, 1592 .array_len = anv_get_layerCount(image, range), 1593 .swizzle = { 1594 .r = remap_swizzle(pCreateInfo->components.r, 1595 VK_COMPONENT_SWIZZLE_R, format.swizzle), 1596 .g = remap_swizzle(pCreateInfo->components.g, 1597 VK_COMPONENT_SWIZZLE_G, format.swizzle), 1598 .b = remap_swizzle(pCreateInfo->components.b, 1599 VK_COMPONENT_SWIZZLE_B, format.swizzle), 1600 .a = remap_swizzle(pCreateInfo->components.a, 1601 VK_COMPONENT_SWIZZLE_A, format.swizzle), 1602 }, 1603 }; 1604 1605 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) { 1606 iview->planes[vplane].isl.base_array_layer = 0; 1607 iview->planes[vplane].isl.array_len = iview->extent.depth; 1608 } 1609 1610 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE || 1611 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { 1612 iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT; 1613 } else { 1614 iview->planes[vplane].isl.usage = 0; 1615 } 1616 1617 if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT || 1618 (view_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT && 1619 !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) { 1620 iview->planes[vplane].optimal_sampler_surface_state.state = alloc_surface_state(device); 1621 iview->planes[vplane].general_sampler_surface_state.state = alloc_surface_state(device); 1622 1623 enum isl_aux_usage general_aux_usage = 1624 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit, 1625 VK_IMAGE_LAYOUT_GENERAL); 1626 enum isl_aux_usage optimal_aux_usage = 1627 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit, 1628 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); 1629 1630 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 1631 &iview->planes[vplane].isl, 1632 ISL_SURF_USAGE_TEXTURE_BIT, 1633 optimal_aux_usage, NULL, 1634 ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL, 1635 &iview->planes[vplane].optimal_sampler_surface_state, 1636 NULL); 1637 1638 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 1639 &iview->planes[vplane].isl, 1640 ISL_SURF_USAGE_TEXTURE_BIT, 1641 general_aux_usage, NULL, 1642 0, 1643 &iview->planes[vplane].general_sampler_surface_state, 1644 NULL); 1645 } 1646 1647 /* NOTE: This one needs to go last since it may stomp isl_view.format */ 1648 if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) { 1649 iview->planes[vplane].storage_surface_state.state = alloc_surface_state(device); 1650 iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device); 1651 1652 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 1653 &iview->planes[vplane].isl, 1654 ISL_SURF_USAGE_STORAGE_BIT, 1655 ISL_AUX_USAGE_NONE, NULL, 1656 0, 1657 &iview->planes[vplane].storage_surface_state, 1658 &iview->planes[vplane].storage_image_param); 1659 1660 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit, 1661 &iview->planes[vplane].isl, 1662 ISL_SURF_USAGE_STORAGE_BIT, 1663 ISL_AUX_USAGE_NONE, NULL, 1664 ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY, 1665 &iview->planes[vplane].writeonly_storage_surface_state, 1666 NULL); 1667 } 1668 1669 vplane++; 1670 } 1671 1672 *pView = anv_image_view_to_handle(iview); 1673 1674 return VK_SUCCESS; 1675} 1676 1677void 1678anv_DestroyImageView(VkDevice _device, VkImageView _iview, 1679 const VkAllocationCallbacks *pAllocator) 1680{ 1681 ANV_FROM_HANDLE(anv_device, device, _device); 1682 ANV_FROM_HANDLE(anv_image_view, iview, _iview); 1683 1684 if (!iview) 1685 return; 1686 1687 for (uint32_t plane = 0; plane < iview->n_planes; plane++) { 1688 if (iview->planes[plane].optimal_sampler_surface_state.state.alloc_size > 0) { 1689 anv_state_pool_free(&device->surface_state_pool, 1690 iview->planes[plane].optimal_sampler_surface_state.state); 1691 } 1692 1693 if (iview->planes[plane].general_sampler_surface_state.state.alloc_size > 0) { 1694 anv_state_pool_free(&device->surface_state_pool, 1695 iview->planes[plane].general_sampler_surface_state.state); 1696 } 1697 1698 if (iview->planes[plane].storage_surface_state.state.alloc_size > 0) { 1699 anv_state_pool_free(&device->surface_state_pool, 1700 iview->planes[plane].storage_surface_state.state); 1701 } 1702 1703 if (iview->planes[plane].writeonly_storage_surface_state.state.alloc_size > 0) { 1704 anv_state_pool_free(&device->surface_state_pool, 1705 iview->planes[plane].writeonly_storage_surface_state.state); 1706 } 1707 } 1708 1709 vk_free2(&device->alloc, pAllocator, iview); 1710} 1711 1712 1713VkResult 1714anv_CreateBufferView(VkDevice _device, 1715 const VkBufferViewCreateInfo *pCreateInfo, 1716 const VkAllocationCallbacks *pAllocator, 1717 VkBufferView *pView) 1718{ 1719 ANV_FROM_HANDLE(anv_device, device, _device); 1720 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer); 1721 struct anv_buffer_view *view; 1722 1723 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8, 1724 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 1725 if (!view) 1726 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 1727 1728 /* TODO: Handle the format swizzle? */ 1729 1730 view->format = anv_get_isl_format(&device->info, pCreateInfo->format, 1731 VK_IMAGE_ASPECT_COLOR_BIT, 1732 VK_IMAGE_TILING_LINEAR); 1733 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8; 1734 view->range = anv_buffer_get_range(buffer, pCreateInfo->offset, 1735 pCreateInfo->range); 1736 view->range = align_down_npot_u32(view->range, format_bs); 1737 1738 view->address = anv_address_add(buffer->address, pCreateInfo->offset); 1739 1740 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { 1741 view->surface_state = alloc_surface_state(device); 1742 1743 anv_fill_buffer_surface_state(device, view->surface_state, 1744 view->format, 1745 view->address, view->range, format_bs); 1746 } else { 1747 view->surface_state = (struct anv_state){ 0 }; 1748 } 1749 1750 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { 1751 view->storage_surface_state = alloc_surface_state(device); 1752 view->writeonly_storage_surface_state = alloc_surface_state(device); 1753 1754 enum isl_format storage_format = 1755 isl_has_matching_typed_storage_image_format(&device->info, 1756 view->format) ? 1757 isl_lower_storage_image_format(&device->info, view->format) : 1758 ISL_FORMAT_RAW; 1759 1760 anv_fill_buffer_surface_state(device, view->storage_surface_state, 1761 storage_format, 1762 view->address, view->range, 1763 (storage_format == ISL_FORMAT_RAW ? 1 : 1764 isl_format_get_layout(storage_format)->bpb / 8)); 1765 1766 /* Write-only accesses should use the original format. */ 1767 anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state, 1768 view->format, 1769 view->address, view->range, 1770 isl_format_get_layout(view->format)->bpb / 8); 1771 1772 isl_buffer_fill_image_param(&device->isl_dev, 1773 &view->storage_image_param, 1774 view->format, view->range); 1775 } else { 1776 view->storage_surface_state = (struct anv_state){ 0 }; 1777 view->writeonly_storage_surface_state = (struct anv_state){ 0 }; 1778 } 1779 1780 *pView = anv_buffer_view_to_handle(view); 1781 1782 return VK_SUCCESS; 1783} 1784 1785void 1786anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, 1787 const VkAllocationCallbacks *pAllocator) 1788{ 1789 ANV_FROM_HANDLE(anv_device, device, _device); 1790 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView); 1791 1792 if (!view) 1793 return; 1794 1795 if (view->surface_state.alloc_size > 0) 1796 anv_state_pool_free(&device->surface_state_pool, 1797 view->surface_state); 1798 1799 if (view->storage_surface_state.alloc_size > 0) 1800 anv_state_pool_free(&device->surface_state_pool, 1801 view->storage_surface_state); 1802 1803 if (view->writeonly_storage_surface_state.alloc_size > 0) 1804 anv_state_pool_free(&device->surface_state_pool, 1805 view->writeonly_storage_surface_state); 1806 1807 vk_free2(&device->alloc, pAllocator, view); 1808} 1809 1810const struct anv_surface * 1811anv_image_get_surface_for_aspect_mask(const struct anv_image *image, 1812 VkImageAspectFlags aspect_mask) 1813{ 1814 VkImageAspectFlags sanitized_mask; 1815 1816 switch (aspect_mask) { 1817 case VK_IMAGE_ASPECT_COLOR_BIT: 1818 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); 1819 sanitized_mask = VK_IMAGE_ASPECT_COLOR_BIT; 1820 break; 1821 case VK_IMAGE_ASPECT_DEPTH_BIT: 1822 assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT); 1823 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT; 1824 break; 1825 case VK_IMAGE_ASPECT_STENCIL_BIT: 1826 assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT); 1827 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT; 1828 break; 1829 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 1830 /* FINISHME: The Vulkan spec (git a511ba2) requires support for 1831 * combined depth stencil formats. Specifically, it states: 1832 * 1833 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or 1834 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported. 1835 * 1836 * Image views with both depth and stencil aspects are only valid for 1837 * render target attachments, in which case 1838 * cmd_buffer_emit_depth_stencil() will pick out both the depth and 1839 * stencil surfaces from the underlying surface. 1840 */ 1841 if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 1842 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT; 1843 } else { 1844 assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT); 1845 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT; 1846 } 1847 break; 1848 case VK_IMAGE_ASPECT_PLANE_0_BIT: 1849 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0); 1850 sanitized_mask = VK_IMAGE_ASPECT_PLANE_0_BIT; 1851 break; 1852 case VK_IMAGE_ASPECT_PLANE_1_BIT: 1853 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0); 1854 sanitized_mask = VK_IMAGE_ASPECT_PLANE_1_BIT; 1855 break; 1856 case VK_IMAGE_ASPECT_PLANE_2_BIT: 1857 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0); 1858 sanitized_mask = VK_IMAGE_ASPECT_PLANE_2_BIT; 1859 break; 1860 default: 1861 unreachable("image does not have aspect"); 1862 return NULL; 1863 } 1864 1865 uint32_t plane = anv_image_aspect_to_plane(image->aspects, sanitized_mask); 1866 return &image->planes[plane].surface; 1867} 1868