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