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