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