Path: blob/21.2-virgl/src/intel/vulkan/anv_image.c
4547 views
/*1* Copyright © 2015 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR15* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,16* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL17* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER18* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING19* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS20* IN THE SOFTWARE.21*/2223#include <assert.h>24#include <stdbool.h>25#include <string.h>26#include <unistd.h>27#include <fcntl.h>28#include <sys/mman.h>29#include "drm-uapi/drm_fourcc.h"3031#include "anv_private.h"32#include "util/debug.h"33#include "vk_util.h"34#include "util/u_math.h"3536#include "vk_format.h"3738#define ANV_OFFSET_IMPLICIT UINT64_MAX3940static const enum isl_surf_dim41vk_to_isl_surf_dim[] = {42[VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,43[VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,44[VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,45};4647static uint64_t MUST_CHECK UNUSED48memory_range_end(struct anv_image_memory_range memory_range)49{50assert(anv_is_aligned(memory_range.offset, memory_range.alignment));51return memory_range.offset + memory_range.size;52}5354/**55* Get binding for VkImagePlaneMemoryRequirementsInfo and56* VkBindImagePlaneMemoryInfo.57*/58static struct anv_image_binding *59image_aspect_to_binding(struct anv_image *image, VkImageAspectFlags aspect)60{61uint32_t plane;6263assert(image->disjoint);6465if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {66/* Spec requires special aspects for modifier images. */67assert(aspect >= VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT &&68aspect <= VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT);6970/* We don't advertise DISJOINT for modifiers with aux, and therefore we71* don't handle queries of the modifier's "aux plane" here.72*/73assert(!isl_drm_modifier_has_aux(image->drm_format_mod));7475plane = aspect - VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT;76} else {77plane = anv_image_aspect_to_plane(image->aspects, aspect);78}7980return &image->bindings[ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane];81}8283/**84* Extend the memory binding's range by appending a new memory range with `size`85* and `alignment` at `offset`. Return the appended range.86*87* Offset is ignored if ANV_OFFSET_IMPLICIT.88*89* The given binding must not be ANV_IMAGE_MEMORY_BINDING_MAIN. The function90* converts to MAIN as needed.91*/92static VkResult MUST_CHECK93image_binding_grow(const struct anv_device *device,94struct anv_image *image,95enum anv_image_memory_binding binding,96uint64_t offset,97uint64_t size,98uint32_t alignment,99struct anv_image_memory_range *out_range)100{101/* We overwrite 'offset' but need to remember if it was implicit. */102const bool has_implicit_offset = (offset == ANV_OFFSET_IMPLICIT);103104assert(size > 0);105assert(util_is_power_of_two_or_zero(alignment));106107switch (binding) {108case ANV_IMAGE_MEMORY_BINDING_MAIN:109/* The caller must not pre-translate BINDING_PLANE_i to BINDING_MAIN. */110unreachable("ANV_IMAGE_MEMORY_BINDING_MAIN");111case ANV_IMAGE_MEMORY_BINDING_PLANE_0:112case ANV_IMAGE_MEMORY_BINDING_PLANE_1:113case ANV_IMAGE_MEMORY_BINDING_PLANE_2:114if (!image->disjoint)115binding = ANV_IMAGE_MEMORY_BINDING_MAIN;116break;117case ANV_IMAGE_MEMORY_BINDING_PRIVATE:118assert(offset == ANV_OFFSET_IMPLICIT);119break;120case ANV_IMAGE_MEMORY_BINDING_END:121unreachable("ANV_IMAGE_MEMORY_BINDING_END");122}123124struct anv_image_memory_range *container =125&image->bindings[binding].memory_range;126127if (has_implicit_offset) {128offset = align_u64(container->offset + container->size, alignment);129} else {130/* Offset must be validated because it comes from131* VkImageDrmFormatModifierExplicitCreateInfoEXT.132*/133if (unlikely(!anv_is_aligned(offset, alignment))) {134return vk_errorf(device, &device->vk.base,135VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT,136"VkImageDrmFormatModifierExplicitCreateInfoEXT::"137"pPlaneLayouts[]::offset is misaligned");138}139140/* We require that surfaces be added in memory-order. This simplifies the141* layout validation required by142* VkImageDrmFormatModifierExplicitCreateInfoEXT,143*/144if (unlikely(offset < container->size)) {145return vk_errorf(device, &device->vk.base,146VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT,147"VkImageDrmFormatModifierExplicitCreateInfoEXT::"148"pPlaneLayouts[]::offset is too small");149}150}151152if (__builtin_add_overflow(offset, size, &container->size)) {153if (has_implicit_offset) {154assert(!"overflow");155return vk_errorf(device, &device->vk.base,156VK_ERROR_UNKNOWN,157"internal error: overflow in %s", __func__);158} else {159return vk_errorf(device, &device->vk.base,160VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT,161"VkImageDrmFormatModifierExplicitCreateInfoEXT::"162"pPlaneLayouts[]::offset is too large");163}164}165166container->alignment = MAX2(container->alignment, alignment);167168*out_range = (struct anv_image_memory_range) {169.binding = binding,170.offset = offset,171.size = size,172.alignment = alignment,173};174175return VK_SUCCESS;176}177178/**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*/184static void185memory_range_merge(struct anv_image_memory_range *a,186const struct anv_image_memory_range b)187{188if (b.size == 0)189return;190191if (a->binding != b.binding)192return;193194assert(a->offset == 0);195assert(anv_is_aligned(a->offset, a->alignment));196assert(anv_is_aligned(b.offset, b.alignment));197198a->alignment = MAX2(a->alignment, b.alignment);199a->size = MAX2(a->size, b.offset + b.size);200}201202static isl_surf_usage_flags_t203choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,204VkImageUsageFlags vk_usage,205isl_surf_usage_flags_t isl_extra_usage,206VkImageAspectFlagBits aspect)207{208isl_surf_usage_flags_t isl_usage = isl_extra_usage;209210if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)211isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;212213if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)214isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;215216if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)217isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;218219if (vk_create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)220isl_usage |= ISL_SURF_USAGE_CUBE_BIT;221222/* Even if we're only using it for transfer operations, clears to depth and223* stencil images happen as depth and stencil so they need the right ISL224* usage bits or else things will fall apart.225*/226switch (aspect) {227case VK_IMAGE_ASPECT_DEPTH_BIT:228isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;229break;230case VK_IMAGE_ASPECT_STENCIL_BIT:231isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;232break;233case VK_IMAGE_ASPECT_COLOR_BIT:234case VK_IMAGE_ASPECT_PLANE_0_BIT:235case VK_IMAGE_ASPECT_PLANE_1_BIT:236case VK_IMAGE_ASPECT_PLANE_2_BIT:237break;238default:239unreachable("bad VkImageAspect");240}241242if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {243/* blorp implements transfers by sampling from the source image. */244isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;245}246247if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&248aspect == 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/stencil251* formats differently. */252isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;253}254255return isl_usage;256}257258static isl_tiling_flags_t259choose_isl_tiling_flags(const struct intel_device_info *devinfo,260const struct anv_image_create_info *anv_info,261const struct isl_drm_modifier_info *isl_mod_info,262bool legacy_scanout)263{264const VkImageCreateInfo *base_info = anv_info->vk_info;265isl_tiling_flags_t flags = 0;266267assert((isl_mod_info != NULL) ==268(base_info->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT));269270switch (base_info->tiling) {271default:272unreachable("bad VkImageTiling");273case VK_IMAGE_TILING_OPTIMAL:274flags = ISL_TILING_ANY_MASK;275break;276case VK_IMAGE_TILING_LINEAR:277flags = ISL_TILING_LINEAR_BIT;278break;279case VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT:280flags = 1 << isl_mod_info->tiling;281}282283if (anv_info->isl_tiling_flags) {284assert(isl_mod_info == NULL);285flags &= anv_info->isl_tiling_flags;286}287288if (legacy_scanout) {289isl_tiling_flags_t legacy_mask = ISL_TILING_LINEAR_BIT;290if (devinfo->has_tiling_uapi)291legacy_mask |= ISL_TILING_X_BIT;292flags &= legacy_mask;293}294295assert(flags);296297return flags;298}299300/**301* Add the surface to the binding at the given offset.302*303* \see image_binding_grow()304*/305static VkResult MUST_CHECK306add_surface(struct anv_device *device,307struct anv_image *image,308struct anv_surface *surf,309enum anv_image_memory_binding binding,310uint64_t offset)311{312/* isl surface must be initialized */313assert(surf->isl.size_B > 0);314315return image_binding_grow(device, image, binding, offset,316surf->isl.size_B,317surf->isl.alignment_B,318&surf->memory_range);319}320321/**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 same325* limitations may also constrain the tiling of the primary surface; therefore326* paramater @a inout_primary_tiling_flags.327*328* If the image plane is a separate stencil plane and if the user provided329* VkImageStencilUsageCreateInfoEXT, then @a usage must be stencilUsage.330*331* @see anv_image::planes[]::shadow_surface332*/333static bool334anv_image_plane_needs_shadow_surface(const struct intel_device_info *devinfo,335struct anv_format_plane plane_format,336VkImageTiling vk_tiling,337VkImageUsageFlags vk_plane_usage,338VkImageCreateFlags vk_create_flags,339isl_tiling_flags_t *inout_primary_tiling_flags)340{341if (devinfo->ver <= 8 &&342(vk_create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&343vk_tiling == VK_IMAGE_TILING_OPTIMAL) {344/* We must fallback to a linear surface because we may not be able to345* correctly handle the offsets if tiled. (On gfx9,346* RENDER_SURFACE_STATE::X/Y Offset are sufficient). To prevent garbage347* performance while texturing, we maintain a tiled shadow surface.348*/349assert(isl_format_is_compressed(plane_format.isl_format));350351if (inout_primary_tiling_flags) {352*inout_primary_tiling_flags = ISL_TILING_LINEAR_BIT;353}354355return true;356}357358if (devinfo->ver <= 7 &&359plane_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. */362return true;363}364365return false;366}367368bool369anv_formats_ccs_e_compatible(const struct intel_device_info *devinfo,370VkImageCreateFlags create_flags,371VkFormat vk_format,372VkImageTiling vk_tiling,373const VkImageFormatListCreateInfoKHR *fmt_list)374{375enum isl_format format =376anv_get_isl_format(devinfo, vk_format,377VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);378379if (!isl_format_supports_ccs_e(devinfo, format))380return false;381382if (!(create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))383return true;384385if (!fmt_list || fmt_list->viewFormatCount == 0)386return false;387388for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {389enum isl_format view_format =390anv_get_isl_format(devinfo, fmt_list->pViewFormats[i],391VK_IMAGE_ASPECT_COLOR_BIT, vk_tiling);392393if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format))394return false;395}396397return true;398}399400/**401* For color images that have an auxiliary surface, request allocation for an402* additional buffer that mainly stores fast-clear values. Use of this buffer403* allows us to access the image's subresources while being aware of their404* fast-clear values in non-trivial cases (e.g., outside of a render pass in405* which a fast clear has occurred).406*407* In order to avoid having multiple clear colors for a single plane of an408* image (hence a single RENDER_SURFACE_STATE), we only allow fast-clears on409* 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 color416* * 1 dword for the anv_fast_clear_type of the clear color417* * On gfx9+, 1 dword per level and layer of the image (3D levels count418* multiple layers) in level-major order for compression state.419*420* For the purpose of discoverability, the algorithm used to manage421* 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 initialized425* to default values.426*427* * On fast-clear, the clear value is written into surface state and also428* into the buffer and the fast clear type is set appropriately. Both429* setting the fast-clear value in the buffer and setting the fast-clear430* type happen from the GPU using MI commands.431*432* * Whenever a render or blorp operation is performed with CCS_E, we call433* genX(cmd_buffer_mark_image_written) to set the compression state to434* true (which is represented by UINT32_MAX).435*436* * On pipeline barrier transitions, the worst-case transition is computed437* from the image layouts. The command streamer inspects the fast clear438* type and compression state dwords and constructs a predicate. The439* worst-case resolve is performed with the given predicate and the fast440* clear and compression state is set accordingly.441*442* See anv_layout_to_aux_usage and anv_layout_to_fast_clear_type functions for443* 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 clear449* 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 into452* blorp and it knows to copy the clear color.453*/454static VkResult MUST_CHECK455add_aux_state_tracking_buffer(struct anv_device *device,456struct anv_image *image,457uint32_t plane)458{459assert(image && device);460assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_NONE &&461image->aspects & (VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV |462VK_IMAGE_ASPECT_DEPTH_BIT));463464const unsigned clear_color_state_size = device->info.ver >= 10 ?465device->isl_dev.ss.clear_color_state_size :466device->isl_dev.ss.clear_value_size;467468/* Clear color and fast clear type */469unsigned state_size = clear_color_state_size + 4;470471/* We only need to track compression on CCS_E surfaces. */472if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) {473if (image->type == VK_IMAGE_TYPE_3D) {474for (uint32_t l = 0; l < image->levels; l++)475state_size += anv_minify(image->extent.depth, l) * 4;476} else {477state_size += image->levels * image->array_size * 4;478}479}480481enum anv_image_memory_binding binding =482ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane;483484if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID)485binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE;486487/* We believe that 256B alignment may be sufficient, but we choose 4K due to488* lack of testing. And MI_LOAD/STORE operations require dword-alignment.489*/490return image_binding_grow(device, image, binding,491ANV_OFFSET_IMPLICIT, state_size, 4096,492&image->planes[plane].fast_clear_memory_range);493}494495/**496* The return code indicates whether creation of the VkImage should continue497* or fail, not whether the creation of the aux surface succeeded. If the aux498* surface is not required (for example, by neither hardware nor DRM format499* modifier), then this may return VK_SUCCESS when creation of the aux surface500* fails.501*502* @param offset See add_surface()503*/504static VkResult505add_aux_surface_if_supported(struct anv_device *device,506struct anv_image *image,507uint32_t plane,508struct anv_format_plane plane_format,509const VkImageFormatListCreateInfoKHR *fmt_list,510uint64_t offset,511uint32_t stride,512isl_surf_usage_flags_t isl_extra_usage_flags)513{514VkImageAspectFlags aspect = plane_format.aspect;515VkResult result;516bool ok;517518/* The aux surface must not be already added. */519assert(!anv_surface_is_valid(&image->planes[plane].aux_surface));520521if ((isl_extra_usage_flags & ISL_SURF_USAGE_DISABLE_AUX_BIT))522return VK_SUCCESS;523524if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {525/* We don't advertise that depth buffers could be used as storage526* images.527*/528assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));529530/* Allow the user to control HiZ enabling. Disable by default on gfx7531* because resolves are not currently implemented pre-BDW.532*/533if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {534/* It will never be used as an attachment, HiZ is pointless. */535return VK_SUCCESS;536}537538if (device->info.ver == 7) {539anv_perf_warn(device, &image->base, "Implement gfx7 HiZ");540return VK_SUCCESS;541}542543if (image->levels > 1) {544anv_perf_warn(device, &image->base, "Enable multi-LOD HiZ");545return VK_SUCCESS;546}547548if (device->info.ver == 8 && image->samples > 1) {549anv_perf_warn(device, &image->base, "Enable gfx8 multisampled HiZ");550return VK_SUCCESS;551}552553if (INTEL_DEBUG & DEBUG_NO_HIZ)554return VK_SUCCESS;555556ok = isl_surf_get_hiz_surf(&device->isl_dev,557&image->planes[plane].primary_surface.isl,558&image->planes[plane].aux_surface.isl);559assert(ok);560if (!isl_surf_supports_ccs(&device->isl_dev,561&image->planes[plane].primary_surface.isl,562&image->planes[plane].aux_surface.isl)) {563image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;564} else if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |565VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) &&566image->samples == 1) {567/* If it's used as an input attachment or a texture and it's568* single-sampled (this is a requirement for HiZ+CCS write-through569* mode), use write-through mode so that we don't need to resolve570* before texturing. This will make depth testing a bit slower but571* texturing faster.572*573* TODO: This is a heuristic trade-off; we haven't tuned it at all.574*/575assert(device->info.ver >= 12);576image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS_WT;577} else {578assert(device->info.ver >= 12);579image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ_CCS;580}581582result = add_surface(device, image, &image->planes[plane].aux_surface,583ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane,584ANV_OFFSET_IMPLICIT);585if (result != VK_SUCCESS)586return result;587588if (image->planes[plane].aux_usage == ISL_AUX_USAGE_HIZ_CCS_WT)589return add_aux_state_tracking_buffer(device, image, plane);590} else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {591592if (INTEL_DEBUG & DEBUG_NO_RBC)593return VK_SUCCESS;594595if (!isl_surf_supports_ccs(&device->isl_dev,596&image->planes[plane].primary_surface.isl,597NULL))598return VK_SUCCESS;599600image->planes[plane].aux_usage = ISL_AUX_USAGE_STC_CCS;601} else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples == 1) {602if (image->n_planes != 1) {603/* Multiplanar images seem to hit a sampler bug with CCS and R16G16604* format. (Putting the clear state a page/4096bytes further fixes605* the issue).606*/607return VK_SUCCESS;608}609610if ((image->create_flags & VK_IMAGE_CREATE_ALIAS_BIT)) {611/* The image may alias a plane of a multiplanar image. Above we ban612* CCS on multiplanar images.613*614* We must also reject aliasing of any image that uses615* ANV_IMAGE_MEMORY_BINDING_PRIVATE. Since we're already rejecting all616* aliasing here, there's no need to further analyze if the image needs617* a private binding.618*/619return VK_SUCCESS;620}621622if (!isl_format_supports_rendering(&device->info,623plane_format.isl_format)) {624/* Disable CCS because it is not useful (we can't render to the image625* with CCS enabled). While it may be technically possible to enable626* CCS for this case, we currently don't have things hooked up to get627* it working.628*/629anv_perf_warn(device, &image->base,630"This image format doesn't support rendering. "631"Not allocating an CCS buffer.");632return VK_SUCCESS;633}634635if (device->info.ver >= 12 && image->array_size > 1) {636/* HSD 14010672564: On TGL, if a block of fragment shader outputs637* match the surface's clear color, the HW may convert them to638* fast-clears. Anv only does clear color tracking for the first639* slice unfortunately. Disable CCS until anv gains more clear color640* tracking abilities.641*/642anv_perf_warn(device, &image->base,643"HW may put fast-clear blocks on more slices than SW "644"currently tracks. Not allocating a CCS buffer.");645return VK_SUCCESS;646}647648if (INTEL_DEBUG & DEBUG_NO_RBC)649return VK_SUCCESS;650651ok = isl_surf_get_ccs_surf(&device->isl_dev,652&image->planes[plane].primary_surface.isl,653NULL,654&image->planes[plane].aux_surface.isl,655stride);656if (!ok)657return VK_SUCCESS;658659/* Choose aux usage */660if (!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&661anv_formats_ccs_e_compatible(&device->info,662image->create_flags,663image->vk_format,664image->tiling,665fmt_list)) {666/* For images created without MUTABLE_FORMAT_BIT set, we know that667* they will always be used with the original format. In particular,668* they will always be used with a format that supports color669* compression. If it's never used as a storage image, then it will670* only be used through the sampler or the as a render target. This671* means that it's safe to just leave compression on at all times for672* these formats.673*/674image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;675} else if (device->info.ver >= 12) {676anv_perf_warn(device, &image->base,677"The CCS_D aux mode is not yet handled on "678"Gfx12+. Not allocating a CCS buffer.");679image->planes[plane].aux_surface.isl.size_B = 0;680return VK_SUCCESS;681} else {682image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_D;683}684685if (!device->physical->has_implicit_ccs) {686enum anv_image_memory_binding binding =687ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane;688689if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID &&690!isl_drm_modifier_has_aux(image->drm_format_mod))691binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE;692693result = add_surface(device, image, &image->planes[plane].aux_surface,694binding, offset);695if (result != VK_SUCCESS)696return result;697}698699return add_aux_state_tracking_buffer(device, image, plane);700} else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) {701assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));702ok = isl_surf_get_mcs_surf(&device->isl_dev,703&image->planes[plane].primary_surface.isl,704&image->planes[plane].aux_surface.isl);705if (!ok)706return VK_SUCCESS;707708image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS;709710result = add_surface(device, image, &image->planes[plane].aux_surface,711ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane,712ANV_OFFSET_IMPLICIT);713if (result != VK_SUCCESS)714return result;715716return add_aux_state_tracking_buffer(device, image, plane);717}718719return VK_SUCCESS;720}721722static VkResult723add_shadow_surface(struct anv_device *device,724struct anv_image *image,725uint32_t plane,726struct anv_format_plane plane_format,727uint32_t stride,728VkImageUsageFlags vk_plane_usage)729{730ASSERTED bool ok;731732ok = isl_surf_init(&device->isl_dev,733&image->planes[plane].shadow_surface.isl,734.dim = vk_to_isl_surf_dim[image->type],735.format = plane_format.isl_format,736.width = image->extent.width,737.height = image->extent.height,738.depth = image->extent.depth,739.levels = image->levels,740.array_len = image->array_size,741.samples = image->samples,742.min_alignment_B = 0,743.row_pitch_B = stride,744.usage = ISL_SURF_USAGE_TEXTURE_BIT |745(vk_plane_usage & ISL_SURF_USAGE_CUBE_BIT),746.tiling_flags = ISL_TILING_ANY_MASK);747748/* isl_surf_init() will fail only if provided invalid input. Invalid input749* here is illegal in Vulkan.750*/751assert(ok);752753return add_surface(device, image, &image->planes[plane].shadow_surface,754ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane,755ANV_OFFSET_IMPLICIT);756}757758/**759* Initialize the anv_image::*_surface selected by \a aspect. Then update the760* image's memory requirements (that is, the image's size and alignment).761*762* @param offset See add_surface()763*/764static VkResult765add_primary_surface(struct anv_device *device,766struct anv_image *image,767uint32_t plane,768struct anv_format_plane plane_format,769uint64_t offset,770uint32_t stride,771isl_tiling_flags_t isl_tiling_flags,772isl_surf_usage_flags_t isl_usage)773{774struct anv_surface *anv_surf = &image->planes[plane].primary_surface;775bool ok;776777ok = isl_surf_init(&device->isl_dev, &anv_surf->isl,778.dim = vk_to_isl_surf_dim[image->type],779.format = plane_format.isl_format,780.width = image->extent.width / plane_format.denominator_scales[0],781.height = image->extent.height / plane_format.denominator_scales[1],782.depth = image->extent.depth,783.levels = image->levels,784.array_len = image->array_size,785.samples = image->samples,786.min_alignment_B = 0,787.row_pitch_B = stride,788.usage = isl_usage,789.tiling_flags = isl_tiling_flags);790791if (!ok) {792/* TODO: Should return793* VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT in come cases.794*/795return VK_ERROR_OUT_OF_DEVICE_MEMORY;796}797798image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;799800return add_surface(device, image, anv_surf,801ANV_IMAGE_MEMORY_BINDING_PLANE_0 + plane, offset);802}803804#ifndef NDEBUG805static bool MUST_CHECK806memory_range_is_aligned(struct anv_image_memory_range memory_range)807{808return anv_is_aligned(memory_range.offset, memory_range.alignment);809}810#endif811812struct check_memory_range_params {813struct anv_image_memory_range *accum_ranges;814const struct anv_surface *test_surface;815const struct anv_image_memory_range *test_range;816enum anv_image_memory_binding expect_binding;817};818819#define check_memory_range(...) \820check_memory_range_s(&(struct check_memory_range_params) { __VA_ARGS__ })821822static void UNUSED823check_memory_range_s(const struct check_memory_range_params *p)824{825assert((p->test_surface == NULL) != (p->test_range == NULL));826827const struct anv_image_memory_range *test_range =828p->test_range ?: &p->test_surface->memory_range;829830struct anv_image_memory_range *accum_range =831&p->accum_ranges[p->expect_binding];832833assert(test_range->binding == p->expect_binding);834assert(test_range->offset >= memory_range_end(*accum_range));835assert(memory_range_is_aligned(*test_range));836837if (p->test_surface) {838assert(anv_surface_is_valid(p->test_surface));839assert(p->test_surface->memory_range.alignment ==840p->test_surface->isl.alignment_B);841}842843memory_range_merge(accum_range, *test_range);844}845846/**847* Validate the image's memory bindings *after* all its surfaces and memory848* ranges are final.849*850* For simplicity's sake, we do not validate free-form layout of the image's851* memory bindings. We validate the layout described in the comments of struct852* anv_image.853*/854static void855check_memory_bindings(const struct anv_device *device,856const struct anv_image *image)857{858#ifdef DEBUG859/* As we inspect each part of the image, we merge the part's memory range860* into these accumulation ranges.861*/862struct anv_image_memory_range accum_ranges[ANV_IMAGE_MEMORY_BINDING_END];863for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; ++i) {864accum_ranges[i] = (struct anv_image_memory_range) {865.binding = i,866};867}868869for (uint32_t p = 0; p < image->n_planes; ++p) {870const struct anv_image_plane *plane = &image->planes[p];871872/* The binding that must contain the plane's primary surface. */873const enum anv_image_memory_binding primary_binding = image->disjoint874? ANV_IMAGE_MEMORY_BINDING_PLANE_0 + p875: ANV_IMAGE_MEMORY_BINDING_MAIN;876877/* Aliasing is incompatible with the private binding because it does not878* live in a VkDeviceMemory.879*/880assert(!(image->create_flags & VK_IMAGE_CREATE_ALIAS_BIT) ||881image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].memory_range.size == 0);882883/* Check primary surface */884check_memory_range(accum_ranges,885.test_surface = &plane->primary_surface,886.expect_binding = primary_binding);887888/* Check shadow surface */889if (anv_surface_is_valid(&plane->shadow_surface)) {890check_memory_range(accum_ranges,891.test_surface = &plane->shadow_surface,892.expect_binding = primary_binding);893}894895/* Check aux_surface */896if (anv_surface_is_valid(&plane->aux_surface)) {897enum anv_image_memory_binding binding = primary_binding;898899if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID &&900!isl_drm_modifier_has_aux(image->drm_format_mod))901binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE;902903/* Display hardware requires that the aux surface start at904* a higher address than the primary surface. The 3D hardware905* doesn't care, but we enforce the display requirement in case906* the image is sent to display.907*/908check_memory_range(accum_ranges,909.test_surface = &plane->aux_surface,910.expect_binding = binding);911}912913/* Check fast clear state */914if (plane->fast_clear_memory_range.size > 0) {915enum anv_image_memory_binding binding = primary_binding;916917if (image->drm_format_mod != DRM_FORMAT_MOD_INVALID)918binding = ANV_IMAGE_MEMORY_BINDING_PRIVATE;919920/* We believe that 256B alignment may be sufficient, but we choose 4K921* due to lack of testing. And MI_LOAD/STORE operations require922* dword-alignment.923*/924assert(plane->fast_clear_memory_range.alignment == 4096);925check_memory_range(accum_ranges,926.test_range = &plane->fast_clear_memory_range,927.expect_binding = binding);928}929}930#endif931}932933/**934* Check that the fully-initialized anv_image is compatible with its DRM format935* modifier.936*937* Checking compatibility at the end of image creation is prudent, not938* superfluous, because usage of modifiers triggers numerous special cases939* throughout queries and image creation, and because940* vkGetPhysicalDeviceImageFormatProperties2 has difficulty detecting all941* incompatibilities.942*943* Return VK_ERROR_UNKNOWN if the incompatibility is difficult to detect in944* vkGetPhysicalDeviceImageFormatProperties2. Otherwise, assert fail.945*946* Ideally, if vkGetPhysicalDeviceImageFormatProperties2() succeeds with a given947* modifier, then vkCreateImage() produces an image that is compatible with the948* modifier. However, it is difficult to reconcile the two functions to agree949* due to their complexity. For example, isl_surf_get_ccs_surf() may950* unexpectedly fail in vkCreateImage(), eliminating the image's aux surface951* even when the modifier requires one. (Maybe we should reconcile the two952* functions despite the difficulty).953*/954static VkResult MUST_CHECK955check_drm_format_mod(const struct anv_device *device,956const struct anv_image *image)957{958/* Image must have a modifier if and only if it has modifier tiling. */959assert((image->drm_format_mod != DRM_FORMAT_MOD_INVALID) ==960(image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT));961962if (image->drm_format_mod == DRM_FORMAT_MOD_INVALID)963return VK_SUCCESS;964965const struct isl_drm_modifier_info *isl_mod_info =966isl_drm_modifier_get_info(image->drm_format_mod);967968/* Driver must support the modifier. */969assert(isl_drm_modifier_get_score(&device->info, isl_mod_info->modifier));970971/* Enforced by us, not the Vulkan spec. */972assert(image->type == VK_IMAGE_TYPE_2D);973assert(!(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT));974assert(!(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT));975assert(image->levels == 1);976assert(image->array_size == 1);977assert(image->samples == 1);978979for (int i = 0; i < image->n_planes; ++i) {980const struct anv_image_plane *plane = &image->planes[i];981ASSERTED const struct anv_format_plane *plane_format =982&image->format->planes[i];983ASSERTED const struct isl_format_layout *isl_layout =984isl_format_get_layout(plane_format->isl_format);985986/* Enforced by us, not the Vulkan spec. */987assert(isl_layout->txc == ISL_TXC_NONE);988assert(isl_layout->colorspace == ISL_COLORSPACE_LINEAR ||989isl_layout->colorspace == ISL_COLORSPACE_SRGB);990assert(!anv_surface_is_valid(&plane->shadow_surface));991992if (isl_mod_info->aux_usage != ISL_AUX_USAGE_NONE) {993/* Reject DISJOINT for consistency with the GL driver. */994assert(!image->disjoint);995996/* The modifier's required aux usage mandates the image's aux usage.997* The inverse, however, does not hold; if the modifier has no aux998* usage, then we may enable a private aux surface.999*/1000if (plane->aux_usage != isl_mod_info->aux_usage) {1001return vk_errorf(device, &image->base, VK_ERROR_UNKNOWN,1002"image with modifier unexpectedly has wrong aux "1003"usage");1004}1005}1006}10071008return VK_SUCCESS;1009}10101011/**1012* Use when the app does not provide1013* VkImageDrmFormatModifierExplicitCreateInfoEXT.1014*/1015static VkResult MUST_CHECK1016add_all_surfaces_implicit_layout(1017struct anv_device *device,1018struct anv_image *image,1019const VkImageFormatListCreateInfo *format_list_info,1020uint32_t stride,1021isl_tiling_flags_t isl_tiling_flags,1022isl_surf_usage_flags_t isl_extra_usage_flags)1023{1024const struct intel_device_info *devinfo = &device->info;1025VkResult result;10261027u_foreach_bit(b, image->aspects) {1028VkImageAspectFlagBits aspect = 1 << b;1029uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);1030const struct anv_format_plane plane_format =1031anv_get_format_plane(devinfo, image->vk_format, aspect, image->tiling);10321033VkImageUsageFlags vk_usage = image->usage;1034if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT)1035vk_usage = image->stencil_usage;10361037isl_surf_usage_flags_t isl_usage =1038choose_isl_surf_usage(image->create_flags, vk_usage,1039isl_extra_usage_flags, aspect);10401041/* Must call this before adding any surfaces because it may modify1042* isl_tiling_flags.1043*/1044bool needs_shadow =1045anv_image_plane_needs_shadow_surface(devinfo, plane_format,1046image->tiling, vk_usage,1047image->create_flags,1048&isl_tiling_flags);10491050result = add_primary_surface(device, image, plane, plane_format,1051ANV_OFFSET_IMPLICIT, stride,1052isl_tiling_flags, isl_usage);1053if (result != VK_SUCCESS)1054return result;10551056if (needs_shadow) {1057result = add_shadow_surface(device, image, plane, plane_format,1058stride, vk_usage);1059if (result != VK_SUCCESS)1060return result;1061}10621063result = add_aux_surface_if_supported(device, image, plane, plane_format,1064format_list_info,1065ANV_OFFSET_IMPLICIT, stride,1066isl_extra_usage_flags);1067if (result != VK_SUCCESS)1068return result;1069}10701071return VK_SUCCESS;1072}10731074/**1075* Use when the app provides VkImageDrmFormatModifierExplicitCreateInfoEXT.1076*/1077static VkResult1078add_all_surfaces_explicit_layout(1079struct anv_device *device,1080struct anv_image *image,1081const VkImageFormatListCreateInfo *format_list_info,1082const VkImageDrmFormatModifierExplicitCreateInfoEXT *drm_info,1083isl_tiling_flags_t isl_tiling_flags,1084isl_surf_usage_flags_t isl_extra_usage_flags)1085{1086const struct intel_device_info *devinfo = &device->info;1087const uint32_t mod_plane_count = drm_info->drmFormatModifierPlaneCount;1088const bool mod_has_aux =1089isl_drm_modifier_has_aux(drm_info->drmFormatModifier);1090VkResult result;10911092/* About valid usage in the Vulkan spec:1093*1094* Unlike vanilla vkCreateImage, which produces undefined behavior on user1095* error, here the spec requires the implementation to return1096* VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT if the app provides1097* a bad plane layout. However, the spec does require1098* drmFormatModifierPlaneCount to be valid.1099*1100* Most validation of plane layout occurs in add_surface().1101*/11021103/* We support a restricted set of images with modifiers.1104*1105* With aux usage,1106* - Format plane count must be 1.1107* - Memory plane count must be 2.1108* Without aux usage,1109* - Each format plane must map to a distint memory plane.1110*1111* For the other cases, currently there is no way to properly map memory1112* planes to format planes and aux planes due to the lack of defined ABI1113* for external multi-planar images.1114*/1115if (image->n_planes == 1)1116assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);1117else1118assert(!(image->aspects & ~VK_IMAGE_ASPECT_PLANES_BITS_ANV));11191120if (mod_has_aux)1121assert(image->n_planes == 1 && mod_plane_count == 2);1122else1123assert(image->n_planes == mod_plane_count);11241125/* Reject special values in the app-provided plane layouts. */1126for (uint32_t i = 0; i < mod_plane_count; ++i) {1127if (drm_info->pPlaneLayouts[i].rowPitch == 0) {1128return vk_errorf(device, &device->vk.base,1129VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT,1130"VkImageDrmFormatModifierExplicitCreateInfoEXT::"1131"pPlaneLayouts[%u]::rowPitch is 0", i);1132}11331134if (drm_info->pPlaneLayouts[i].offset == ANV_OFFSET_IMPLICIT) {1135return vk_errorf(device, &device->vk.base,1136VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT,1137"VkImageDrmFormatModifierExplicitCreateInfoEXT::"1138"pPlaneLayouts[%u]::offset is %" PRIu64,1139i, ANV_OFFSET_IMPLICIT);1140}1141}11421143u_foreach_bit(b, image->aspects) {1144const VkImageAspectFlagBits aspect = 1 << b;1145const uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);1146const struct anv_format_plane format_plane =1147anv_get_format_plane(devinfo, image->vk_format, aspect, image->tiling);1148const VkSubresourceLayout *primary_layout = &drm_info->pPlaneLayouts[plane];11491150result = add_primary_surface(device, image, plane,1151format_plane,1152primary_layout->offset,1153primary_layout->rowPitch,1154isl_tiling_flags,1155isl_extra_usage_flags);1156if (result != VK_SUCCESS)1157return result;11581159if (!mod_has_aux) {1160/* Even though the modifier does not support aux, try to create1161* a driver-private aux to improve performance.1162*/1163result = add_aux_surface_if_supported(device, image, plane,1164format_plane,1165format_list_info,1166ANV_OFFSET_IMPLICIT, 0,1167isl_extra_usage_flags);1168if (result != VK_SUCCESS)1169return result;1170} else {1171const VkSubresourceLayout *aux_layout = &drm_info->pPlaneLayouts[1];1172result = add_aux_surface_if_supported(device, image, plane,1173format_plane,1174format_list_info,1175aux_layout->offset,1176aux_layout->rowPitch,1177isl_extra_usage_flags);1178if (result != VK_SUCCESS)1179return result;1180}1181}11821183return VK_SUCCESS;1184}11851186static const struct isl_drm_modifier_info *1187choose_drm_format_mod(const struct anv_physical_device *device,1188uint32_t modifier_count, const uint64_t *modifiers)1189{1190uint64_t best_mod = UINT64_MAX;1191uint32_t best_score = 0;11921193for (uint32_t i = 0; i < modifier_count; ++i) {1194uint32_t score = isl_drm_modifier_get_score(&device->info, modifiers[i]);1195if (score > best_score) {1196best_mod = modifiers[i];1197best_score = score;1198}1199}12001201if (best_score > 0)1202return isl_drm_modifier_get_info(best_mod);1203else1204return NULL;1205}12061207static VkImageUsageFlags1208anv_image_create_usage(const VkImageCreateInfo *pCreateInfo,1209VkImageUsageFlags usage)1210{1211/* Add TRANSFER_SRC usage for multisample attachment images. This is1212* because we might internally use the TRANSFER_SRC layout on them for1213* blorp operations associated with resolving those into other attachments1214* at the end of a subpass.1215*1216* Without this additional usage, we compute an incorrect AUX state in1217* anv_layout_to_aux_state().1218*/1219if (pCreateInfo->samples > VK_SAMPLE_COUNT_1_BIT &&1220(usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |1221VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)))1222usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;1223return usage;1224}12251226static VkResult MUST_CHECK1227alloc_private_binding(struct anv_device *device,1228struct anv_image *image,1229const VkImageCreateInfo *create_info)1230{1231struct anv_image_binding *binding =1232&image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE];12331234if (binding->memory_range.size == 0)1235return VK_SUCCESS;12361237const VkImageSwapchainCreateInfoKHR *swapchain_info =1238vk_find_struct_const(create_info->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);12391240if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) {1241/* The image will be bound to swapchain memory. */1242return VK_SUCCESS;1243}12441245return anv_device_alloc_bo(device, "image-binding-private",1246binding->memory_range.size, 0, 0,1247&binding->address.bo);1248}12491250VkResult1251anv_image_create(VkDevice _device,1252const struct anv_image_create_info *create_info,1253const VkAllocationCallbacks* alloc,1254VkImage *pImage)1255{1256ANV_FROM_HANDLE(anv_device, device, _device);1257const VkImageCreateInfo *pCreateInfo = create_info->vk_info;1258const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_explicit_info = NULL;1259const struct isl_drm_modifier_info *isl_mod_info = NULL;1260struct anv_image *image = NULL;1261VkResult r;12621263assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);12641265const struct wsi_image_create_info *wsi_info =1266vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);12671268if (pCreateInfo->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {1269mod_explicit_info =1270vk_find_struct_const(pCreateInfo->pNext,1271IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);1272if (mod_explicit_info) {1273isl_mod_info = isl_drm_modifier_get_info(mod_explicit_info->drmFormatModifier);1274} else {1275const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list_info =1276vk_find_struct_const(pCreateInfo->pNext,1277IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);1278isl_mod_info = choose_drm_format_mod(device->physical,1279mod_list_info->drmFormatModifierCount,1280mod_list_info->pDrmFormatModifiers);1281}12821283assert(isl_mod_info);1284}12851286anv_assert(pCreateInfo->mipLevels > 0);1287anv_assert(pCreateInfo->arrayLayers > 0);1288anv_assert(pCreateInfo->samples > 0);1289anv_assert(pCreateInfo->extent.width > 0);1290anv_assert(pCreateInfo->extent.height > 0);1291anv_assert(pCreateInfo->extent.depth > 0);12921293image = vk_object_zalloc(&device->vk, alloc, sizeof(*image),1294VK_OBJECT_TYPE_IMAGE);1295if (!image)1296return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);12971298image->type = pCreateInfo->imageType;1299image->extent = anv_sanitize_image_extent(pCreateInfo->imageType,1300pCreateInfo->extent);1301image->vk_format = pCreateInfo->format;1302image->format = anv_get_format(pCreateInfo->format);1303image->aspects = vk_format_aspects(image->vk_format);1304image->levels = pCreateInfo->mipLevels;1305image->array_size = pCreateInfo->arrayLayers;1306image->samples = pCreateInfo->samples;1307image->usage = anv_image_create_usage(pCreateInfo, pCreateInfo->usage);1308image->create_flags = pCreateInfo->flags;1309image->tiling = pCreateInfo->tiling;1310image->needs_set_tiling = wsi_info && wsi_info->scanout;1311image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :1312DRM_FORMAT_MOD_INVALID;13131314if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {1315image->stencil_usage = pCreateInfo->usage;1316const VkImageStencilUsageCreateInfoEXT *stencil_usage_info =1317vk_find_struct_const(pCreateInfo->pNext,1318IMAGE_STENCIL_USAGE_CREATE_INFO_EXT);1319if (stencil_usage_info) {1320image->stencil_usage =1321anv_image_create_usage(pCreateInfo,1322stencil_usage_info->stencilUsage);1323}1324}13251326for (int i = 0; i < ANV_IMAGE_MEMORY_BINDING_END; ++i) {1327image->bindings[i] = (struct anv_image_binding) {1328.memory_range = { .binding = i },1329};1330}13311332/* In case of external format, We don't know format yet,1333* so skip the rest for now.1334*/1335if (create_info->external_format) {1336image->external_format = true;1337*pImage = anv_image_to_handle(image);1338return VK_SUCCESS;1339}13401341image->n_planes = image->format->n_planes;13421343/* The Vulkan 1.2.165 glossary says:1344*1345* A disjoint image consists of multiple disjoint planes, and is created1346* with the VK_IMAGE_CREATE_DISJOINT_BIT bit set.1347*/1348image->disjoint = image->format->n_planes > 1 &&1349(pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT);13501351const isl_tiling_flags_t isl_tiling_flags =1352choose_isl_tiling_flags(&device->info, create_info, isl_mod_info,1353image->needs_set_tiling);13541355const VkImageFormatListCreateInfoKHR *fmt_list =1356vk_find_struct_const(pCreateInfo->pNext,1357IMAGE_FORMAT_LIST_CREATE_INFO_KHR);13581359if (mod_explicit_info) {1360r = add_all_surfaces_explicit_layout(device, image, fmt_list,1361mod_explicit_info, isl_tiling_flags,1362create_info->isl_extra_usage_flags);1363} else {1364r = add_all_surfaces_implicit_layout(device, image, fmt_list, 0,1365isl_tiling_flags,1366create_info->isl_extra_usage_flags);1367}13681369if (r != VK_SUCCESS)1370goto fail;13711372r = alloc_private_binding(device, image, pCreateInfo);1373if (r != VK_SUCCESS)1374goto fail;13751376check_memory_bindings(device, image);13771378r = check_drm_format_mod(device, image);1379if (r != VK_SUCCESS)1380goto fail;13811382*pImage = anv_image_to_handle(image);13831384return VK_SUCCESS;13851386fail:1387vk_object_free(&device->vk, alloc, image);1388return r;1389}13901391static struct anv_image *1392anv_swapchain_get_image(VkSwapchainKHR swapchain,1393uint32_t index)1394{1395uint32_t n_images = index + 1;1396VkImage *images = malloc(sizeof(*images) * n_images);1397VkResult result = wsi_common_get_images(swapchain, &n_images, images);13981399if (result != VK_SUCCESS && result != VK_INCOMPLETE) {1400free(images);1401return NULL;1402}14031404ANV_FROM_HANDLE(anv_image, image, images[index]);1405free(images);14061407return image;1408}14091410static VkResult1411anv_image_from_swapchain(VkDevice device,1412const VkImageCreateInfo *pCreateInfo,1413const VkImageSwapchainCreateInfoKHR *swapchain_info,1414const VkAllocationCallbacks *pAllocator,1415VkImage *pImage)1416{1417struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0);1418assert(swapchain_image);14191420VkImageCreateInfo local_create_info = *pCreateInfo;1421local_create_info.pNext = NULL;14221423/* Added by wsi code. */1424local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;14251426/* The spec requires TILING_OPTIMAL as input, but the swapchain image may1427* privately use a different tiling. See spec anchor1428* #swapchain-wsi-image-create-info .1429*/1430assert(local_create_info.tiling == VK_IMAGE_TILING_OPTIMAL);1431local_create_info.tiling = swapchain_image->tiling;14321433VkImageDrmFormatModifierListCreateInfoEXT local_modifier_info = {1434.sType = VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT,1435.drmFormatModifierCount = 1,1436.pDrmFormatModifiers = &swapchain_image->drm_format_mod,1437};14381439if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)1440__vk_append_struct(&local_create_info, &local_modifier_info);14411442assert(swapchain_image->type == local_create_info.imageType);1443assert(swapchain_image->vk_format == local_create_info.format);1444assert(swapchain_image->extent.width == local_create_info.extent.width);1445assert(swapchain_image->extent.height == local_create_info.extent.height);1446assert(swapchain_image->extent.depth == local_create_info.extent.depth);1447assert(swapchain_image->array_size == local_create_info.arrayLayers);1448assert(swapchain_image->samples == local_create_info.samples);1449assert(swapchain_image->tiling == local_create_info.tiling);1450assert(swapchain_image->usage == local_create_info.usage);14511452return anv_image_create(device,1453&(struct anv_image_create_info) {1454.vk_info = &local_create_info,1455.external_format = swapchain_image->external_format,1456},1457pAllocator,1458pImage);1459}14601461VkResult1462anv_CreateImage(VkDevice device,1463const VkImageCreateInfo *pCreateInfo,1464const VkAllocationCallbacks *pAllocator,1465VkImage *pImage)1466{1467const VkExternalMemoryImageCreateInfo *create_info =1468vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);14691470if (create_info && (create_info->handleTypes &1471VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))1472return anv_image_from_external(device, pCreateInfo, create_info,1473pAllocator, pImage);14741475bool use_external_format = false;1476const VkExternalFormatANDROID *ext_format =1477vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);14781479/* "If externalFormat is zero, the effect is as if the1480* VkExternalFormatANDROID structure was not present. Otherwise, the image1481* will have the specified external format."1482*/1483if (ext_format && ext_format->externalFormat != 0)1484use_external_format = true;14851486const VkNativeBufferANDROID *gralloc_info =1487vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);1488if (gralloc_info)1489return anv_image_from_gralloc(device, pCreateInfo, gralloc_info,1490pAllocator, pImage);14911492#ifndef VK_USE_PLATFORM_ANDROID_KHR1493/* Ignore swapchain creation info on Android. Since we don't have an1494* implementation in Mesa, we're guaranteed to access an Android object1495* incorrectly.1496*/1497const VkImageSwapchainCreateInfoKHR *swapchain_info =1498vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);1499if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)1500return anv_image_from_swapchain(device, pCreateInfo, swapchain_info,1501pAllocator, pImage);1502#endif15031504return anv_image_create(device,1505&(struct anv_image_create_info) {1506.vk_info = pCreateInfo,1507.external_format = use_external_format,1508},1509pAllocator,1510pImage);1511}15121513void1514anv_DestroyImage(VkDevice _device, VkImage _image,1515const VkAllocationCallbacks *pAllocator)1516{1517ANV_FROM_HANDLE(anv_device, device, _device);1518ANV_FROM_HANDLE(anv_image, image, _image);15191520if (!image)1521return;15221523if (image->from_gralloc) {1524assert(!image->disjoint);1525assert(image->n_planes == 1);1526assert(image->planes[0].primary_surface.memory_range.binding ==1527ANV_IMAGE_MEMORY_BINDING_MAIN);1528assert(image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo != NULL);1529anv_device_release_bo(device, image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address.bo);1530}15311532struct anv_bo *private_bo = image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address.bo;1533if (private_bo)1534anv_device_release_bo(device, private_bo);15351536vk_object_free(&device->vk, pAllocator, image);1537}15381539/* We are binding AHardwareBuffer. Get a description, resolve the1540* format and prepare anv_image properly.1541*/1542static void1543resolve_ahw_image(struct anv_device *device,1544struct anv_image *image,1545struct anv_device_memory *mem)1546{1547#if defined(ANDROID) && ANDROID_API_LEVEL >= 261548assert(mem->ahw);1549AHardwareBuffer_Desc desc;1550AHardwareBuffer_describe(mem->ahw, &desc);1551VkResult result;15521553/* Check tiling. */1554int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);1555VkImageTiling vk_tiling;1556isl_tiling_flags_t isl_tiling_flags = 0;15571558switch (i915_tiling) {1559case I915_TILING_NONE:1560vk_tiling = VK_IMAGE_TILING_LINEAR;1561isl_tiling_flags = ISL_TILING_LINEAR_BIT;1562break;1563case I915_TILING_X:1564vk_tiling = VK_IMAGE_TILING_OPTIMAL;1565isl_tiling_flags = ISL_TILING_X_BIT;1566break;1567case I915_TILING_Y:1568vk_tiling = VK_IMAGE_TILING_OPTIMAL;1569isl_tiling_flags = ISL_TILING_Y0_BIT;1570break;1571case -1:1572default:1573unreachable("Invalid tiling flags.");1574}15751576assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||1577vk_tiling == VK_IMAGE_TILING_OPTIMAL);15781579/* Check format. */1580VkFormat vk_format = vk_format_from_android(desc.format, desc.usage);1581enum isl_format isl_fmt = anv_get_isl_format(&device->info,1582vk_format,1583VK_IMAGE_ASPECT_COLOR_BIT,1584vk_tiling);1585assert(isl_fmt != ISL_FORMAT_UNSUPPORTED);15861587/* Handle RGB(X)->RGBA fallback. */1588switch (desc.format) {1589case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:1590case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:1591if (isl_format_is_rgb(isl_fmt))1592isl_fmt = isl_format_rgb_to_rgba(isl_fmt);1593break;1594}15951596/* Now we are able to fill anv_image fields properly and create1597* isl_surface for it.1598*/1599image->vk_format = vk_format;1600image->format = anv_get_format(vk_format);1601image->aspects = vk_format_aspects(image->vk_format);1602image->n_planes = image->format->n_planes;16031604uint32_t stride = desc.stride *1605(isl_format_get_layout(isl_fmt)->bpb / 8);16061607result = add_all_surfaces_implicit_layout(device, image, NULL, stride,1608isl_tiling_flags,1609ISL_SURF_USAGE_DISABLE_AUX_BIT);1610assert(result == VK_SUCCESS);1611#endif1612}16131614void anv_GetImageMemoryRequirements2(1615VkDevice _device,1616const VkImageMemoryRequirementsInfo2* pInfo,1617VkMemoryRequirements2* pMemoryRequirements)1618{1619ANV_FROM_HANDLE(anv_device, device, _device);1620ANV_FROM_HANDLE(anv_image, image, pInfo->image);16211622const VkImagePlaneMemoryRequirementsInfo *plane_reqs = NULL;16231624/* The Vulkan spec (git aaed022) says:1625*1626* memoryTypeBits is a bitfield and contains one bit set for every1627* supported memory type for the resource. The bit `1<<i` is set if and1628* only if the memory type `i` in the VkPhysicalDeviceMemoryProperties1629* structure for the physical device is supported.1630*1631* All types are currently supported for images.1632*/1633uint32_t memory_types = (1ull << device->physical->memory.type_count) - 1;16341635vk_foreach_struct_const(ext, pInfo->pNext) {1636switch (ext->sType) {1637case VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO: {1638assert(image->disjoint);1639plane_reqs = (const VkImagePlaneMemoryRequirementsInfo *) ext;1640const struct anv_image_binding *binding =1641image_aspect_to_binding(image, plane_reqs->planeAspect);16421643pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {1644.size = binding->memory_range.size,1645.alignment = binding->memory_range.alignment,1646.memoryTypeBits = memory_types,1647};1648break;1649}16501651default:1652anv_debug_ignored_stype(ext->sType);1653break;1654}1655}16561657vk_foreach_struct(ext, pMemoryRequirements->pNext) {1658switch (ext->sType) {1659case VK_STRUCTURE_TYPE_MEMORY_DEDICATED_REQUIREMENTS: {1660VkMemoryDedicatedRequirements *requirements = (void *)ext;1661if (image->needs_set_tiling || image->external_format) {1662/* If we need to set the tiling for external consumers, we need a1663* dedicated allocation.1664*1665* See also anv_AllocateMemory.1666*/1667requirements->prefersDedicatedAllocation = true;1668requirements->requiresDedicatedAllocation = true;1669} else {1670requirements->prefersDedicatedAllocation = false;1671requirements->requiresDedicatedAllocation = false;1672}1673break;1674}16751676default:1677anv_debug_ignored_stype(ext->sType);1678break;1679}1680}16811682/* If the image is disjoint, then we must return the memory requirements for1683* the single plane specified in VkImagePlaneMemoryRequirementsInfo. If1684* non-disjoint, then exactly one set of memory requirements exists for the1685* whole image.1686*1687* This is enforced by the Valid Usage for VkImageMemoryRequirementsInfo2,1688* which requires that the app provide VkImagePlaneMemoryRequirementsInfo if1689* and only if the image is disjoint (that is, multi-planar format and1690* VK_IMAGE_CREATE_DISJOINT_BIT).1691*/1692assert(image->disjoint == (plane_reqs != NULL));16931694if (!image->disjoint) {1695const struct anv_image_binding *binding =1696&image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN];16971698pMemoryRequirements->memoryRequirements = (VkMemoryRequirements) {1699.size = binding->memory_range.size,1700.alignment = binding->memory_range.alignment,1701.memoryTypeBits = memory_types,1702};1703}1704}17051706void anv_GetImageSparseMemoryRequirements(1707VkDevice device,1708VkImage image,1709uint32_t* pSparseMemoryRequirementCount,1710VkSparseImageMemoryRequirements* pSparseMemoryRequirements)1711{1712*pSparseMemoryRequirementCount = 0;1713}17141715void anv_GetImageSparseMemoryRequirements2(1716VkDevice device,1717const VkImageSparseMemoryRequirementsInfo2* pInfo,1718uint32_t* pSparseMemoryRequirementCount,1719VkSparseImageMemoryRequirements2* pSparseMemoryRequirements)1720{1721*pSparseMemoryRequirementCount = 0;1722}17231724VkResult anv_BindImageMemory2(1725VkDevice _device,1726uint32_t bindInfoCount,1727const VkBindImageMemoryInfo* pBindInfos)1728{1729ANV_FROM_HANDLE(anv_device, device, _device);17301731for (uint32_t i = 0; i < bindInfoCount; i++) {1732const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];1733ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory);1734ANV_FROM_HANDLE(anv_image, image, bind_info->image);1735bool did_bind = false;17361737/* Resolve will alter the image's aspects, do this first. */1738if (mem && mem->ahw)1739resolve_ahw_image(device, image, mem);17401741vk_foreach_struct_const(s, bind_info->pNext) {1742switch (s->sType) {1743case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: {1744const VkBindImagePlaneMemoryInfo *plane_info =1745(const VkBindImagePlaneMemoryInfo *) s;17461747/* Workaround for possible spec bug.1748*1749* Unlike VkImagePlaneMemoryRequirementsInfo, which requires that1750* the image be disjoint (that is, multi-planar format and1751* VK_IMAGE_CREATE_DISJOINT_BIT), VkBindImagePlaneMemoryInfo allows1752* the image to be non-disjoint and requires only that the image1753* have the DISJOINT flag. In this case, regardless of the value of1754* VkImagePlaneMemoryRequirementsInfo::planeAspect, the behavior is1755* the same as if VkImagePlaneMemoryRequirementsInfo were omitted.1756*/1757if (!image->disjoint)1758break;17591760struct anv_image_binding *binding =1761image_aspect_to_binding(image, plane_info->planeAspect);17621763binding->address = (struct anv_address) {1764.bo = mem->bo,1765.offset = bind_info->memoryOffset,1766};17671768did_bind = true;1769break;1770}1771case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {1772/* Ignore this struct on Android, we cannot access swapchain1773* structures threre.1774*/1775#ifndef VK_USE_PLATFORM_ANDROID_KHR1776const VkBindImageMemorySwapchainInfoKHR *swapchain_info =1777(const VkBindImageMemorySwapchainInfoKHR *) s;1778struct anv_image *swapchain_image =1779anv_swapchain_get_image(swapchain_info->swapchain,1780swapchain_info->imageIndex);1781assert(swapchain_image);1782assert(image->aspects == swapchain_image->aspects);1783assert(mem == NULL);17841785for (int j = 0; j < ARRAY_SIZE(image->bindings); ++j)1786image->bindings[j].address = swapchain_image->bindings[j].address;17871788/* We must bump the private binding's bo's refcount because, unlike the other1789* bindings, its lifetime is not application-managed.1790*/1791struct anv_bo *private_bo =1792image->bindings[ANV_IMAGE_MEMORY_BINDING_PRIVATE].address.bo;1793if (private_bo)1794anv_bo_ref(private_bo);17951796did_bind = true;1797#endif1798break;1799}1800#pragma GCC diagnostic push1801#pragma GCC diagnostic ignored "-Wswitch"1802case VK_STRUCTURE_TYPE_NATIVE_BUFFER_ANDROID: {1803const VkNativeBufferANDROID *gralloc_info =1804(const VkNativeBufferANDROID *)s;1805VkResult result = anv_image_bind_from_gralloc(device, image,1806gralloc_info);1807if (result != VK_SUCCESS)1808return result;1809did_bind = true;1810break;1811}1812#pragma GCC diagnostic pop1813default:1814anv_debug_ignored_stype(s->sType);1815break;1816}1817}18181819if (!did_bind) {1820assert(!image->disjoint);18211822image->bindings[ANV_IMAGE_MEMORY_BINDING_MAIN].address =1823(struct anv_address) {1824.bo = mem->bo,1825.offset = bind_info->memoryOffset,1826};18271828did_bind = true;1829}18301831/* On platforms that use implicit CCS, if the plane's bo lacks implicit1832* CCS then disable compression on the plane.1833*/1834for (int p = 0; p < image->n_planes; ++p) {1835enum anv_image_memory_binding binding =1836image->planes[p].primary_surface.memory_range.binding;1837const struct anv_bo *bo =1838image->bindings[binding].address.bo;18391840if (bo && !bo->has_implicit_ccs &&1841device->physical->has_implicit_ccs)1842image->planes[p].aux_usage = ISL_AUX_USAGE_NONE;1843}1844}18451846return VK_SUCCESS;1847}18481849void anv_GetImageSubresourceLayout(1850VkDevice device,1851VkImage _image,1852const VkImageSubresource* subresource,1853VkSubresourceLayout* layout)1854{1855ANV_FROM_HANDLE(anv_image, image, _image);1856const struct anv_surface *surface;18571858assert(__builtin_popcount(subresource->aspectMask) == 1);18591860/* The Vulkan spec requires that aspectMask be1861* VK_IMAGE_ASPECT_MEMORY_PLANE_i_BIT_EXT if tiling is1862* VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT.1863*1864* For swapchain images, the Vulkan spec says that every swapchain image has1865* tiling VK_IMAGE_TILING_OPTIMAL, but we may choose1866* VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT internally. Vulkan doesn't allow1867* vkGetImageSubresourceLayout for images with VK_IMAGE_TILING_OPTIMAL,1868* therefore it's invalid for the application to call this on a swapchain1869* image. The WSI code, however, knows when it has internally created1870* a swapchain image with VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT,1871* so it _should_ correctly use VK_IMAGE_ASPECT_MEMORY_PLANE_* in that case.1872* But it incorrectly uses VK_IMAGE_ASPECT_PLANE_*, so we have a temporary1873* workaround.1874*/1875if (image->tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {1876/* TODO(chadv): Drop this workaround when WSI gets fixed. */1877uint32_t mem_plane;1878switch (subresource->aspectMask) {1879case VK_IMAGE_ASPECT_MEMORY_PLANE_0_BIT_EXT:1880case VK_IMAGE_ASPECT_PLANE_0_BIT:1881mem_plane = 0;1882break;1883case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:1884case VK_IMAGE_ASPECT_PLANE_1_BIT:1885mem_plane = 1;1886break;1887case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:1888case VK_IMAGE_ASPECT_PLANE_2_BIT:1889mem_plane = 2;1890break;1891default:1892unreachable("bad VkImageAspectFlags");1893}18941895if (mem_plane == 1 && isl_drm_modifier_has_aux(image->drm_format_mod)) {1896assert(image->n_planes == 1);1897/* If the memory binding differs between primary and aux, then the1898* returned offset will be incorrect.1899*/1900assert(image->planes[0].aux_surface.memory_range.binding ==1901image->planes[0].primary_surface.memory_range.binding);1902surface = &image->planes[0].aux_surface;1903} else {1904assert(mem_plane < image->n_planes);1905surface = &image->planes[mem_plane].primary_surface;1906}1907} else {1908uint32_t plane = anv_image_aspect_to_plane(image->aspects,1909subresource->aspectMask);1910surface = &image->planes[plane].primary_surface;1911}19121913layout->offset = surface->memory_range.offset;1914layout->rowPitch = surface->isl.row_pitch_B;1915layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);1916layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);19171918if (subresource->mipLevel > 0 || subresource->arrayLayer > 0) {1919assert(surface->isl.tiling == ISL_TILING_LINEAR);19201921uint32_t offset_B;1922isl_surf_get_image_offset_B_tile_sa(&surface->isl,1923subresource->mipLevel,1924subresource->arrayLayer,19250 /* logical_z_offset_px */,1926&offset_B, NULL, NULL);1927layout->offset += offset_B;1928layout->size = layout->rowPitch * anv_minify(image->extent.height,1929subresource->mipLevel) *1930image->extent.depth;1931} else {1932layout->size = surface->memory_range.size;1933}1934}19351936VkResult anv_GetImageDrmFormatModifierPropertiesEXT(1937VkDevice device,1938VkImage _image,1939VkImageDrmFormatModifierPropertiesEXT* pProperties)1940{1941ANV_FROM_HANDLE(anv_image, image, _image);19421943assert(pProperties->sType ==1944VK_STRUCTURE_TYPE_IMAGE_DRM_FORMAT_MODIFIER_PROPERTIES_EXT);19451946pProperties->drmFormatModifier = image->drm_format_mod;19471948return VK_SUCCESS;1949}19501951static VkImageUsageFlags1952vk_image_layout_to_usage_flags(VkImageLayout layout,1953VkImageAspectFlagBits aspect)1954{1955assert(util_bitcount(aspect) == 1);19561957switch (layout) {1958case VK_IMAGE_LAYOUT_UNDEFINED:1959case VK_IMAGE_LAYOUT_PREINITIALIZED:1960return 0u;19611962case VK_IMAGE_LAYOUT_GENERAL:1963return ~0u;19641965case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:1966assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);1967return VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;19681969case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:1970assert(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT |1971VK_IMAGE_ASPECT_STENCIL_BIT));1972return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;19731974case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:1975assert(aspect & VK_IMAGE_ASPECT_DEPTH_BIT);1976return vk_image_layout_to_usage_flags(1977VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);19781979case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:1980assert(aspect & VK_IMAGE_ASPECT_STENCIL_BIT);1981return vk_image_layout_to_usage_flags(1982VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);19831984case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:1985assert(aspect & (VK_IMAGE_ASPECT_DEPTH_BIT |1986VK_IMAGE_ASPECT_STENCIL_BIT));1987return VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |1988VK_IMAGE_USAGE_SAMPLED_BIT |1989VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;19901991case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:1992assert(aspect & VK_IMAGE_ASPECT_DEPTH_BIT);1993return vk_image_layout_to_usage_flags(1994VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);19951996case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:1997assert(aspect & VK_IMAGE_ASPECT_STENCIL_BIT);1998return vk_image_layout_to_usage_flags(1999VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);20002001case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:2002return VK_IMAGE_USAGE_SAMPLED_BIT |2003VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;20042005case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:2006return VK_IMAGE_USAGE_TRANSFER_SRC_BIT;20072008case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:2009return VK_IMAGE_USAGE_TRANSFER_DST_BIT;20102011case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:2012if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {2013return vk_image_layout_to_usage_flags(2014VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);2015} else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {2016return vk_image_layout_to_usage_flags(2017VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);2018} else {2019assert(!"Must be a depth/stencil aspect");2020return 0;2021}20222023case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:2024if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {2025return vk_image_layout_to_usage_flags(2026VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, aspect);2027} else if (aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {2028return vk_image_layout_to_usage_flags(2029VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, aspect);2030} else {2031assert(!"Must be a depth/stencil aspect");2032return 0;2033}20342035case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:2036assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);2037/* This needs to be handled specially by the caller */2038return 0;20392040case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:2041assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);2042return vk_image_layout_to_usage_flags(VK_IMAGE_LAYOUT_GENERAL, aspect);20432044case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:2045assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);2046return VK_IMAGE_USAGE_SHADING_RATE_IMAGE_BIT_NV;20472048case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:2049assert(aspect == VK_IMAGE_ASPECT_COLOR_BIT);2050return VK_IMAGE_USAGE_FRAGMENT_DENSITY_MAP_BIT_EXT;20512052case VK_IMAGE_LAYOUT_MAX_ENUM:2053case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR:2054case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR:2055unreachable("Invalid image layout.");2056}20572058unreachable("Invalid image layout.");2059}20602061static bool2062vk_image_layout_is_read_only(VkImageLayout layout,2063VkImageAspectFlagBits aspect)2064{2065assert(util_bitcount(aspect) == 1);20662067switch (layout) {2068case VK_IMAGE_LAYOUT_UNDEFINED:2069case VK_IMAGE_LAYOUT_PREINITIALIZED:2070return true; /* These are only used for layout transitions */20712072case VK_IMAGE_LAYOUT_GENERAL:2073case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:2074case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:2075case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:2076case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:2077case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:2078case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:2079return false;20802081case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:2082case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:2083case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:2084case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:2085case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:2086case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:2087case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:2088case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL:2089return true;20902091case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:2092return aspect == VK_IMAGE_ASPECT_DEPTH_BIT;20932094case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:2095return aspect == VK_IMAGE_ASPECT_STENCIL_BIT;20962097case VK_IMAGE_LAYOUT_MAX_ENUM:2098case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL_KHR:2099case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL_KHR:2100unreachable("Invalid image layout.");2101}21022103unreachable("Invalid image layout.");2104}21052106/**2107* This function returns the assumed isl_aux_state for a given VkImageLayout.2108* Because Vulkan image layouts don't map directly to isl_aux_state enums, the2109* returned enum is the assumed worst case.2110*2111* @param devinfo The device information of the Intel GPU.2112* @param image The image that may contain a collection of buffers.2113* @param aspect The aspect of the image to be accessed.2114* @param layout The current layout of the image aspect(s).2115*2116* @return The primary buffer that should be used for the given layout.2117*/2118enum isl_aux_state ATTRIBUTE_PURE2119anv_layout_to_aux_state(const struct intel_device_info * const devinfo,2120const struct anv_image * const image,2121const VkImageAspectFlagBits aspect,2122const VkImageLayout layout)2123{2124/* Validate the inputs. */21252126/* The devinfo is needed as the optimal buffer varies across generations. */2127assert(devinfo != NULL);21282129/* The layout of a NULL image is not properly defined. */2130assert(image != NULL);21312132/* The aspect must be exactly one of the image aspects. */2133assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));21342135/* Determine the optimal buffer. */21362137uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);21382139/* If we don't have an aux buffer then aux state makes no sense */2140const enum isl_aux_usage aux_usage = image->planes[plane].aux_usage;2141assert(aux_usage != ISL_AUX_USAGE_NONE);21422143/* All images that use an auxiliary surface are required to be tiled. */2144assert(image->planes[plane].primary_surface.isl.tiling != ISL_TILING_LINEAR);21452146/* Handle a few special cases */2147switch (layout) {2148/* Invalid layouts */2149case VK_IMAGE_LAYOUT_MAX_ENUM:2150unreachable("Invalid image layout.");21512152/* Undefined layouts2153*2154* The pre-initialized layout is equivalent to the undefined layout for2155* optimally-tiled images. We can only do color compression (CCS or HiZ)2156* on tiled images.2157*/2158case VK_IMAGE_LAYOUT_UNDEFINED:2159case VK_IMAGE_LAYOUT_PREINITIALIZED:2160return ISL_AUX_STATE_AUX_INVALID;21612162case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {2163assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);21642165enum isl_aux_state aux_state =2166isl_drm_modifier_get_default_aux_state(image->drm_format_mod);21672168switch (aux_state) {2169default:2170assert(!"unexpected isl_aux_state");2171case ISL_AUX_STATE_AUX_INVALID:2172/* The modifier does not support compression. But, if we arrived2173* here, then we have enabled compression on it anyway, in which case2174* we must resolve the aux surface before we release ownership to the2175* presentation engine (because, having no modifier, the presentation2176* engine will not be aware of the aux surface). The presentation2177* engine will not access the aux surface (because it is unware of2178* it), and so the aux surface will still be resolved when we2179* re-acquire ownership.2180*2181* Therefore, at ownership transfers in either direction, there does2182* exist an aux surface despite the lack of modifier and its state is2183* pass-through.2184*/2185return ISL_AUX_STATE_PASS_THROUGH;2186case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:2187return ISL_AUX_STATE_COMPRESSED_NO_CLEAR;2188}2189}21902191default:2192break;2193}21942195const bool read_only = vk_image_layout_is_read_only(layout, aspect);21962197const VkImageUsageFlags image_aspect_usage =2198aspect == VK_IMAGE_ASPECT_STENCIL_BIT ? image->stencil_usage :2199image->usage;2200const VkImageUsageFlags usage =2201vk_image_layout_to_usage_flags(layout, aspect) & image_aspect_usage;22022203bool aux_supported = true;2204bool clear_supported = isl_aux_usage_has_fast_clears(aux_usage);22052206if ((usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) && !read_only) {2207/* This image could be used as both an input attachment and a render2208* target (depth, stencil, or color) at the same time and this can cause2209* corruption.2210*2211* We currently only disable aux in this way for depth even though we2212* disable it for color in GL.2213*2214* TODO: Should we be disabling this in more cases?2215*/2216if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {2217aux_supported = false;2218clear_supported = false;2219}2220}22212222if (usage & VK_IMAGE_USAGE_STORAGE_BIT) {2223aux_supported = false;2224clear_supported = false;2225}22262227if (usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |2228VK_IMAGE_USAGE_SAMPLED_BIT |2229VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)) {2230switch (aux_usage) {2231case ISL_AUX_USAGE_HIZ:2232if (!anv_can_sample_with_hiz(devinfo, image)) {2233aux_supported = false;2234clear_supported = false;2235}2236break;22372238case ISL_AUX_USAGE_HIZ_CCS:2239aux_supported = false;2240clear_supported = false;2241break;22422243case ISL_AUX_USAGE_HIZ_CCS_WT:2244break;22452246case ISL_AUX_USAGE_CCS_D:2247aux_supported = false;2248clear_supported = false;2249break;22502251case ISL_AUX_USAGE_MCS:2252if (!anv_can_sample_mcs_with_clear(devinfo, image))2253clear_supported = false;2254break;22552256case ISL_AUX_USAGE_CCS_E:2257case ISL_AUX_USAGE_STC_CCS:2258break;22592260default:2261unreachable("Unsupported aux usage");2262}2263}22642265switch (aux_usage) {2266case ISL_AUX_USAGE_HIZ:2267case ISL_AUX_USAGE_HIZ_CCS:2268case ISL_AUX_USAGE_HIZ_CCS_WT:2269if (aux_supported) {2270assert(clear_supported);2271return ISL_AUX_STATE_COMPRESSED_CLEAR;2272} else if (read_only) {2273return ISL_AUX_STATE_RESOLVED;2274} else {2275return ISL_AUX_STATE_AUX_INVALID;2276}22772278case ISL_AUX_USAGE_CCS_D:2279/* We only support clear in exactly one state */2280if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {2281assert(aux_supported);2282assert(clear_supported);2283return ISL_AUX_STATE_PARTIAL_CLEAR;2284} else {2285return ISL_AUX_STATE_PASS_THROUGH;2286}22872288case ISL_AUX_USAGE_CCS_E:2289if (aux_supported) {2290assert(clear_supported);2291return ISL_AUX_STATE_COMPRESSED_CLEAR;2292} else {2293return ISL_AUX_STATE_PASS_THROUGH;2294}22952296case ISL_AUX_USAGE_MCS:2297assert(aux_supported);2298if (clear_supported) {2299return ISL_AUX_STATE_COMPRESSED_CLEAR;2300} else {2301return ISL_AUX_STATE_COMPRESSED_NO_CLEAR;2302}23032304case ISL_AUX_USAGE_STC_CCS:2305assert(aux_supported);2306assert(!clear_supported);2307return ISL_AUX_STATE_COMPRESSED_NO_CLEAR;23082309default:2310unreachable("Unsupported aux usage");2311}2312}23132314/**2315* This function determines the optimal buffer to use for a given2316* VkImageLayout and other pieces of information needed to make that2317* determination. This does not determine the optimal buffer to use2318* during a resolve operation.2319*2320* @param devinfo The device information of the Intel GPU.2321* @param image The image that may contain a collection of buffers.2322* @param aspect The aspect of the image to be accessed.2323* @param usage The usage which describes how the image will be accessed.2324* @param layout The current layout of the image aspect(s).2325*2326* @return The primary buffer that should be used for the given layout.2327*/2328enum isl_aux_usage ATTRIBUTE_PURE2329anv_layout_to_aux_usage(const struct intel_device_info * const devinfo,2330const struct anv_image * const image,2331const VkImageAspectFlagBits aspect,2332const VkImageUsageFlagBits usage,2333const VkImageLayout layout)2334{2335uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);23362337/* If there is no auxiliary surface allocated, we must use the one and only2338* main buffer.2339*/2340if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE)2341return ISL_AUX_USAGE_NONE;23422343enum isl_aux_state aux_state =2344anv_layout_to_aux_state(devinfo, image, aspect, layout);23452346switch (aux_state) {2347case ISL_AUX_STATE_CLEAR:2348unreachable("We never use this state");23492350case ISL_AUX_STATE_PARTIAL_CLEAR:2351assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);2352assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_D);2353assert(image->samples == 1);2354return ISL_AUX_USAGE_CCS_D;23552356case ISL_AUX_STATE_COMPRESSED_CLEAR:2357case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:2358return image->planes[plane].aux_usage;23592360case ISL_AUX_STATE_RESOLVED:2361/* We can only use RESOLVED in read-only layouts because any write will2362* either land us in AUX_INVALID or COMPRESSED_NO_CLEAR. We can do2363* writes in PASS_THROUGH without destroying it so that is allowed.2364*/2365assert(vk_image_layout_is_read_only(layout, aspect));2366assert(util_is_power_of_two_or_zero(usage));2367if (usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {2368/* If we have valid HiZ data and are using the image as a read-only2369* depth/stencil attachment, we should enable HiZ so that we can get2370* faster depth testing.2371*/2372return image->planes[plane].aux_usage;2373} else {2374return ISL_AUX_USAGE_NONE;2375}23762377case ISL_AUX_STATE_PASS_THROUGH:2378case ISL_AUX_STATE_AUX_INVALID:2379return ISL_AUX_USAGE_NONE;2380}23812382unreachable("Invalid isl_aux_state");2383}23842385/**2386* This function returns the level of unresolved fast-clear support of the2387* given image in the given VkImageLayout.2388*2389* @param devinfo The device information of the Intel GPU.2390* @param image The image that may contain a collection of buffers.2391* @param aspect The aspect of the image to be accessed.2392* @param usage The usage which describes how the image will be accessed.2393* @param layout The current layout of the image aspect(s).2394*/2395enum anv_fast_clear_type ATTRIBUTE_PURE2396anv_layout_to_fast_clear_type(const struct intel_device_info * const devinfo,2397const struct anv_image * const image,2398const VkImageAspectFlagBits aspect,2399const VkImageLayout layout)2400{2401if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)2402return ANV_FAST_CLEAR_NONE;24032404uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);24052406/* If there is no auxiliary surface allocated, there are no fast-clears */2407if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE)2408return ANV_FAST_CLEAR_NONE;24092410/* We don't support MSAA fast-clears on Ivybridge or Bay Trail because they2411* lack the MI ALU which we need to determine the predicates.2412*/2413if (devinfo->verx10 == 70 && image->samples > 1)2414return ANV_FAST_CLEAR_NONE;24152416enum isl_aux_state aux_state =2417anv_layout_to_aux_state(devinfo, image, aspect, layout);24182419switch (aux_state) {2420case ISL_AUX_STATE_CLEAR:2421unreachable("We never use this state");24222423case ISL_AUX_STATE_PARTIAL_CLEAR:2424case ISL_AUX_STATE_COMPRESSED_CLEAR:2425if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {2426return ANV_FAST_CLEAR_DEFAULT_VALUE;2427} else if (layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL) {2428/* When we're in a render pass we have the clear color data from the2429* VkRenderPassBeginInfo and we can use arbitrary clear colors. They2430* must get partially resolved before we leave the render pass.2431*/2432return ANV_FAST_CLEAR_ANY;2433} else if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS ||2434image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) {2435if (devinfo->ver >= 11) {2436/* On ICL and later, the sampler hardware uses a copy of the clear2437* value that is encoded as a pixel value. Therefore, we can use2438* any clear color we like for sampling.2439*/2440return ANV_FAST_CLEAR_ANY;2441} else {2442/* If the image has MCS or CCS_E enabled all the time then we can2443* use fast-clear as long as the clear color is the default value2444* of zero since this is the default value we program into every2445* surface state used for texturing.2446*/2447return ANV_FAST_CLEAR_DEFAULT_VALUE;2448}2449} else {2450return ANV_FAST_CLEAR_NONE;2451}24522453case ISL_AUX_STATE_COMPRESSED_NO_CLEAR:2454case ISL_AUX_STATE_RESOLVED:2455case ISL_AUX_STATE_PASS_THROUGH:2456case ISL_AUX_STATE_AUX_INVALID:2457return ANV_FAST_CLEAR_NONE;2458}24592460unreachable("Invalid isl_aux_state");2461}246224632464static struct anv_state2465alloc_surface_state(struct anv_device *device)2466{2467return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);2468}24692470static enum isl_channel_select2471remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,2472struct isl_swizzle format_swizzle)2473{2474if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)2475swizzle = component;24762477switch (swizzle) {2478case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO;2479case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE;2480case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r;2481case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g;2482case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b;2483case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a;2484default:2485unreachable("Invalid swizzle");2486}2487}24882489void2490anv_image_fill_surface_state(struct anv_device *device,2491const struct anv_image *image,2492VkImageAspectFlagBits aspect,2493const struct isl_view *view_in,2494isl_surf_usage_flags_t view_usage,2495enum isl_aux_usage aux_usage,2496const union isl_color_value *clear_color,2497enum anv_image_view_state_flags flags,2498struct anv_surface_state *state_inout,2499struct brw_image_param *image_param_out)2500{2501uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);25022503const struct anv_surface *surface = &image->planes[plane].primary_surface,2504*aux_surface = &image->planes[plane].aux_surface;25052506struct isl_view view = *view_in;2507view.usage |= view_usage;25082509/* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a2510* compressed surface with a shadow surface, we use the shadow instead of2511* the primary surface. The shadow surface will be tiled, unlike the main2512* surface, so it should get significantly better performance.2513*/2514if (anv_surface_is_valid(&image->planes[plane].shadow_surface) &&2515isl_format_is_compressed(view.format) &&2516(flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) {2517assert(isl_format_is_compressed(surface->isl.format));2518assert(surface->isl.tiling == ISL_TILING_LINEAR);2519assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR);2520surface = &image->planes[plane].shadow_surface;2521}25222523/* For texturing from stencil on gfx7, we have to sample from a shadow2524* surface because we don't support W-tiling in the sampler.2525*/2526if (anv_surface_is_valid(&image->planes[plane].shadow_surface) &&2527aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {2528assert(device->info.ver == 7);2529assert(view_usage & ISL_SURF_USAGE_TEXTURE_BIT);2530surface = &image->planes[plane].shadow_surface;2531}25322533if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)2534view.swizzle = anv_swizzle_for_render(view.swizzle);25352536/* On Ivy Bridge and Bay Trail we do the swizzle in the shader */2537if (device->info.verx10 == 70)2538view.swizzle = ISL_SWIZZLE_IDENTITY;25392540/* If this is a HiZ buffer we can sample from with a programmable clear2541* value (SKL+), define the clear value to the optimal constant.2542*/2543union isl_color_value default_clear_color = { .u32 = { 0, } };2544if (device->info.ver >= 9 && aspect == VK_IMAGE_ASPECT_DEPTH_BIT)2545default_clear_color.f32[0] = ANV_HZ_FC_VAL;2546if (!clear_color)2547clear_color = &default_clear_color;25482549const struct anv_address address =2550anv_image_address(image, &surface->memory_range);25512552if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&2553!(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) &&2554!isl_has_matching_typed_storage_image_format(&device->info,2555view.format)) {2556/* In this case, we are a writeable storage buffer which needs to be2557* lowered to linear. All tiling and offset calculations will be done in2558* the shader.2559*/2560assert(aux_usage == ISL_AUX_USAGE_NONE);2561isl_buffer_fill_state(&device->isl_dev, state_inout->state.map,2562.address = anv_address_physical(address),2563.size_B = surface->isl.size_B,2564.format = ISL_FORMAT_RAW,2565.swizzle = ISL_SWIZZLE_IDENTITY,2566.stride_B = 1,2567.mocs = anv_mocs(device, address.bo, view_usage));2568state_inout->address = address,2569state_inout->aux_address = ANV_NULL_ADDRESS;2570state_inout->clear_address = ANV_NULL_ADDRESS;2571} else {2572if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&2573!(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) {2574/* Typed surface reads support a very limited subset of the shader2575* image formats. Translate it into the closest format the hardware2576* supports.2577*/2578assert(aux_usage == ISL_AUX_USAGE_NONE);2579view.format = isl_lower_storage_image_format(&device->info,2580view.format);2581}25822583const struct isl_surf *isl_surf = &surface->isl;25842585struct isl_surf tmp_surf;2586uint32_t offset_B = 0, tile_x_sa = 0, tile_y_sa = 0;2587if (isl_format_is_compressed(surface->isl.format) &&2588!isl_format_is_compressed(view.format)) {2589/* We're creating an uncompressed view of a compressed surface. This2590* is allowed but only for a single level/layer.2591*/2592assert(surface->isl.samples == 1);2593assert(view.levels == 1);2594assert(view.array_len == 1);25952596ASSERTED bool ok =2597isl_surf_get_uncompressed_surf(&device->isl_dev, isl_surf, &view,2598&tmp_surf, &view,2599&offset_B, &tile_x_sa, &tile_y_sa);2600assert(ok);2601isl_surf = &tmp_surf;26022603if (device->info.ver <= 8) {2604assert(surface->isl.tiling == ISL_TILING_LINEAR);2605assert(tile_x_sa == 0);2606assert(tile_y_sa == 0);2607}2608}26092610state_inout->address = anv_address_add(address, offset_B);26112612struct anv_address aux_address = ANV_NULL_ADDRESS;2613if (aux_usage != ISL_AUX_USAGE_NONE)2614aux_address = anv_image_address(image, &aux_surface->memory_range);2615state_inout->aux_address = aux_address;26162617struct anv_address clear_address = ANV_NULL_ADDRESS;2618if (device->info.ver >= 10 && isl_aux_usage_has_fast_clears(aux_usage)) {2619clear_address = anv_image_get_clear_color_addr(device, image, aspect);2620}2621state_inout->clear_address = clear_address;26222623isl_surf_fill_state(&device->isl_dev, state_inout->state.map,2624.surf = isl_surf,2625.view = &view,2626.address = anv_address_physical(state_inout->address),2627.clear_color = *clear_color,2628.aux_surf = &aux_surface->isl,2629.aux_usage = aux_usage,2630.aux_address = anv_address_physical(aux_address),2631.clear_address = anv_address_physical(clear_address),2632.use_clear_address = !anv_address_is_null(clear_address),2633.mocs = anv_mocs(device, state_inout->address.bo,2634view_usage),2635.x_offset_sa = tile_x_sa,2636.y_offset_sa = tile_y_sa);26372638/* With the exception of gfx8, the bottom 12 bits of the MCS base address2639* are used to store other information. This should be ok, however,2640* because the surface buffer addresses are always 4K page aligned.2641*/2642if (!anv_address_is_null(aux_address)) {2643uint32_t *aux_addr_dw = state_inout->state.map +2644device->isl_dev.ss.aux_addr_offset;2645assert((aux_address.offset & 0xfff) == 0);2646state_inout->aux_address.offset |= *aux_addr_dw & 0xfff;2647}26482649if (device->info.ver >= 10 && clear_address.bo) {2650uint32_t *clear_addr_dw = state_inout->state.map +2651device->isl_dev.ss.clear_color_state_offset;2652assert((clear_address.offset & 0x3f) == 0);2653state_inout->clear_address.offset |= *clear_addr_dw & 0x3f;2654}2655}26562657if (image_param_out) {2658assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT);2659isl_surf_fill_image_param(&device->isl_dev, image_param_out,2660&surface->isl, &view);2661}2662}26632664static VkImageAspectFlags2665remap_aspect_flags(VkImageAspectFlags view_aspects)2666{2667if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {2668if (util_bitcount(view_aspects) == 1)2669return VK_IMAGE_ASPECT_COLOR_BIT;26702671VkImageAspectFlags color_aspects = 0;2672for (uint32_t i = 0; i < util_bitcount(view_aspects); i++)2673color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT << i;2674return color_aspects;2675}2676/* No special remapping needed for depth & stencil aspects. */2677return view_aspects;2678}26792680static uint32_t2681anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask)2682{2683uint32_t planes = 0;26842685if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT |2686VK_IMAGE_ASPECT_DEPTH_BIT |2687VK_IMAGE_ASPECT_STENCIL_BIT |2688VK_IMAGE_ASPECT_PLANE_0_BIT))2689planes++;2690if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT)2691planes++;2692if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT)2693planes++;26942695if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 &&2696(aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)2697planes++;26982699return planes;2700}27012702VkResult2703anv_CreateImageView(VkDevice _device,2704const VkImageViewCreateInfo *pCreateInfo,2705const VkAllocationCallbacks *pAllocator,2706VkImageView *pView)2707{2708ANV_FROM_HANDLE(anv_device, device, _device);2709ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);2710struct anv_image_view *iview;27112712iview = vk_object_zalloc(&device->vk, pAllocator, sizeof(*iview),2713VK_OBJECT_TYPE_IMAGE_VIEW);2714if (iview == NULL)2715return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);27162717const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;27182719assert(range->layerCount > 0);2720assert(range->baseMipLevel < image->levels);27212722/* Check if a conversion info was passed. */2723const struct anv_format *conv_format = NULL;2724const VkSamplerYcbcrConversionInfo *conv_info =2725vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);27262727/* If image has an external format, the pNext chain must contain an instance of2728* VKSamplerYcbcrConversionInfo with a conversion object created with the same2729* external format as image."2730*/2731assert(!image->external_format || conv_info);27322733if (conv_info) {2734ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion);2735conv_format = conversion->format;2736}27372738VkImageUsageFlags image_usage = image->usage;2739if (range->aspectMask & (VK_IMAGE_ASPECT_DEPTH_BIT |2740VK_IMAGE_ASPECT_STENCIL_BIT)) {2741assert(!(range->aspectMask & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV));2742/* From the Vulkan 1.2.131 spec:2743*2744* "If the image was has a depth-stencil format and was created with2745* a VkImageStencilUsageCreateInfo structure included in the pNext2746* chain of VkImageCreateInfo, the usage is calculated based on the2747* subresource.aspectMask provided:2748*2749* - If aspectMask includes only VK_IMAGE_ASPECT_STENCIL_BIT, the2750* implicit usage is equal to2751* VkImageStencilUsageCreateInfo::stencilUsage.2752*2753* - If aspectMask includes only VK_IMAGE_ASPECT_DEPTH_BIT, the2754* implicit usage is equal to VkImageCreateInfo::usage.2755*2756* - If both aspects are included in aspectMask, the implicit usage2757* is equal to the intersection of VkImageCreateInfo::usage and2758* VkImageStencilUsageCreateInfo::stencilUsage.2759*/2760if (range->aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) {2761image_usage = image->stencil_usage;2762} else if (range->aspectMask == VK_IMAGE_ASPECT_DEPTH_BIT) {2763image_usage = image->usage;2764} else {2765assert(range->aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT |2766VK_IMAGE_ASPECT_STENCIL_BIT));2767image_usage = image->usage & image->stencil_usage;2768}2769}27702771const VkImageViewUsageCreateInfo *usage_info =2772vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO);2773VkImageUsageFlags view_usage = usage_info ? usage_info->usage : image_usage;27742775/* View usage should be a subset of image usage */2776assert((view_usage & ~image_usage) == 0);2777assert(view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |2778VK_IMAGE_USAGE_STORAGE_BIT |2779VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |2780VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |2781VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));27822783switch (image->type) {2784default:2785unreachable("bad VkImageType");2786case VK_IMAGE_TYPE_1D:2787case VK_IMAGE_TYPE_2D:2788assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);2789break;2790case VK_IMAGE_TYPE_3D:2791assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 12792<= anv_minify(image->extent.depth, range->baseMipLevel));2793break;2794}27952796/* First expand aspects to the image's ones (for example2797* VK_IMAGE_ASPECT_COLOR_BIT will be converted to2798* VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT |2799* VK_IMAGE_ASPECT_PLANE_2_BIT for an image of format2800* VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.2801*/2802VkImageAspectFlags expanded_aspects =2803anv_image_expand_aspects(image, range->aspectMask);28042805iview->image = image;28062807/* Remap the expanded aspects for the image view. For example if only2808* VK_IMAGE_ASPECT_PLANE_1_BIT was given in range->aspectMask, we will2809* convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of2810* the image view, it only has a single plane.2811*/2812iview->aspect_mask = remap_aspect_flags(expanded_aspects);2813iview->n_planes = anv_image_aspect_get_planes(iview->aspect_mask);2814iview->vk_format = pCreateInfo->format;28152816/* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */2817assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED);28182819/* Format is undefined, this can happen when using external formats. Set2820* view format from the passed conversion info.2821*/2822if (iview->vk_format == VK_FORMAT_UNDEFINED && conv_format)2823iview->vk_format = conv_format->vk_format;28242825iview->extent = (VkExtent3D) {2826.width = anv_minify(image->extent.width , range->baseMipLevel),2827.height = anv_minify(image->extent.height, range->baseMipLevel),2828.depth = anv_minify(image->extent.depth , range->baseMipLevel),2829};28302831/* Now go through the underlying image selected planes (computed in2832* expanded_aspects) and map them to planes in the image view.2833*/2834uint32_t vplane = 0;2835anv_foreach_image_aspect_bit(iaspect_bit, image, expanded_aspects) {2836uint32_t iplane =2837anv_image_aspect_to_plane(image->aspects, 1UL << iaspect_bit);2838VkImageAspectFlags vplane_aspect =2839anv_plane_to_aspect(iview->aspect_mask, vplane);2840struct anv_format_plane format =2841anv_get_format_plane(&device->info, iview->vk_format,2842vplane_aspect, image->tiling);28432844iview->planes[vplane].image_plane = iplane;28452846iview->planes[vplane].isl = (struct isl_view) {2847.format = format.isl_format,2848.base_level = range->baseMipLevel,2849.levels = anv_get_levelCount(image, range),2850.base_array_layer = range->baseArrayLayer,2851.array_len = anv_get_layerCount(image, range),2852.swizzle = {2853.r = remap_swizzle(pCreateInfo->components.r,2854VK_COMPONENT_SWIZZLE_R, format.swizzle),2855.g = remap_swizzle(pCreateInfo->components.g,2856VK_COMPONENT_SWIZZLE_G, format.swizzle),2857.b = remap_swizzle(pCreateInfo->components.b,2858VK_COMPONENT_SWIZZLE_B, format.swizzle),2859.a = remap_swizzle(pCreateInfo->components.a,2860VK_COMPONENT_SWIZZLE_A, format.swizzle),2861},2862};28632864if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {2865iview->planes[vplane].isl.base_array_layer = 0;2866iview->planes[vplane].isl.array_len = iview->extent.depth;2867}28682869if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||2870pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {2871iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT;2872} else {2873iview->planes[vplane].isl.usage = 0;2874}28752876if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||2877(view_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&2878!(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {2879iview->planes[vplane].optimal_sampler_surface_state.state = alloc_surface_state(device);2880iview->planes[vplane].general_sampler_surface_state.state = alloc_surface_state(device);28812882enum isl_aux_usage general_aux_usage =2883anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,2884VK_IMAGE_USAGE_SAMPLED_BIT,2885VK_IMAGE_LAYOUT_GENERAL);2886enum isl_aux_usage optimal_aux_usage =2887anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,2888VK_IMAGE_USAGE_SAMPLED_BIT,2889VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);28902891anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,2892&iview->planes[vplane].isl,2893ISL_SURF_USAGE_TEXTURE_BIT,2894optimal_aux_usage, NULL,2895ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL,2896&iview->planes[vplane].optimal_sampler_surface_state,2897NULL);28982899anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,2900&iview->planes[vplane].isl,2901ISL_SURF_USAGE_TEXTURE_BIT,2902general_aux_usage, NULL,29030,2904&iview->planes[vplane].general_sampler_surface_state,2905NULL);2906}29072908/* NOTE: This one needs to go last since it may stomp isl_view.format */2909if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {2910if (isl_is_storage_image_format(format.isl_format)) {2911iview->planes[vplane].storage_surface_state.state =2912alloc_surface_state(device);29132914anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,2915&iview->planes[vplane].isl,2916ISL_SURF_USAGE_STORAGE_BIT,2917ISL_AUX_USAGE_NONE, NULL,29180,2919&iview->planes[vplane].storage_surface_state,2920&iview->planes[vplane].storage_image_param);2921} else {2922/* In this case, we support the format but, because there's no2923* SPIR-V format specifier corresponding to it, we only support2924* NonReadable (writeonly in GLSL) access. Instead of hanging in2925* these invalid cases, we give them a NULL descriptor.2926*/2927assert(isl_format_supports_typed_writes(&device->info,2928format.isl_format));2929iview->planes[vplane].storage_surface_state.state =2930device->null_surface_state;2931}29322933iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device);2934anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,2935&iview->planes[vplane].isl,2936ISL_SURF_USAGE_STORAGE_BIT,2937ISL_AUX_USAGE_NONE, NULL,2938ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY,2939&iview->planes[vplane].writeonly_storage_surface_state,2940NULL);2941}29422943vplane++;2944}29452946*pView = anv_image_view_to_handle(iview);29472948return VK_SUCCESS;2949}29502951void2952anv_DestroyImageView(VkDevice _device, VkImageView _iview,2953const VkAllocationCallbacks *pAllocator)2954{2955ANV_FROM_HANDLE(anv_device, device, _device);2956ANV_FROM_HANDLE(anv_image_view, iview, _iview);29572958if (!iview)2959return;29602961for (uint32_t plane = 0; plane < iview->n_planes; plane++) {2962/* Check offset instead of alloc_size because this they might be2963* device->null_surface_state which always has offset == 0. We don't2964* own that one so we don't want to accidentally free it.2965*/2966if (iview->planes[plane].optimal_sampler_surface_state.state.offset) {2967anv_state_pool_free(&device->surface_state_pool,2968iview->planes[plane].optimal_sampler_surface_state.state);2969}29702971if (iview->planes[plane].general_sampler_surface_state.state.offset) {2972anv_state_pool_free(&device->surface_state_pool,2973iview->planes[plane].general_sampler_surface_state.state);2974}29752976if (iview->planes[plane].storage_surface_state.state.offset) {2977anv_state_pool_free(&device->surface_state_pool,2978iview->planes[plane].storage_surface_state.state);2979}29802981if (iview->planes[plane].writeonly_storage_surface_state.state.offset) {2982anv_state_pool_free(&device->surface_state_pool,2983iview->planes[plane].writeonly_storage_surface_state.state);2984}2985}29862987vk_object_free(&device->vk, pAllocator, iview);2988}298929902991VkResult2992anv_CreateBufferView(VkDevice _device,2993const VkBufferViewCreateInfo *pCreateInfo,2994const VkAllocationCallbacks *pAllocator,2995VkBufferView *pView)2996{2997ANV_FROM_HANDLE(anv_device, device, _device);2998ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);2999struct anv_buffer_view *view;30003001view = vk_object_alloc(&device->vk, pAllocator, sizeof(*view),3002VK_OBJECT_TYPE_BUFFER_VIEW);3003if (!view)3004return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);30053006/* TODO: Handle the format swizzle? */30073008view->format = anv_get_isl_format(&device->info, pCreateInfo->format,3009VK_IMAGE_ASPECT_COLOR_BIT,3010VK_IMAGE_TILING_LINEAR);3011const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;3012view->range = anv_buffer_get_range(buffer, pCreateInfo->offset,3013pCreateInfo->range);3014view->range = align_down_npot_u32(view->range, format_bs);30153016view->address = anv_address_add(buffer->address, pCreateInfo->offset);30173018if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {3019view->surface_state = alloc_surface_state(device);30203021anv_fill_buffer_surface_state(device, view->surface_state,3022view->format, ISL_SURF_USAGE_TEXTURE_BIT,3023view->address, view->range, format_bs);3024} else {3025view->surface_state = (struct anv_state){ 0 };3026}30273028if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {3029view->storage_surface_state = alloc_surface_state(device);3030view->writeonly_storage_surface_state = alloc_surface_state(device);30313032enum isl_format storage_format =3033isl_has_matching_typed_storage_image_format(&device->info,3034view->format) ?3035isl_lower_storage_image_format(&device->info, view->format) :3036ISL_FORMAT_RAW;30373038anv_fill_buffer_surface_state(device, view->storage_surface_state,3039storage_format, ISL_SURF_USAGE_STORAGE_BIT,3040view->address, view->range,3041(storage_format == ISL_FORMAT_RAW ? 1 :3042isl_format_get_layout(storage_format)->bpb / 8));30433044/* Write-only accesses should use the original format. */3045anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state,3046view->format, ISL_SURF_USAGE_STORAGE_BIT,3047view->address, view->range,3048isl_format_get_layout(view->format)->bpb / 8);30493050isl_buffer_fill_image_param(&device->isl_dev,3051&view->storage_image_param,3052view->format, view->range);3053} else {3054view->storage_surface_state = (struct anv_state){ 0 };3055view->writeonly_storage_surface_state = (struct anv_state){ 0 };3056}30573058*pView = anv_buffer_view_to_handle(view);30593060return VK_SUCCESS;3061}30623063void3064anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,3065const VkAllocationCallbacks *pAllocator)3066{3067ANV_FROM_HANDLE(anv_device, device, _device);3068ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);30693070if (!view)3071return;30723073if (view->surface_state.alloc_size > 0)3074anv_state_pool_free(&device->surface_state_pool,3075view->surface_state);30763077if (view->storage_surface_state.alloc_size > 0)3078anv_state_pool_free(&device->surface_state_pool,3079view->storage_surface_state);30803081if (view->writeonly_storage_surface_state.alloc_size > 0)3082anv_state_pool_free(&device->surface_state_pool,3083view->writeonly_storage_surface_state);30843085vk_object_free(&device->vk, pAllocator, view);3086}308730883089