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