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