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