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