anv_image.c revision e3bfa959a836eae4460c4640158d01d4257c883a
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 30#include "anv_private.h" 31#include "util/debug.h" 32 33#include "vk_format_info.h" 34 35/** 36 * Exactly one bit must be set in \a aspect. 37 */ 38static isl_surf_usage_flags_t 39choose_isl_surf_usage(VkImageUsageFlags vk_usage, 40 VkImageAspectFlags aspect) 41{ 42 isl_surf_usage_flags_t isl_usage = 0; 43 44 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT) 45 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 46 47 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) 48 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 49 50 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) 51 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 52 53 if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT) 54 isl_usage |= ISL_SURF_USAGE_CUBE_BIT; 55 56 /* Even if we're only using it for transfer operations, clears to depth and 57 * stencil images happen as depth and stencil so they need the right ISL 58 * usage bits or else things will fall apart. 59 */ 60 switch (aspect) { 61 case VK_IMAGE_ASPECT_DEPTH_BIT: 62 isl_usage |= ISL_SURF_USAGE_DEPTH_BIT; 63 break; 64 case VK_IMAGE_ASPECT_STENCIL_BIT: 65 isl_usage |= ISL_SURF_USAGE_STENCIL_BIT; 66 break; 67 case VK_IMAGE_ASPECT_COLOR_BIT: 68 break; 69 default: 70 unreachable("bad VkImageAspect"); 71 } 72 73 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) { 74 /* blorp implements transfers by sampling from the source image. */ 75 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT; 76 } 77 78 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT && 79 aspect == VK_IMAGE_ASPECT_COLOR_BIT) { 80 /* blorp implements transfers by rendering into the destination image. 81 * Only request this with color images, as we deal with depth/stencil 82 * formats differently. */ 83 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT; 84 } 85 86 return isl_usage; 87} 88 89/** 90 * Exactly one bit must be set in \a aspect. 91 */ 92static struct anv_surface * 93get_surface(struct anv_image *image, VkImageAspectFlags aspect) 94{ 95 switch (aspect) { 96 default: 97 unreachable("bad VkImageAspect"); 98 case VK_IMAGE_ASPECT_COLOR_BIT: 99 return &image->color_surface; 100 case VK_IMAGE_ASPECT_DEPTH_BIT: 101 return &image->depth_surface; 102 case VK_IMAGE_ASPECT_STENCIL_BIT: 103 return &image->stencil_surface; 104 } 105} 106 107static void 108add_surface(struct anv_image *image, struct anv_surface *surf) 109{ 110 assert(surf->isl.size > 0); /* isl surface must be initialized */ 111 112 surf->offset = align_u32(image->size, surf->isl.alignment); 113 image->size = surf->offset + surf->isl.size; 114 image->alignment = MAX2(image->alignment, surf->isl.alignment); 115} 116 117/** 118 * Initialize the anv_image::*_surface selected by \a aspect. Then update the 119 * image's memory requirements (that is, the image's size and alignment). 120 * 121 * Exactly one bit must be set in \a aspect. 122 */ 123static VkResult 124make_surface(const struct anv_device *dev, 125 struct anv_image *image, 126 const struct anv_image_create_info *anv_info, 127 VkImageAspectFlags aspect) 128{ 129 const VkImageCreateInfo *vk_info = anv_info->vk_info; 130 bool ok UNUSED; 131 132 static const enum isl_surf_dim vk_to_isl_surf_dim[] = { 133 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D, 134 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D, 135 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D, 136 }; 137 138 /* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the 139 * result with an optionally provided ISL tiling argument. 140 */ 141 isl_tiling_flags_t tiling_flags = 142 (vk_info->tiling == VK_IMAGE_TILING_LINEAR) ? 143 ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK; 144 145 if (anv_info->isl_tiling_flags) 146 tiling_flags &= anv_info->isl_tiling_flags; 147 148 assert(tiling_flags); 149 150 struct anv_surface *anv_surf = get_surface(image, aspect); 151 152 image->extent = anv_sanitize_image_extent(vk_info->imageType, 153 vk_info->extent); 154 155 enum isl_format format = anv_get_isl_format(&dev->info, vk_info->format, 156 aspect, vk_info->tiling); 157 assert(format != ISL_FORMAT_UNSUPPORTED); 158 159 ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl, 160 .dim = vk_to_isl_surf_dim[vk_info->imageType], 161 .format = format, 162 .width = image->extent.width, 163 .height = image->extent.height, 164 .depth = image->extent.depth, 165 .levels = vk_info->mipLevels, 166 .array_len = vk_info->arrayLayers, 167 .samples = vk_info->samples, 168 .min_alignment = 0, 169 .min_pitch = anv_info->stride, 170 .usage = choose_isl_surf_usage(image->usage, aspect), 171 .tiling_flags = tiling_flags); 172 173 /* isl_surf_init() will fail only if provided invalid input. Invalid input 174 * is illegal in Vulkan. 175 */ 176 assert(ok); 177 178 add_surface(image, anv_surf); 179 180 /* Add a HiZ surface to a depth buffer that will be used for rendering. 181 */ 182 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) { 183 /* Allow the user to control HiZ enabling. Disable by default on gen7 184 * because resolves are not currently implemented pre-BDW. 185 */ 186 if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) { 187 /* It will never be used as an attachment, HiZ is pointless. */ 188 } else if (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) { 189 /* From the 1.0.37 spec: 190 * 191 * "An attachment used as an input attachment and depth/stencil 192 * attachment must be in either VK_IMAGE_LAYOUT_GENERAL or 193 * VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL." 194 * 195 * It will never have a layout of 196 * VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, so HiZ is 197 * currently pointless. If transfer operations learn to use the HiZ 198 * buffer, we can enable HiZ for VK_IMAGE_LAYOUT_GENERAL and support 199 * input attachments. 200 */ 201 anv_finishme("Implement HiZ for input attachments"); 202 } else if (!env_var_as_boolean("INTEL_VK_HIZ", dev->info.gen >= 8)) { 203 anv_finishme("Implement gen7 HiZ"); 204 } else if (vk_info->mipLevels > 1) { 205 anv_finishme("Test multi-LOD HiZ"); 206 } else if (vk_info->arrayLayers > 1) { 207 anv_finishme("Implement multi-arrayLayer HiZ clears and resolves"); 208 } else if (dev->info.gen == 8 && vk_info->samples > 1) { 209 anv_finishme("Test gen8 multisampled HiZ"); 210 } else { 211 assert(image->aux_surface.isl.size == 0); 212 isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl, 213 &image->aux_surface.isl); 214 add_surface(image, &image->aux_surface); 215 image->aux_usage = ISL_AUX_USAGE_HIZ; 216 } 217 } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) { 218 if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) { 219 assert(image->aux_surface.isl.size == 0); 220 ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl, 221 &image->aux_surface.isl); 222 if (ok) { 223 add_surface(image, &image->aux_surface); 224 225 /* For images created without MUTABLE_FORMAT_BIT set, we know that 226 * they will always be used with the original format. In 227 * particular, they will always be used with a format that 228 * supports color compression. This means that it's safe to just 229 * leave compression on at all times for these formats. 230 */ 231 if (!(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && 232 isl_format_supports_lossless_compression(&dev->info, format)) { 233 if (vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 234 /* 235 * For now, we leave compression off for anything that may 236 * be used as a storage image. This is because accessing 237 * storage images may involve ccs-incompatible views or even 238 * untyped messages which don't support compression at all. 239 */ 240 anv_finishme("Enable CCS for storage images"); 241 } else { 242 image->aux_usage = ISL_AUX_USAGE_CCS_E; 243 } 244 } 245 } 246 } 247 } 248 249 return VK_SUCCESS; 250} 251 252VkResult 253anv_image_create(VkDevice _device, 254 const struct anv_image_create_info *create_info, 255 const VkAllocationCallbacks* alloc, 256 VkImage *pImage) 257{ 258 ANV_FROM_HANDLE(anv_device, device, _device); 259 const VkImageCreateInfo *pCreateInfo = create_info->vk_info; 260 struct anv_image *image = NULL; 261 VkResult r; 262 263 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO); 264 265 anv_assert(pCreateInfo->mipLevels > 0); 266 anv_assert(pCreateInfo->arrayLayers > 0); 267 anv_assert(pCreateInfo->samples > 0); 268 anv_assert(pCreateInfo->extent.width > 0); 269 anv_assert(pCreateInfo->extent.height > 0); 270 anv_assert(pCreateInfo->extent.depth > 0); 271 272 image = vk_alloc2(&device->alloc, alloc, sizeof(*image), 8, 273 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 274 if (!image) 275 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 276 277 memset(image, 0, sizeof(*image)); 278 image->type = pCreateInfo->imageType; 279 image->extent = pCreateInfo->extent; 280 image->vk_format = pCreateInfo->format; 281 image->aspects = vk_format_aspects(image->vk_format); 282 image->levels = pCreateInfo->mipLevels; 283 image->array_size = pCreateInfo->arrayLayers; 284 image->samples = pCreateInfo->samples; 285 image->usage = pCreateInfo->usage; 286 image->tiling = pCreateInfo->tiling; 287 image->aux_usage = ISL_AUX_USAGE_NONE; 288 289 uint32_t b; 290 for_each_bit(b, image->aspects) { 291 r = make_surface(device, image, create_info, (1 << b)); 292 if (r != VK_SUCCESS) 293 goto fail; 294 } 295 296 *pImage = anv_image_to_handle(image); 297 298 return VK_SUCCESS; 299 300fail: 301 if (image) 302 vk_free2(&device->alloc, alloc, image); 303 304 return r; 305} 306 307VkResult 308anv_CreateImage(VkDevice device, 309 const VkImageCreateInfo *pCreateInfo, 310 const VkAllocationCallbacks *pAllocator, 311 VkImage *pImage) 312{ 313 return anv_image_create(device, 314 &(struct anv_image_create_info) { 315 .vk_info = pCreateInfo, 316 }, 317 pAllocator, 318 pImage); 319} 320 321void 322anv_DestroyImage(VkDevice _device, VkImage _image, 323 const VkAllocationCallbacks *pAllocator) 324{ 325 ANV_FROM_HANDLE(anv_device, device, _device); 326 ANV_FROM_HANDLE(anv_image, image, _image); 327 328 if (!image) 329 return; 330 331 vk_free2(&device->alloc, pAllocator, image); 332} 333 334VkResult anv_BindImageMemory( 335 VkDevice _device, 336 VkImage _image, 337 VkDeviceMemory _memory, 338 VkDeviceSize memoryOffset) 339{ 340 ANV_FROM_HANDLE(anv_device, device, _device); 341 ANV_FROM_HANDLE(anv_device_memory, mem, _memory); 342 ANV_FROM_HANDLE(anv_image, image, _image); 343 344 if (mem) { 345 image->bo = &mem->bo; 346 image->offset = memoryOffset; 347 } else { 348 image->bo = NULL; 349 image->offset = 0; 350 } 351 352 if (image->aux_surface.isl.size > 0) { 353 354 /* The offset and size must be a multiple of 4K or else the 355 * anv_gem_mmap call below will return NULL. 356 */ 357 assert((image->offset + image->aux_surface.offset) % 4096 == 0); 358 assert(image->aux_surface.isl.size % 4096 == 0); 359 360 /* Auxiliary surfaces need to have their memory cleared to 0 before they 361 * can be used. For CCS surfaces, this puts them in the "resolved" 362 * state so they can be used with CCS enabled before we ever touch it 363 * from the GPU. For HiZ, we need something valid or else we may get 364 * GPU hangs on some hardware and 0 works fine. 365 */ 366 void *map = anv_gem_mmap(device, image->bo->gem_handle, 367 image->offset + image->aux_surface.offset, 368 image->aux_surface.isl.size, 369 device->info.has_llc ? 0 : I915_MMAP_WC); 370 371 /* If anv_gem_mmap returns NULL, it's likely that the kernel was 372 * not able to find space on the host to create a proper mapping. 373 */ 374 if (map == NULL) 375 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 376 377 memset(map, 0, image->aux_surface.isl.size); 378 379 anv_gem_munmap(map, image->aux_surface.isl.size); 380 } 381 382 return VK_SUCCESS; 383} 384 385static void 386anv_surface_get_subresource_layout(struct anv_image *image, 387 struct anv_surface *surface, 388 const VkImageSubresource *subresource, 389 VkSubresourceLayout *layout) 390{ 391 /* If we are on a non-zero mip level or array slice, we need to 392 * calculate a real offset. 393 */ 394 anv_assert(subresource->mipLevel == 0); 395 anv_assert(subresource->arrayLayer == 0); 396 397 layout->offset = surface->offset; 398 layout->rowPitch = surface->isl.row_pitch; 399 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl); 400 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl); 401 layout->size = surface->isl.size; 402} 403 404void anv_GetImageSubresourceLayout( 405 VkDevice device, 406 VkImage _image, 407 const VkImageSubresource* pSubresource, 408 VkSubresourceLayout* pLayout) 409{ 410 ANV_FROM_HANDLE(anv_image, image, _image); 411 412 assert(__builtin_popcount(pSubresource->aspectMask) == 1); 413 414 switch (pSubresource->aspectMask) { 415 case VK_IMAGE_ASPECT_COLOR_BIT: 416 anv_surface_get_subresource_layout(image, &image->color_surface, 417 pSubresource, pLayout); 418 break; 419 case VK_IMAGE_ASPECT_DEPTH_BIT: 420 anv_surface_get_subresource_layout(image, &image->depth_surface, 421 pSubresource, pLayout); 422 break; 423 case VK_IMAGE_ASPECT_STENCIL_BIT: 424 anv_surface_get_subresource_layout(image, &image->stencil_surface, 425 pSubresource, pLayout); 426 break; 427 default: 428 assert(!"Invalid image aspect"); 429 } 430} 431 432static struct anv_state 433alloc_surface_state(struct anv_device *device) 434{ 435 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64); 436} 437 438static enum isl_channel_select 439remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component, 440 struct isl_swizzle format_swizzle) 441{ 442 if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY) 443 swizzle = component; 444 445 switch (swizzle) { 446 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO; 447 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE; 448 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r; 449 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g; 450 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b; 451 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a; 452 default: 453 unreachable("Invalid swizzle"); 454 } 455} 456 457 458VkResult 459anv_CreateImageView(VkDevice _device, 460 const VkImageViewCreateInfo *pCreateInfo, 461 const VkAllocationCallbacks *pAllocator, 462 VkImageView *pView) 463{ 464 ANV_FROM_HANDLE(anv_device, device, _device); 465 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image); 466 struct anv_image_view *iview; 467 468 iview = vk_alloc2(&device->alloc, pAllocator, sizeof(*iview), 8, 469 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 470 if (iview == NULL) 471 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 472 473 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange; 474 475 assert(range->layerCount > 0); 476 assert(range->baseMipLevel < image->levels); 477 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | 478 VK_IMAGE_USAGE_STORAGE_BIT | 479 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | 480 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)); 481 482 switch (image->type) { 483 default: 484 unreachable("bad VkImageType"); 485 case VK_IMAGE_TYPE_1D: 486 case VK_IMAGE_TYPE_2D: 487 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size); 488 break; 489 case VK_IMAGE_TYPE_3D: 490 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 491 <= anv_minify(image->extent.depth, range->baseMipLevel)); 492 break; 493 } 494 495 const struct anv_surface *surface = 496 anv_image_get_surface_for_aspect_mask(image, range->aspectMask); 497 498 iview->image = image; 499 iview->bo = image->bo; 500 iview->offset = image->offset + surface->offset; 501 502 iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask; 503 iview->vk_format = pCreateInfo->format; 504 505 struct anv_format format = anv_get_format(&device->info, pCreateInfo->format, 506 range->aspectMask, image->tiling); 507 508 iview->isl = (struct isl_view) { 509 .format = format.isl_format, 510 .base_level = range->baseMipLevel, 511 .levels = anv_get_levelCount(image, range), 512 .base_array_layer = range->baseArrayLayer, 513 .array_len = anv_get_layerCount(image, range), 514 .swizzle = { 515 .r = remap_swizzle(pCreateInfo->components.r, 516 VK_COMPONENT_SWIZZLE_R, format.swizzle), 517 .g = remap_swizzle(pCreateInfo->components.g, 518 VK_COMPONENT_SWIZZLE_G, format.swizzle), 519 .b = remap_swizzle(pCreateInfo->components.b, 520 VK_COMPONENT_SWIZZLE_B, format.swizzle), 521 .a = remap_swizzle(pCreateInfo->components.a, 522 VK_COMPONENT_SWIZZLE_A, format.swizzle), 523 }, 524 }; 525 526 iview->extent = (VkExtent3D) { 527 .width = anv_minify(image->extent.width , range->baseMipLevel), 528 .height = anv_minify(image->extent.height, range->baseMipLevel), 529 .depth = anv_minify(image->extent.depth , range->baseMipLevel), 530 }; 531 532 if (image->type == VK_IMAGE_TYPE_3D) { 533 iview->isl.base_array_layer = 0; 534 iview->isl.array_len = iview->extent.depth; 535 } 536 537 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE || 538 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) { 539 iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT; 540 } else { 541 iview->isl.usage = 0; 542 } 543 544 /* If the HiZ buffer can be sampled from, set the constant clear color. 545 * If it cannot, disable the isl aux usage flag. 546 */ 547 float red_clear_color = 0.0f; 548 enum isl_aux_usage surf_usage = image->aux_usage; 549 if (image->aux_usage == ISL_AUX_USAGE_HIZ) { 550 if (iview->aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT && 551 anv_can_sample_with_hiz(device->info.gen, image->samples)) { 552 /* When a HiZ buffer is sampled on gen9+, ensure that 553 * the constant fast clear value is set in the surface state. 554 */ 555 if (device->info.gen >= 9) 556 red_clear_color = ANV_HZ_FC_VAL; 557 } else { 558 surf_usage = ISL_AUX_USAGE_NONE; 559 } 560 } 561 562 /* Input attachment surfaces for color are allocated and filled 563 * out at BeginRenderPass time because they need compression information. 564 * Compression is not yet enabled for depth textures and stencil doesn't 565 * allow compression so we can just use the texture surface state from the 566 * view. 567 */ 568 if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT || 569 (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT && 570 !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) { 571 iview->sampler_surface_state = alloc_surface_state(device); 572 573 struct isl_view view = iview->isl; 574 view.usage |= ISL_SURF_USAGE_TEXTURE_BIT; 575 isl_surf_fill_state(&device->isl_dev, 576 iview->sampler_surface_state.map, 577 .surf = &surface->isl, 578 .view = &view, 579 .clear_color.f32 = { red_clear_color,}, 580 .aux_surf = &image->aux_surface.isl, 581 .aux_usage = surf_usage, 582 .mocs = device->default_mocs); 583 584 if (!device->info.has_llc) 585 anv_state_clflush(iview->sampler_surface_state); 586 } else { 587 iview->sampler_surface_state.alloc_size = 0; 588 } 589 590 /* NOTE: This one needs to go last since it may stomp isl_view.format */ 591 if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) { 592 iview->storage_surface_state = alloc_surface_state(device); 593 594 if (isl_has_matching_typed_storage_image_format(&device->info, 595 format.isl_format)) { 596 struct isl_view view = iview->isl; 597 view.usage |= ISL_SURF_USAGE_STORAGE_BIT; 598 view.format = isl_lower_storage_image_format(&device->info, 599 format.isl_format); 600 isl_surf_fill_state(&device->isl_dev, 601 iview->storage_surface_state.map, 602 .surf = &surface->isl, 603 .view = &view, 604 .aux_surf = &image->aux_surface.isl, 605 .aux_usage = surf_usage, 606 .mocs = device->default_mocs); 607 } else { 608 anv_fill_buffer_surface_state(device, iview->storage_surface_state, 609 ISL_FORMAT_RAW, 610 iview->offset, 611 iview->bo->size - iview->offset, 1); 612 } 613 614 isl_surf_fill_image_param(&device->isl_dev, 615 &iview->storage_image_param, 616 &surface->isl, &iview->isl); 617 618 if (!device->info.has_llc) 619 anv_state_clflush(iview->storage_surface_state); 620 } else { 621 iview->storage_surface_state.alloc_size = 0; 622 } 623 624 *pView = anv_image_view_to_handle(iview); 625 626 return VK_SUCCESS; 627} 628 629void 630anv_DestroyImageView(VkDevice _device, VkImageView _iview, 631 const VkAllocationCallbacks *pAllocator) 632{ 633 ANV_FROM_HANDLE(anv_device, device, _device); 634 ANV_FROM_HANDLE(anv_image_view, iview, _iview); 635 636 if (!iview) 637 return; 638 639 if (iview->sampler_surface_state.alloc_size > 0) { 640 anv_state_pool_free(&device->surface_state_pool, 641 iview->sampler_surface_state); 642 } 643 644 if (iview->storage_surface_state.alloc_size > 0) { 645 anv_state_pool_free(&device->surface_state_pool, 646 iview->storage_surface_state); 647 } 648 649 vk_free2(&device->alloc, pAllocator, iview); 650} 651 652 653VkResult 654anv_CreateBufferView(VkDevice _device, 655 const VkBufferViewCreateInfo *pCreateInfo, 656 const VkAllocationCallbacks *pAllocator, 657 VkBufferView *pView) 658{ 659 ANV_FROM_HANDLE(anv_device, device, _device); 660 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer); 661 struct anv_buffer_view *view; 662 663 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8, 664 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 665 if (!view) 666 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); 667 668 /* TODO: Handle the format swizzle? */ 669 670 view->format = anv_get_isl_format(&device->info, pCreateInfo->format, 671 VK_IMAGE_ASPECT_COLOR_BIT, 672 VK_IMAGE_TILING_LINEAR); 673 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8; 674 view->bo = buffer->bo; 675 view->offset = buffer->offset + pCreateInfo->offset; 676 view->range = pCreateInfo->range == VK_WHOLE_SIZE ? 677 buffer->size - pCreateInfo->offset : pCreateInfo->range; 678 view->range = align_down_npot_u32(view->range, format_bs); 679 680 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) { 681 view->surface_state = alloc_surface_state(device); 682 683 anv_fill_buffer_surface_state(device, view->surface_state, 684 view->format, 685 view->offset, view->range, format_bs); 686 } else { 687 view->surface_state = (struct anv_state){ 0 }; 688 } 689 690 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) { 691 view->storage_surface_state = alloc_surface_state(device); 692 693 enum isl_format storage_format = 694 isl_has_matching_typed_storage_image_format(&device->info, 695 view->format) ? 696 isl_lower_storage_image_format(&device->info, view->format) : 697 ISL_FORMAT_RAW; 698 699 anv_fill_buffer_surface_state(device, view->storage_surface_state, 700 storage_format, 701 view->offset, view->range, 702 (storage_format == ISL_FORMAT_RAW ? 1 : 703 isl_format_get_layout(storage_format)->bpb / 8)); 704 705 isl_buffer_fill_image_param(&device->isl_dev, 706 &view->storage_image_param, 707 view->format, view->range); 708 } else { 709 view->storage_surface_state = (struct anv_state){ 0 }; 710 } 711 712 *pView = anv_buffer_view_to_handle(view); 713 714 return VK_SUCCESS; 715} 716 717void 718anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView, 719 const VkAllocationCallbacks *pAllocator) 720{ 721 ANV_FROM_HANDLE(anv_device, device, _device); 722 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView); 723 724 if (!view) 725 return; 726 727 if (view->surface_state.alloc_size > 0) 728 anv_state_pool_free(&device->surface_state_pool, 729 view->surface_state); 730 731 if (view->storage_surface_state.alloc_size > 0) 732 anv_state_pool_free(&device->surface_state_pool, 733 view->storage_surface_state); 734 735 vk_free2(&device->alloc, pAllocator, view); 736} 737 738const struct anv_surface * 739anv_image_get_surface_for_aspect_mask(const struct anv_image *image, 740 VkImageAspectFlags aspect_mask) 741{ 742 switch (aspect_mask) { 743 case VK_IMAGE_ASPECT_COLOR_BIT: 744 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT); 745 return &image->color_surface; 746 case VK_IMAGE_ASPECT_DEPTH_BIT: 747 assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT); 748 return &image->depth_surface; 749 case VK_IMAGE_ASPECT_STENCIL_BIT: 750 assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT); 751 return &image->stencil_surface; 752 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT: 753 /* FINISHME: The Vulkan spec (git a511ba2) requires support for 754 * combined depth stencil formats. Specifically, it states: 755 * 756 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or 757 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported. 758 * 759 * Image views with both depth and stencil aspects are only valid for 760 * render target attachments, in which case 761 * cmd_buffer_emit_depth_stencil() will pick out both the depth and 762 * stencil surfaces from the underlying surface. 763 */ 764 if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 765 return &image->depth_surface; 766 } else { 767 assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT); 768 return &image->stencil_surface; 769 } 770 default: 771 unreachable("image does not have aspect"); 772 return NULL; 773 } 774} 775