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