xref: /third_party/mesa3d/src/amd/vulkan/radv_image.c (revision bf215546)
1/*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 */
27
28#include "ac_drm_fourcc.h"
29#include "util/debug.h"
30#include "util/u_atomic.h"
31#include "vulkan/util/vk_format.h"
32#include "radv_debug.h"
33#include "radv_private.h"
34#include "radv_radeon_winsys.h"
35#include "sid.h"
36#include "vk_format.h"
37#include "vk_util.h"
38
39#include "gfx10_format_table.h"
40
41static unsigned
42radv_choose_tiling(struct radv_device *device, const VkImageCreateInfo *pCreateInfo,
43                   VkFormat format)
44{
45   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
46      assert(pCreateInfo->samples <= 1);
47      return RADEON_SURF_MODE_LINEAR_ALIGNED;
48   }
49
50   /* MSAA resources must be 2D tiled. */
51   if (pCreateInfo->samples > 1)
52      return RADEON_SURF_MODE_2D;
53
54   if (!vk_format_is_compressed(format) && !vk_format_is_depth_or_stencil(format) &&
55       device->physical_device->rad_info.gfx_level <= GFX8) {
56      /* this causes hangs in some VK CTS tests on GFX9. */
57      /* Textures with a very small height are recommended to be linear. */
58      if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
59          /* Only very thin and long 2D textures should benefit from
60           * linear_aligned. */
61          (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
62         return RADEON_SURF_MODE_LINEAR_ALIGNED;
63   }
64
65   return RADEON_SURF_MODE_2D;
66}
67
68static bool
69radv_use_tc_compat_htile_for_image(struct radv_device *device, const VkImageCreateInfo *pCreateInfo,
70                                   VkFormat format)
71{
72   /* TC-compat HTILE is only available for GFX8+. */
73   if (device->physical_device->rad_info.gfx_level < GFX8)
74      return false;
75
76   if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT))
77      return false;
78
79   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
80      return false;
81
82   /* Do not enable TC-compatible HTILE if the image isn't readable by a
83    * shader because no texture fetches will happen.
84    */
85   if (!(pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
86                               VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
87      return false;
88
89   if (device->physical_device->rad_info.gfx_level < GFX9) {
90      /* TC-compat HTILE for MSAA depth/stencil images is broken
91       * on GFX8 because the tiling doesn't match.
92       */
93      if (pCreateInfo->samples >= 2 && format == VK_FORMAT_D32_SFLOAT_S8_UINT)
94         return false;
95
96      /* GFX9+ supports compression for both 32-bit and 16-bit depth
97       * surfaces, while GFX8 only supports 32-bit natively. Though,
98       * the driver allows TC-compat HTILE for 16-bit depth surfaces
99       * with no Z planes compression.
100       */
101      if (format != VK_FORMAT_D32_SFLOAT_S8_UINT && format != VK_FORMAT_D32_SFLOAT &&
102          format != VK_FORMAT_D16_UNORM)
103         return false;
104   }
105
106   return true;
107}
108
109static bool
110radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info)
111{
112   if (info->bo_metadata) {
113      if (device->physical_device->rad_info.gfx_level >= GFX9)
114         return info->bo_metadata->u.gfx9.scanout;
115      else
116         return info->bo_metadata->u.legacy.scanout;
117   }
118
119   return info->scanout;
120}
121
122static bool
123radv_image_use_fast_clear_for_image_early(const struct radv_device *device,
124                                          const struct radv_image *image)
125{
126   if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
127      return true;
128
129   if (image->info.samples <= 1 && image->info.width * image->info.height <= 512 * 512) {
130      /* Do not enable CMASK or DCC for small surfaces where the cost
131       * of the eliminate pass can be higher than the benefit of fast
132       * clear. RadeonSI does this, but the image threshold is
133       * different.
134       */
135      return false;
136   }
137
138   return !!(image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
139}
140
141static bool
142radv_image_use_fast_clear_for_image(const struct radv_device *device,
143                                    const struct radv_image *image)
144{
145   if (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
146      return true;
147
148   return radv_image_use_fast_clear_for_image_early(device, image) &&
149          (image->exclusive ||
150           /* Enable DCC for concurrent images if stores are
151            * supported because that means we can keep DCC compressed on
152            * all layouts/queues.
153            */
154           radv_image_use_dcc_image_stores(device, image));
155}
156
157bool
158radv_are_formats_dcc_compatible(const struct radv_physical_device *pdev, const void *pNext,
159                                VkFormat format, VkImageCreateFlags flags, bool *sign_reinterpret)
160{
161   bool blendable;
162
163   if (!radv_is_colorbuffer_format_supported(pdev, format, &blendable))
164      return false;
165
166   if (sign_reinterpret != NULL)
167      *sign_reinterpret = false;
168
169   if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
170      const struct VkImageFormatListCreateInfo *format_list =
171         (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(
172            pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
173
174      /* We have to ignore the existence of the list if viewFormatCount = 0 */
175      if (format_list && format_list->viewFormatCount) {
176         /* compatibility is transitive, so we only need to check
177          * one format with everything else. */
178         for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
179            if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
180               continue;
181
182            if (!radv_dcc_formats_compatible(pdev->rad_info.gfx_level, format,
183                                             format_list->pViewFormats[i], sign_reinterpret))
184               return false;
185         }
186      } else {
187         return false;
188      }
189   }
190
191   return true;
192}
193
194static bool
195radv_format_is_atomic_allowed(struct radv_device *device, VkFormat format)
196{
197   if (format == VK_FORMAT_R32_SFLOAT && !device->image_float32_atomics)
198      return false;
199
200   return radv_is_atomic_format_supported(format);
201}
202
203static bool
204radv_formats_is_atomic_allowed(struct radv_device *device, const void *pNext, VkFormat format,
205                               VkImageCreateFlags flags)
206{
207   if (radv_format_is_atomic_allowed(device, format))
208      return true;
209
210   if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
211      const struct VkImageFormatListCreateInfo *format_list =
212         (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(
213            pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
214
215      /* We have to ignore the existence of the list if viewFormatCount = 0 */
216      if (format_list && format_list->viewFormatCount) {
217         for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
218            if (radv_format_is_atomic_allowed(device, format_list->pViewFormats[i]))
219               return true;
220         }
221      }
222   }
223
224   return false;
225}
226
227static bool
228radv_use_dcc_for_image_early(struct radv_device *device, struct radv_image *image,
229                             const VkImageCreateInfo *pCreateInfo, VkFormat format,
230                             bool *sign_reinterpret)
231{
232   /* DCC (Delta Color Compression) is only available for GFX8+. */
233   if (device->physical_device->rad_info.gfx_level < GFX8)
234      return false;
235
236   if (device->instance->debug_flags & RADV_DEBUG_NO_DCC)
237      return false;
238
239   if (image->shareable && image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
240      return false;
241
242   /*
243    * TODO: Enable DCC for storage images on GFX9 and earlier.
244    *
245    * Also disable DCC with atomics because even when DCC stores are
246    * supported atomics will always decompress. So if we are
247    * decompressing a lot anyway we might as well not have DCC.
248    */
249   if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
250       (device->physical_device->rad_info.gfx_level < GFX10 ||
251        radv_formats_is_atomic_allowed(device, pCreateInfo->pNext, format, pCreateInfo->flags)))
252      return false;
253
254   /* Do not enable DCC for fragment shading rate attachments. */
255   if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)
256      return false;
257
258   if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
259      return false;
260
261   if (vk_format_is_subsampled(format) || vk_format_get_plane_count(format) > 1)
262      return false;
263
264   if (!radv_image_use_fast_clear_for_image_early(device, image) &&
265       image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
266      return false;
267
268   /* Do not enable DCC for mipmapped arrays because performance is worse. */
269   if (pCreateInfo->arrayLayers > 1 && pCreateInfo->mipLevels > 1)
270      return false;
271
272   if (device->physical_device->rad_info.gfx_level < GFX10) {
273      /* TODO: Add support for DCC MSAA on GFX8-9. */
274      if (pCreateInfo->samples > 1 && !device->physical_device->dcc_msaa_allowed)
275         return false;
276
277      /* TODO: Add support for DCC layers/mipmaps on GFX9. */
278      if ((pCreateInfo->arrayLayers > 1 || pCreateInfo->mipLevels > 1) &&
279          device->physical_device->rad_info.gfx_level == GFX9)
280         return false;
281   }
282
283   return radv_are_formats_dcc_compatible(device->physical_device, pCreateInfo->pNext, format,
284                                          pCreateInfo->flags, sign_reinterpret);
285}
286
287static bool
288radv_use_dcc_for_image_late(struct radv_device *device, struct radv_image *image)
289{
290   if (!radv_image_has_dcc(image))
291      return false;
292
293   if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
294      return true;
295
296   if (!radv_image_use_fast_clear_for_image(device, image))
297      return false;
298
299   /* TODO: Fix storage images with DCC without DCC image stores.
300    * Disabling it for now. */
301   if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
302       !radv_image_use_dcc_image_stores(device, image))
303      return false;
304
305   return true;
306}
307
308/*
309 * Whether to enable image stores with DCC compression for this image. If
310 * this function returns false the image subresource should be decompressed
311 * before using it with image stores.
312 *
313 * Note that this can have mixed performance implications, see
314 * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6796#note_643299
315 *
316 * This function assumes the image uses DCC compression.
317 */
318bool
319radv_image_use_dcc_image_stores(const struct radv_device *device, const struct radv_image *image)
320{
321   return ac_surface_supports_dcc_image_stores(device->physical_device->rad_info.gfx_level,
322                                               &image->planes[0].surface);
323}
324
325/*
326 * Whether to use a predicate to determine whether DCC is in a compressed
327 * state. This can be used to avoid decompressing an image multiple times.
328 */
329bool
330radv_image_use_dcc_predication(const struct radv_device *device, const struct radv_image *image)
331{
332   return radv_image_has_dcc(image) && !radv_image_use_dcc_image_stores(device, image);
333}
334
335static inline bool
336radv_use_fmask_for_image(const struct radv_device *device, const struct radv_image *image)
337{
338   return image->info.samples > 1 && ((image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) ||
339                                      (device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS));
340}
341
342static inline bool
343radv_use_htile_for_image(const struct radv_device *device, const struct radv_image *image)
344{
345   /* TODO:
346    * - Investigate about mips+layers.
347    * - Enable on other gens.
348    */
349   bool use_htile_for_mips =
350      image->info.array_size == 1 && device->physical_device->rad_info.gfx_level >= GFX10;
351
352   /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */
353   if (device->physical_device->rad_info.gfx_level == GFX10 &&
354       image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->info.levels > 1)
355      return false;
356
357   /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */
358   if (device->physical_device->rad_info.chip_class == GFX10 &&
359       image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->info.levels > 1)
360      return false;
361
362   /* Do not enable HTILE for very small images because it seems less performant but make sure it's
363    * allowed with VRS attachments because we need HTILE.
364    */
365   if (image->info.width * image->info.height < 8 * 8 &&
366       !(device->instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) &&
367       !device->attachment_vrs_enabled)
368      return false;
369
370   return (image->info.levels == 1 || use_htile_for_mips) && !image->shareable;
371}
372
373static bool
374radv_use_tc_compat_cmask_for_image(struct radv_device *device, struct radv_image *image)
375{
376   /* TC-compat CMASK is only available for GFX8+. */
377   if (device->physical_device->rad_info.gfx_level < GFX8)
378      return false;
379
380   if (device->instance->debug_flags & RADV_DEBUG_NO_TC_COMPAT_CMASK)
381      return false;
382
383   /* TC-compat CMASK with storage images is supported on GFX10+. */
384   if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
385       device->physical_device->rad_info.gfx_level < GFX10)
386      return false;
387
388   /* Do not enable TC-compatible if the image isn't readable by a shader
389    * because no texture fetches will happen.
390    */
391   if (!(image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
392                            VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
393      return false;
394
395   /* If the image doesn't have FMASK, it can't be fetchable. */
396   if (!radv_image_has_fmask(image))
397      return false;
398
399   return true;
400}
401
402static uint32_t
403si_get_bo_metadata_word1(const struct radv_device *device)
404{
405   return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id;
406}
407
408static bool
409radv_is_valid_opaque_metadata(const struct radv_device *device, const struct radeon_bo_metadata *md)
410{
411   if (md->metadata[0] != 1 || md->metadata[1] != si_get_bo_metadata_word1(device))
412      return false;
413
414   if (md->size_metadata < 40)
415      return false;
416
417   return true;
418}
419
420static void
421radv_patch_surface_from_metadata(struct radv_device *device, struct radeon_surf *surface,
422                                 const struct radeon_bo_metadata *md)
423{
424   surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
425
426   if (device->physical_device->rad_info.gfx_level >= GFX9) {
427      if (md->u.gfx9.swizzle_mode > 0)
428         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
429      else
430         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
431
432      surface->u.gfx9.swizzle_mode = md->u.gfx9.swizzle_mode;
433   } else {
434      surface->u.legacy.pipe_config = md->u.legacy.pipe_config;
435      surface->u.legacy.bankw = md->u.legacy.bankw;
436      surface->u.legacy.bankh = md->u.legacy.bankh;
437      surface->u.legacy.tile_split = md->u.legacy.tile_split;
438      surface->u.legacy.mtilea = md->u.legacy.mtilea;
439      surface->u.legacy.num_banks = md->u.legacy.num_banks;
440
441      if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
442         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
443      else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
444         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
445      else
446         surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
447   }
448}
449
450static VkResult
451radv_patch_image_dimensions(struct radv_device *device, struct radv_image *image,
452                            const struct radv_image_create_info *create_info,
453                            struct ac_surf_info *image_info)
454{
455   unsigned width = image->info.width;
456   unsigned height = image->info.height;
457
458   /*
459    * minigbm sometimes allocates bigger images which is going to result in
460    * weird strides and other properties. Lets be lenient where possible and
461    * fail it on GFX10 (as we cannot cope there).
462    *
463    * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
464    */
465   if (create_info->bo_metadata &&
466       radv_is_valid_opaque_metadata(device, create_info->bo_metadata)) {
467      const struct radeon_bo_metadata *md = create_info->bo_metadata;
468
469      if (device->physical_device->rad_info.gfx_level >= GFX10) {
470         width = G_00A004_WIDTH_LO(md->metadata[3]) + (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1;
471         height = G_00A008_HEIGHT(md->metadata[4]) + 1;
472      } else {
473         width = G_008F18_WIDTH(md->metadata[4]) + 1;
474         height = G_008F18_HEIGHT(md->metadata[4]) + 1;
475      }
476   }
477
478   if (image->info.width == width && image->info.height == height)
479      return VK_SUCCESS;
480
481   if (width < image->info.width || height < image->info.height) {
482      fprintf(stderr,
483              "The imported image has smaller dimensions than the internal\n"
484              "dimensions. Using it is going to fail badly, so we reject\n"
485              "this import.\n"
486              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
487              image->info.width, image->info.height, width, height);
488      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
489   } else if (device->physical_device->rad_info.gfx_level >= GFX10) {
490      fprintf(stderr,
491              "Tried to import an image with inconsistent width on GFX10.\n"
492              "As GFX10 has no separate stride fields we cannot cope with\n"
493              "an inconsistency in width and will fail this import.\n"
494              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
495              image->info.width, image->info.height, width, height);
496      return VK_ERROR_INVALID_EXTERNAL_HANDLE;
497   } else {
498      fprintf(stderr,
499              "Tried to import an image with inconsistent width on pre-GFX10.\n"
500              "As GFX10 has no separate stride fields we cannot cope with\n"
501              "an inconsistency and would fail on GFX10.\n"
502              "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
503              image->info.width, image->info.height, width, height);
504   }
505   image_info->width = width;
506   image_info->height = height;
507
508   return VK_SUCCESS;
509}
510
511static VkResult
512radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image *image,
513                                 const struct radv_image_create_info *create_info,
514                                 struct ac_surf_info *image_info)
515{
516   VkResult result = radv_patch_image_dimensions(device, image, create_info, image_info);
517   if (result != VK_SUCCESS)
518      return result;
519
520   for (unsigned plane = 0; plane < image->plane_count; ++plane) {
521      if (create_info->bo_metadata) {
522         radv_patch_surface_from_metadata(device, &image->planes[plane].surface,
523                                          create_info->bo_metadata);
524      }
525
526      if (radv_surface_has_scanout(device, create_info)) {
527         image->planes[plane].surface.flags |= RADEON_SURF_SCANOUT;
528         if (device->instance->debug_flags & RADV_DEBUG_NO_DISPLAY_DCC)
529            image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
530
531         image->info.surf_index = NULL;
532      }
533
534      if (create_info->prime_blit_src && device->physical_device->rad_info.gfx_level == GFX9) {
535         /* Older SDMA hw can't handle DCC */
536         image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
537      }
538   }
539   return VK_SUCCESS;
540}
541
542static VkFormat
543etc2_emulation_format(VkFormat format)
544{
545   switch (format) {
546   case VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK:
547   case VK_FORMAT_ETC2_R8G8B8A1_UNORM_BLOCK:
548   case VK_FORMAT_ETC2_R8G8B8A8_UNORM_BLOCK:
549      return VK_FORMAT_R8G8B8A8_UNORM;
550   case VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK:
551   case VK_FORMAT_ETC2_R8G8B8A1_SRGB_BLOCK:
552   case VK_FORMAT_ETC2_R8G8B8A8_SRGB_BLOCK:
553      return VK_FORMAT_R8G8B8A8_SRGB;
554   case VK_FORMAT_EAC_R11_UNORM_BLOCK:
555      return VK_FORMAT_R16_UNORM;
556   case VK_FORMAT_EAC_R11_SNORM_BLOCK:
557      return VK_FORMAT_R16_SNORM;
558   case VK_FORMAT_EAC_R11G11_UNORM_BLOCK:
559      return VK_FORMAT_R16G16_UNORM;
560   case VK_FORMAT_EAC_R11G11_SNORM_BLOCK:
561      return VK_FORMAT_R16G16_SNORM;
562   default:
563      unreachable("Unhandled ETC format");
564   }
565}
566
567static VkFormat
568radv_image_get_plane_format(const struct radv_physical_device *pdev, const struct radv_image *image,
569                            unsigned plane)
570{
571   if (pdev->emulate_etc2 &&
572       vk_format_description(image->vk.format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
573      if (plane == 0)
574         return image->vk.format;
575      return etc2_emulation_format(image->vk.format);
576   }
577   return vk_format_get_plane_format(image->vk.format, plane);
578}
579
580static uint64_t
581radv_get_surface_flags(struct radv_device *device, struct radv_image *image, unsigned plane_id,
582                       const VkImageCreateInfo *pCreateInfo, VkFormat image_format)
583{
584   uint64_t flags;
585   unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
586   VkFormat format = radv_image_get_plane_format(device->physical_device, image, plane_id);
587   const struct util_format_description *desc = vk_format_description(format);
588   bool is_depth, is_stencil;
589
590   is_depth = util_format_has_depth(desc);
591   is_stencil = util_format_has_stencil(desc);
592
593   flags = RADEON_SURF_SET(array_mode, MODE);
594
595   switch (pCreateInfo->imageType) {
596   case VK_IMAGE_TYPE_1D:
597      if (pCreateInfo->arrayLayers > 1)
598         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
599      else
600         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
601      break;
602   case VK_IMAGE_TYPE_2D:
603      if (pCreateInfo->arrayLayers > 1)
604         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
605      else
606         flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
607      break;
608   case VK_IMAGE_TYPE_3D:
609      flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
610      break;
611   default:
612      unreachable("unhandled image type");
613   }
614
615   /* Required for clearing/initializing a specific layer on GFX8. */
616   flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS;
617
618   if (is_depth) {
619      flags |= RADEON_SURF_ZBUFFER;
620
621      if (radv_use_htile_for_image(device, image) &&
622          !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) {
623         if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
624            flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
625      } else {
626         flags |= RADEON_SURF_NO_HTILE;
627      }
628   }
629
630   if (is_stencil)
631      flags |= RADEON_SURF_SBUFFER;
632
633   if (device->physical_device->rad_info.gfx_level >= GFX9 &&
634       pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
635       vk_format_get_blocksizebits(image_format) == 128 && vk_format_is_compressed(image_format))
636      flags |= RADEON_SURF_NO_RENDER_TARGET;
637
638   if (!radv_use_dcc_for_image_early(device, image, pCreateInfo, image_format,
639                                     &image->dcc_sign_reinterpret))
640      flags |= RADEON_SURF_DISABLE_DCC;
641
642   if (!radv_use_fmask_for_image(device, image))
643      flags |= RADEON_SURF_NO_FMASK;
644
645   if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
646      flags |=
647         RADEON_SURF_PRT | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE | RADEON_SURF_DISABLE_DCC;
648   }
649
650   return flags;
651}
652
653static inline unsigned
654si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
655{
656   if (stencil)
657      return plane->surface.u.legacy.zs.stencil_tiling_index[level];
658   else
659      return plane->surface.u.legacy.tiling_index[level];
660}
661
662static unsigned
663radv_map_swizzle(unsigned swizzle)
664{
665   switch (swizzle) {
666   case PIPE_SWIZZLE_Y:
667      return V_008F0C_SQ_SEL_Y;
668   case PIPE_SWIZZLE_Z:
669      return V_008F0C_SQ_SEL_Z;
670   case PIPE_SWIZZLE_W:
671      return V_008F0C_SQ_SEL_W;
672   case PIPE_SWIZZLE_0:
673      return V_008F0C_SQ_SEL_0;
674   case PIPE_SWIZZLE_1:
675      return V_008F0C_SQ_SEL_1;
676   default: /* PIPE_SWIZZLE_X */
677      return V_008F0C_SQ_SEL_X;
678   }
679}
680
681static void
682radv_compose_swizzle(const struct util_format_description *desc, const VkComponentMapping *mapping,
683                     enum pipe_swizzle swizzle[4])
684{
685   if (desc->format == PIPE_FORMAT_R64_UINT || desc->format == PIPE_FORMAT_R64_SINT) {
686      /* 64-bit formats only support storage images and storage images
687       * require identity component mappings. We use 32-bit
688       * instructions to access 64-bit images, so we need a special
689       * case here.
690       *
691       * The zw components are 1,0 so that they can be easily be used
692       * by loads to create the w component, which has to be 0 for
693       * NULL descriptors.
694       */
695      swizzle[0] = PIPE_SWIZZLE_X;
696      swizzle[1] = PIPE_SWIZZLE_Y;
697      swizzle[2] = PIPE_SWIZZLE_1;
698      swizzle[3] = PIPE_SWIZZLE_0;
699   } else if (!mapping) {
700      for (unsigned i = 0; i < 4; i++)
701         swizzle[i] = desc->swizzle[i];
702   } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
703      const unsigned char swizzle_xxxx[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_0, PIPE_SWIZZLE_0,
704                                             PIPE_SWIZZLE_1};
705      vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
706   } else {
707      vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
708   }
709}
710
711static void
712radv_make_buffer_descriptor(struct radv_device *device, struct radv_buffer *buffer,
713                            VkFormat vk_format, unsigned offset, unsigned range, uint32_t *state)
714{
715   const struct util_format_description *desc;
716   unsigned stride;
717   uint64_t gpu_address = radv_buffer_get_va(buffer->bo);
718   uint64_t va = gpu_address + buffer->offset;
719   unsigned num_format, data_format;
720   int first_non_void;
721   enum pipe_swizzle swizzle[4];
722   desc = vk_format_description(vk_format);
723   first_non_void = vk_format_get_first_non_void_channel(vk_format);
724   stride = desc->block.bits / 8;
725
726   radv_compose_swizzle(desc, NULL, swizzle);
727
728   va += offset;
729   state[0] = va;
730   state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) | S_008F04_STRIDE(stride);
731
732   if (device->physical_device->rad_info.gfx_level != GFX8 && stride) {
733      range /= stride;
734   }
735
736   state[2] = range;
737   state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
738              S_008F0C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
739              S_008F0C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
740              S_008F0C_DST_SEL_W(radv_map_swizzle(swizzle[3]));
741
742   if (device->physical_device->rad_info.gfx_level >= GFX10) {
743      const struct gfx10_format *fmt = &ac_get_gfx10_format_table(&device->physical_device->rad_info)[vk_format_to_pipe_format(vk_format)];
744
745      /* OOB_SELECT chooses the out-of-bounds check:
746       *  - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
747       *  - 1: index >= NUM_RECORDS
748       *  - 2: NUM_RECORDS == 0
749       *  - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
750       *       else: swizzle_address >= NUM_RECORDS
751       */
752      state[3] |= S_008F0C_FORMAT(fmt->img_format) |
753                  S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET) |
754                  S_008F0C_RESOURCE_LEVEL(device->physical_device->rad_info.gfx_level < GFX11);
755   } else {
756      num_format = radv_translate_buffer_numformat(desc, first_non_void);
757      data_format = radv_translate_buffer_dataformat(desc, first_non_void);
758
759      assert(data_format != V_008F0C_BUF_DATA_FORMAT_INVALID);
760      assert(num_format != ~0);
761
762      state[3] |= S_008F0C_NUM_FORMAT(num_format) | S_008F0C_DATA_FORMAT(data_format);
763   }
764}
765
766static void
767si_set_mutable_tex_desc_fields(struct radv_device *device, struct radv_image *image,
768                               const struct legacy_surf_level *base_level_info, unsigned plane_id,
769                               unsigned base_level, unsigned first_level, unsigned block_width,
770                               bool is_stencil, bool is_storage_image, bool disable_compression,
771                               bool enable_write_compression, uint32_t *state)
772{
773   struct radv_image_plane *plane = &image->planes[plane_id];
774   struct radv_image_binding *binding = image->disjoint ? &image->bindings[plane_id] : &image->bindings[0];
775   uint64_t gpu_address = binding->bo ? radv_buffer_get_va(binding->bo) + binding->offset : 0;
776   uint64_t va = gpu_address;
777   enum amd_gfx_level gfx_level = device->physical_device->rad_info.gfx_level;
778   uint64_t meta_va = 0;
779   if (gfx_level >= GFX9) {
780      if (is_stencil)
781         va += plane->surface.u.gfx9.zs.stencil_offset;
782      else
783         va += plane->surface.u.gfx9.surf_offset;
784   } else
785      va += (uint64_t)base_level_info->offset_256B * 256;
786
787   state[0] = va >> 8;
788   if (gfx_level >= GFX9 || base_level_info->mode == RADEON_SURF_MODE_2D)
789      state[0] |= plane->surface.tile_swizzle;
790   state[1] &= C_008F14_BASE_ADDRESS_HI;
791   state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
792
793   if (gfx_level >= GFX8) {
794      state[6] &= C_008F28_COMPRESSION_EN;
795      state[7] = 0;
796      if (!disable_compression && radv_dcc_enabled(image, first_level)) {
797         meta_va = gpu_address + plane->surface.meta_offset;
798         if (gfx_level <= GFX8)
799            meta_va += plane->surface.u.legacy.color.dcc_level[base_level].dcc_offset;
800
801         unsigned dcc_tile_swizzle = plane->surface.tile_swizzle << 8;
802         dcc_tile_swizzle &= (1 << plane->surface.meta_alignment_log2) - 1;
803         meta_va |= dcc_tile_swizzle;
804      } else if (!disable_compression && radv_image_is_tc_compat_htile(image)) {
805         meta_va = gpu_address + plane->surface.meta_offset;
806      }
807
808      if (meta_va) {
809         state[6] |= S_008F28_COMPRESSION_EN(1);
810         if (gfx_level <= GFX9)
811            state[7] = meta_va >> 8;
812      }
813   }
814
815   if (gfx_level >= GFX10) {
816      state[3] &= C_00A00C_SW_MODE;
817
818      if (is_stencil) {
819         state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode);
820      } else {
821         state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.swizzle_mode);
822      }
823
824      state[6] &= C_00A018_META_DATA_ADDRESS_LO & C_00A018_META_PIPE_ALIGNED;
825
826      if (meta_va) {
827         struct gfx9_surf_meta_flags meta = {
828            .rb_aligned = 1,
829            .pipe_aligned = 1,
830         };
831
832         if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER))
833            meta = plane->surface.u.gfx9.color.dcc;
834
835         if (radv_dcc_enabled(image, first_level) && is_storage_image && enable_write_compression)
836            state[6] |= S_00A018_WRITE_COMPRESS_ENABLE(1);
837
838         state[6] |= S_00A018_META_PIPE_ALIGNED(meta.pipe_aligned) |
839                     S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8);
840      }
841
842      state[7] = meta_va >> 16;
843   } else if (gfx_level == GFX9) {
844      state[3] &= C_008F1C_SW_MODE;
845      state[4] &= C_008F20_PITCH;
846
847      if (is_stencil) {
848         state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.zs.stencil_swizzle_mode);
849         state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.zs.stencil_epitch);
850      } else {
851         state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.swizzle_mode);
852         state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.epitch);
853      }
854
855      state[5] &=
856         C_008F24_META_DATA_ADDRESS & C_008F24_META_PIPE_ALIGNED & C_008F24_META_RB_ALIGNED;
857      if (meta_va) {
858         struct gfx9_surf_meta_flags meta = {
859            .rb_aligned = 1,
860            .pipe_aligned = 1,
861         };
862
863         if (!(plane->surface.flags & RADEON_SURF_Z_OR_SBUFFER))
864            meta = plane->surface.u.gfx9.color.dcc;
865
866         state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) |
867                     S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) |
868                     S_008F24_META_RB_ALIGNED(meta.rb_aligned);
869      }
870   } else {
871      /* GFX6-GFX8 */
872      unsigned pitch = base_level_info->nblk_x * block_width;
873      unsigned index = si_tile_mode_index(plane, base_level, is_stencil);
874
875      state[3] &= C_008F1C_TILING_INDEX;
876      state[3] |= S_008F1C_TILING_INDEX(index);
877      state[4] &= C_008F20_PITCH;
878      state[4] |= S_008F20_PITCH(pitch - 1);
879   }
880}
881
882static unsigned
883radv_tex_dim(VkImageType image_type, VkImageViewType view_type, unsigned nr_layers,
884             unsigned nr_samples, bool is_storage_image, bool gfx9)
885{
886   if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
887      return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
888
889   /* GFX9 allocates 1D textures as 2D. */
890   if (gfx9 && image_type == VK_IMAGE_TYPE_1D)
891      image_type = VK_IMAGE_TYPE_2D;
892   switch (image_type) {
893   case VK_IMAGE_TYPE_1D:
894      return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
895   case VK_IMAGE_TYPE_2D:
896      if (nr_samples > 1)
897         return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY : V_008F1C_SQ_RSRC_IMG_2D_MSAA;
898      else
899         return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_2D;
900   case VK_IMAGE_TYPE_3D:
901      if (view_type == VK_IMAGE_VIEW_TYPE_3D)
902         return V_008F1C_SQ_RSRC_IMG_3D;
903      else
904         return V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
905   default:
906      unreachable("illegal image type");
907   }
908}
909
910static unsigned
911gfx9_border_color_swizzle(const struct util_format_description *desc)
912{
913   unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
914
915   if (desc->swizzle[3] == PIPE_SWIZZLE_X) {
916      /* For the pre-defined border color values (white, opaque
917       * black, transparent black), the only thing that matters is
918       * that the alpha channel winds up in the correct place
919       * (because the RGB channels are all the same) so either of
920       * these enumerations will work.
921       */
922      if (desc->swizzle[2] == PIPE_SWIZZLE_Y)
923         bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
924      else
925         bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
926   } else if (desc->swizzle[0] == PIPE_SWIZZLE_X) {
927      if (desc->swizzle[1] == PIPE_SWIZZLE_Y)
928         bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
929      else
930         bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
931   } else if (desc->swizzle[1] == PIPE_SWIZZLE_X) {
932      bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
933   } else if (desc->swizzle[2] == PIPE_SWIZZLE_X) {
934      bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
935   }
936
937   return bc_swizzle;
938}
939
940bool
941vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
942{
943   const struct util_format_description *desc = vk_format_description(format);
944
945   if (device->physical_device->rad_info.gfx_level >= GFX10 && desc->nr_channels == 1)
946      return desc->swizzle[3] == PIPE_SWIZZLE_X;
947
948   return radv_translate_colorswap(format, false) <= 1;
949}
950/**
951 * Build the sampler view descriptor for a texture (GFX10).
952 */
953static void
954gfx10_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
955                              bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
956                              const VkComponentMapping *mapping, unsigned first_level,
957                              unsigned last_level, unsigned first_layer, unsigned last_layer,
958                              unsigned width, unsigned height, unsigned depth, float min_lod,
959                              uint32_t *state, uint32_t *fmask_state,
960                              VkImageCreateFlags img_create_flags)
961{
962   const struct util_format_description *desc;
963   enum pipe_swizzle swizzle[4];
964   unsigned img_format;
965   unsigned type;
966
967   desc = vk_format_description(vk_format);
968
969   /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
970    * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format,
971    * this uses the Gallium formats to set the description. */
972   if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK &&
973       vk_format == VK_FORMAT_R8G8B8A8_UNORM) {
974      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM);
975   } else if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK &&
976              vk_format == VK_FORMAT_R8G8B8A8_SRGB) {
977      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB);
978   }
979
980   img_format = ac_get_gfx10_format_table(&device->physical_device->rad_info)[vk_format_to_pipe_format(vk_format)].img_format;
981
982   radv_compose_swizzle(desc, mapping, swizzle);
983
984   if (img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) {
985      assert(image->vk.image_type == VK_IMAGE_TYPE_3D);
986      type = V_008F1C_SQ_RSRC_IMG_3D;
987   } else {
988      type = radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, image->info.samples,
989                          is_storage_image, device->physical_device->rad_info.gfx_level == GFX9);
990   }
991
992   if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
993      height = 1;
994      depth = image->info.array_size;
995   } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
996      if (view_type != VK_IMAGE_VIEW_TYPE_3D)
997         depth = image->info.array_size;
998   } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
999      depth = image->info.array_size / 6;
1000
1001   state[0] = 0;
1002   state[1] = S_00A004_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) |
1003              S_00A004_FORMAT(img_format) |
1004              S_00A004_WIDTH_LO(width - 1);
1005   state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
1006              S_00A008_RESOURCE_LEVEL(device->physical_device->rad_info.gfx_level < GFX11);
1007   state[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
1008              S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
1009              S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
1010              S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
1011              S_00A00C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) |
1012              S_00A00C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples)
1013                                                          : last_level) |
1014              S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(desc)) | S_00A00C_TYPE(type);
1015   /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
1016    * to know the total number of layers.
1017    */
1018   state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) |
1019              S_00A010_BASE_ARRAY(first_layer);
1020   state[5] = S_00A014_ARRAY_PITCH(0) |
1021              S_00A014_PERF_MOD(4);
1022   state[6] = 0;
1023   state[7] = 0;
1024
1025   if (img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) {
1026      assert(type == V_008F1C_SQ_RSRC_IMG_3D);
1027
1028      /* ARRAY_PITCH is only meaningful for 3D images, 0 means SRV, 1 means UAV.
1029       * In SRV mode, BASE_ARRAY is ignored and DEPTH is the last slice of mipmap level 0.
1030       * In UAV mode, BASE_ARRAY is the first slice and DEPTH is the last slice of the bound level.
1031       */
1032      state[4] &= C_00A010_DEPTH;
1033      state[4] |= S_00A010_DEPTH(!is_storage_image ? depth - 1 : u_minify(depth, first_level) - 1);
1034      state[5] |= S_00A014_ARRAY_PITCH(is_storage_image);
1035   }
1036
1037   unsigned max_mip =
1038      image->info.samples > 1 ? util_logbase2(image->info.samples) : image->info.levels - 1;
1039
1040   if (device->physical_device->rad_info.gfx_level >= GFX11) {
1041      state[1] |= S_00A004_MAX_MIP(max_mip);
1042   } else {
1043      state[5] |= S_00A014_MAX_MIP(max_mip);
1044   }
1045
1046   if (radv_dcc_enabled(image, first_level)) {
1047      state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
1048                  S_00A018_MAX_COMPRESSED_BLOCK_SIZE(
1049                     image->planes[0].surface.u.gfx9.color.dcc.max_compressed_block_size) |
1050                  S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
1051   }
1052
1053   if (radv_image_get_iterate256(device, image)) {
1054      state[6] |= S_00A018_ITERATE_256(1);
1055   }
1056
1057   /* Initialize the sampler view for FMASK. */
1058   if (fmask_state) {
1059      if (radv_image_has_fmask(image)) {
1060         uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo);
1061         uint32_t format;
1062         uint64_t va;
1063
1064         assert(image->plane_count == 1);
1065
1066         va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset;
1067
1068         switch (image->info.samples) {
1069         case 2:
1070            format = V_008F0C_GFX10_FORMAT_FMASK8_S2_F2;
1071            break;
1072         case 4:
1073            format = V_008F0C_GFX10_FORMAT_FMASK8_S4_F4;
1074            break;
1075         case 8:
1076            format = V_008F0C_GFX10_FORMAT_FMASK32_S8_F8;
1077            break;
1078         default:
1079            unreachable("invalid nr_samples");
1080         }
1081
1082         fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle;
1083         fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) | S_00A004_FORMAT(format) |
1084                          S_00A004_WIDTH_LO(width - 1);
1085         fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) | S_00A008_HEIGHT(height - 1) |
1086                          S_00A008_RESOURCE_LEVEL(1);
1087         fmask_state[3] =
1088            S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
1089            S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
1090            S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode) |
1091            S_00A00C_TYPE(
1092               radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, 0, false, false));
1093         fmask_state[4] = S_00A010_DEPTH(last_layer) | S_00A010_BASE_ARRAY(first_layer);
1094         fmask_state[5] = 0;
1095         fmask_state[6] = S_00A018_META_PIPE_ALIGNED(1);
1096         fmask_state[7] = 0;
1097
1098         if (radv_image_is_tc_compat_cmask(image)) {
1099            va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset;
1100
1101            fmask_state[6] |= S_00A018_COMPRESSION_EN(1);
1102            fmask_state[6] |= S_00A018_META_DATA_ADDRESS_LO(va >> 8);
1103            fmask_state[7] |= va >> 16;
1104         }
1105      } else
1106         memset(fmask_state, 0, 8 * 4);
1107   }
1108}
1109
1110/**
1111 * Build the sampler view descriptor for a texture (SI-GFX9)
1112 */
1113static void
1114si_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
1115                           bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
1116                           const VkComponentMapping *mapping, unsigned first_level,
1117                           unsigned last_level, unsigned first_layer, unsigned last_layer,
1118                           unsigned width, unsigned height, unsigned depth, float min_lod,
1119                           uint32_t *state, uint32_t *fmask_state,
1120                           VkImageCreateFlags img_create_flags)
1121{
1122   const struct util_format_description *desc;
1123   enum pipe_swizzle swizzle[4];
1124   int first_non_void;
1125   unsigned num_format, data_format, type;
1126
1127   desc = vk_format_description(vk_format);
1128
1129   /* For emulated ETC2 without alpha we need to override the format to a 3-componenent format, so
1130    * that border colors work correctly (alpha forced to 1). Since Vulkan has no such format,
1131    * this uses the Gallium formats to set the description. */
1132   if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_UNORM_BLOCK &&
1133       vk_format == VK_FORMAT_R8G8B8A8_UNORM) {
1134      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_UNORM);
1135   } else if (image->vk.format == VK_FORMAT_ETC2_R8G8B8_SRGB_BLOCK &&
1136              vk_format == VK_FORMAT_R8G8B8A8_SRGB) {
1137      desc = util_format_description(PIPE_FORMAT_R8G8B8X8_SRGB);
1138   }
1139
1140   radv_compose_swizzle(desc, mapping, swizzle);
1141
1142   first_non_void = vk_format_get_first_non_void_channel(vk_format);
1143
1144   num_format = radv_translate_tex_numformat(vk_format, desc, first_non_void);
1145   if (num_format == ~0) {
1146      num_format = 0;
1147   }
1148
1149   data_format = radv_translate_tex_dataformat(vk_format, desc, first_non_void);
1150   if (data_format == ~0) {
1151      data_format = 0;
1152   }
1153
1154   /* S8 with either Z16 or Z32 HTILE need a special format. */
1155   if (device->physical_device->rad_info.gfx_level == GFX9 && vk_format == VK_FORMAT_S8_UINT &&
1156       radv_image_is_tc_compat_htile(image)) {
1157      if (image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT)
1158         data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
1159      else if (image->vk.format == VK_FORMAT_D16_UNORM_S8_UINT)
1160         data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
1161   }
1162
1163   if (device->physical_device->rad_info.gfx_level == GFX9 &&
1164       img_create_flags & VK_IMAGE_CREATE_2D_VIEW_COMPATIBLE_BIT_EXT) {
1165      assert(image->vk.image_type == VK_IMAGE_TYPE_3D);
1166      type = V_008F1C_SQ_RSRC_IMG_3D;
1167   } else {
1168      type = radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, image->info.samples,
1169                          is_storage_image, device->physical_device->rad_info.gfx_level == GFX9);
1170   }
1171
1172   if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
1173      height = 1;
1174      depth = image->info.array_size;
1175   } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY || type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
1176      if (view_type != VK_IMAGE_VIEW_TYPE_3D)
1177         depth = image->info.array_size;
1178   } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
1179      depth = image->info.array_size / 6;
1180
1181   state[0] = 0;
1182   state[1] = (S_008F14_MIN_LOD(radv_float_to_ufixed(CLAMP(min_lod, 0, 15), 8)) |
1183               S_008F14_DATA_FORMAT(data_format) |
1184               S_008F14_NUM_FORMAT(num_format));
1185   state[2] = (S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1) | S_008F18_PERF_MOD(4));
1186   state[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
1187               S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
1188               S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
1189               S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
1190               S_008F1C_BASE_LEVEL(image->info.samples > 1 ? 0 : first_level) |
1191               S_008F1C_LAST_LEVEL(image->info.samples > 1 ? util_logbase2(image->info.samples)
1192                                                           : last_level) |
1193               S_008F1C_TYPE(type));
1194   state[4] = 0;
1195   state[5] = S_008F24_BASE_ARRAY(first_layer);
1196   state[6] = 0;
1197   state[7] = 0;
1198
1199   if (device->physical_device->rad_info.gfx_level == GFX9) {
1200      unsigned bc_swizzle = gfx9_border_color_swizzle(desc);
1201
1202      /* Depth is the last accessible layer on Gfx9.
1203       * The hw doesn't need to know the total number of layers.
1204       */
1205      if (type == V_008F1C_SQ_RSRC_IMG_3D)
1206         state[4] |= S_008F20_DEPTH(depth - 1);
1207      else
1208         state[4] |= S_008F20_DEPTH(last_layer);
1209
1210      state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
1211      state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ? util_logbase2(image->info.samples)
1212                                                           : image->info.levels - 1);
1213   } else {
1214      state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1);
1215      state[4] |= S_008F20_DEPTH(depth - 1);
1216      state[5] |= S_008F24_LAST_ARRAY(last_layer);
1217   }
1218   if (!(image->planes[0].surface.flags & RADEON_SURF_Z_OR_SBUFFER) &&
1219       image->planes[0].surface.meta_offset) {
1220      state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
1221   } else {
1222      if (device->instance->disable_aniso_single_level) {
1223         /* The last dword is unused by hw. The shader uses it to clear
1224          * bits in the first dword of sampler state.
1225          */
1226         if (device->physical_device->rad_info.gfx_level <= GFX7 && image->info.samples <= 1) {
1227            if (first_level == last_level)
1228               state[7] = C_008F30_MAX_ANISO_RATIO;
1229            else
1230               state[7] = 0xffffffff;
1231         }
1232      }
1233   }
1234
1235   /* Initialize the sampler view for FMASK. */
1236   if (fmask_state) {
1237      if (radv_image_has_fmask(image)) {
1238         uint32_t fmask_format;
1239         uint64_t gpu_address = radv_buffer_get_va(image->bindings[0].bo);
1240         uint64_t va;
1241
1242         assert(image->plane_count == 1);
1243
1244         va = gpu_address + image->bindings[0].offset + image->planes[0].surface.fmask_offset;
1245
1246         if (device->physical_device->rad_info.gfx_level == GFX9) {
1247            fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK;
1248            switch (image->info.samples) {
1249            case 2:
1250               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_2_2;
1251               break;
1252            case 4:
1253               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_8_4_4;
1254               break;
1255            case 8:
1256               num_format = V_008F14_IMG_NUM_FORMAT_FMASK_32_8_8;
1257               break;
1258            default:
1259               unreachable("invalid nr_samples");
1260            }
1261         } else {
1262            switch (image->info.samples) {
1263            case 2:
1264               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
1265               break;
1266            case 4:
1267               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
1268               break;
1269            case 8:
1270               fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
1271               break;
1272            default:
1273               assert(0);
1274               fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
1275            }
1276            num_format = V_008F14_IMG_NUM_FORMAT_UINT;
1277         }
1278
1279         fmask_state[0] = va >> 8;
1280         fmask_state[0] |= image->planes[0].surface.fmask_tile_swizzle;
1281         fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) | S_008F14_DATA_FORMAT(fmask_format) |
1282                          S_008F14_NUM_FORMAT(num_format);
1283         fmask_state[2] = S_008F18_WIDTH(width - 1) | S_008F18_HEIGHT(height - 1);
1284         fmask_state[3] =
1285            S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
1286            S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) | S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
1287            S_008F1C_TYPE(
1288               radv_tex_dim(image->vk.image_type, view_type, image->info.array_size, 0, false, false));
1289         fmask_state[4] = 0;
1290         fmask_state[5] = S_008F24_BASE_ARRAY(first_layer);
1291         fmask_state[6] = 0;
1292         fmask_state[7] = 0;
1293
1294         if (device->physical_device->rad_info.gfx_level == GFX9) {
1295            fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.color.fmask_swizzle_mode);
1296            fmask_state[4] |= S_008F20_DEPTH(last_layer) |
1297                              S_008F20_PITCH(image->planes[0].surface.u.gfx9.color.fmask_epitch);
1298            fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(1) | S_008F24_META_RB_ALIGNED(1);
1299
1300            if (radv_image_is_tc_compat_cmask(image)) {
1301               va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset;
1302
1303               fmask_state[5] |= S_008F24_META_DATA_ADDRESS(va >> 40);
1304               fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
1305               fmask_state[7] |= va >> 8;
1306            }
1307         } else {
1308            fmask_state[3] |=
1309               S_008F1C_TILING_INDEX(image->planes[0].surface.u.legacy.color.fmask.tiling_index);
1310            fmask_state[4] |=
1311               S_008F20_DEPTH(depth - 1) |
1312               S_008F20_PITCH(image->planes[0].surface.u.legacy.color.fmask.pitch_in_pixels - 1);
1313            fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer);
1314
1315            if (radv_image_is_tc_compat_cmask(image)) {
1316               va = gpu_address + image->bindings[0].offset + image->planes[0].surface.cmask_offset;
1317
1318               fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
1319               fmask_state[7] |= va >> 8;
1320            }
1321         }
1322      } else
1323         memset(fmask_state, 0, 8 * 4);
1324   }
1325}
1326
1327static void
1328radv_make_texture_descriptor(struct radv_device *device, struct radv_image *image,
1329                             bool is_storage_image, VkImageViewType view_type, VkFormat vk_format,
1330                             const VkComponentMapping *mapping, unsigned first_level,
1331                             unsigned last_level, unsigned first_layer, unsigned last_layer,
1332                             unsigned width, unsigned height, unsigned depth, float min_lod, uint32_t *state,
1333                             uint32_t *fmask_state, VkImageCreateFlags img_create_flags)
1334{
1335   if (device->physical_device->rad_info.gfx_level >= GFX10) {
1336      gfx10_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping,
1337                                    first_level, last_level, first_layer, last_layer, width, height,
1338                                    depth, min_lod, state, fmask_state, img_create_flags);
1339   } else {
1340      si_make_texture_descriptor(device, image, is_storage_image, view_type, vk_format, mapping,
1341                                 first_level, last_level, first_layer, last_layer, width, height,
1342                                 depth, min_lod, state, fmask_state, img_create_flags);
1343   }
1344}
1345
1346static void
1347radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image,
1348                           struct radeon_bo_metadata *md)
1349{
1350   static const VkComponentMapping fixedmapping;
1351   uint32_t desc[8];
1352
1353   assert(image->plane_count == 1);
1354
1355   radv_make_texture_descriptor(device, image, false, (VkImageViewType)image->vk.image_type,
1356                                image->vk.format, &fixedmapping, 0, image->info.levels - 1, 0,
1357                                image->info.array_size - 1, image->info.width, image->info.height,
1358                                image->info.depth, 0.0f, desc, NULL, 0);
1359
1360   si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0,
1361                                  0, image->planes[0].surface.blk_w, false, false, false, false,
1362                                  desc);
1363
1364   ac_surface_get_umd_metadata(&device->physical_device->rad_info, &image->planes[0].surface,
1365                               image->info.levels, desc, &md->size_metadata, md->metadata);
1366}
1367
1368void
1369radv_init_metadata(struct radv_device *device, struct radv_image *image,
1370                   struct radeon_bo_metadata *metadata)
1371{
1372   struct radeon_surf *surface = &image->planes[0].surface;
1373
1374   memset(metadata, 0, sizeof(*metadata));
1375
1376   if (device->physical_device->rad_info.gfx_level >= GFX9) {
1377      uint64_t dcc_offset =
1378         image->bindings[0].offset +
1379         (surface->display_dcc_offset ? surface->display_dcc_offset : surface->meta_offset);
1380      metadata->u.gfx9.swizzle_mode = surface->u.gfx9.swizzle_mode;
1381      metadata->u.gfx9.dcc_offset_256b = dcc_offset >> 8;
1382      metadata->u.gfx9.dcc_pitch_max = surface->u.gfx9.color.display_dcc_pitch_max;
1383      metadata->u.gfx9.dcc_independent_64b_blocks = surface->u.gfx9.color.dcc.independent_64B_blocks;
1384      metadata->u.gfx9.dcc_independent_128b_blocks = surface->u.gfx9.color.dcc.independent_128B_blocks;
1385      metadata->u.gfx9.dcc_max_compressed_block_size =
1386         surface->u.gfx9.color.dcc.max_compressed_block_size;
1387      metadata->u.gfx9.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
1388   } else {
1389      metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D
1390                                        ? RADEON_LAYOUT_TILED
1391                                        : RADEON_LAYOUT_LINEAR;
1392      metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D
1393                                        ? RADEON_LAYOUT_TILED
1394                                        : RADEON_LAYOUT_LINEAR;
1395      metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
1396      metadata->u.legacy.bankw = surface->u.legacy.bankw;
1397      metadata->u.legacy.bankh = surface->u.legacy.bankh;
1398      metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
1399      metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
1400      metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
1401      metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
1402      metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
1403   }
1404   radv_query_opaque_metadata(device, image, metadata);
1405}
1406
1407void
1408radv_image_override_offset_stride(struct radv_device *device, struct radv_image *image,
1409                                  uint64_t offset, uint32_t stride)
1410{
1411   ac_surface_override_offset_stride(&device->physical_device->rad_info, &image->planes[0].surface,
1412                                     image->info.levels, offset, stride);
1413}
1414
1415static void
1416radv_image_alloc_single_sample_cmask(const struct radv_device *device,
1417                                     const struct radv_image *image, struct radeon_surf *surf)
1418{
1419   if (!surf->cmask_size || surf->cmask_offset || surf->bpe > 8 || image->info.levels > 1 ||
1420       image->info.depth > 1 || radv_image_has_dcc(image) ||
1421       !radv_image_use_fast_clear_for_image(device, image) ||
1422       (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT))
1423      return;
1424
1425   assert(image->info.storage_samples == 1);
1426
1427   surf->cmask_offset = align64(surf->total_size, 1 << surf->cmask_alignment_log2);
1428   surf->total_size = surf->cmask_offset + surf->cmask_size;
1429   surf->alignment_log2 = MAX2(surf->alignment_log2, surf->cmask_alignment_log2);
1430}
1431
1432static void
1433radv_image_alloc_values(const struct radv_device *device, struct radv_image *image)
1434{
1435   /* images with modifiers can be potentially imported */
1436   if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
1437      return;
1438
1439   if (radv_image_has_cmask(image) || (radv_image_has_dcc(image) && !image->support_comp_to_single)) {
1440      image->fce_pred_offset = image->size;
1441      image->size += 8 * image->info.levels;
1442   }
1443
1444   if (radv_image_use_dcc_predication(device, image)) {
1445      image->dcc_pred_offset = image->size;
1446      image->size += 8 * image->info.levels;
1447   }
1448
1449   if ((radv_image_has_dcc(image) && !image->support_comp_to_single) ||
1450       radv_image_has_cmask(image) || radv_image_has_htile(image)) {
1451      image->clear_value_offset = image->size;
1452      image->size += 8 * image->info.levels;
1453   }
1454
1455   if (radv_image_is_tc_compat_htile(image) &&
1456       device->physical_device->rad_info.has_tc_compat_zrange_bug) {
1457      /* Metadata for the TC-compatible HTILE hardware bug which
1458       * have to be fixed by updating ZRANGE_PRECISION when doing
1459       * fast depth clears to 0.0f.
1460       */
1461      image->tc_compat_zrange_offset = image->size;
1462      image->size += image->info.levels * 4;
1463   }
1464}
1465
1466/* Determine if the image is affected by the pipe misaligned metadata issue
1467 * which requires to invalidate L2.
1468 */
1469static bool
1470radv_image_is_pipe_misaligned(const struct radv_device *device, const struct radv_image *image)
1471{
1472   struct radeon_info *rad_info = &device->physical_device->rad_info;
1473   int log2_samples = util_logbase2(image->info.samples);
1474
1475   assert(rad_info->gfx_level >= GFX10);
1476
1477   for (unsigned i = 0; i < image->plane_count; ++i) {
1478      VkFormat fmt = radv_image_get_plane_format(device->physical_device, image, i);
1479      int log2_bpp = util_logbase2(vk_format_get_blocksize(fmt));
1480      int log2_bpp_and_samples;
1481
1482      if (rad_info->gfx_level >= GFX10_3) {
1483         log2_bpp_and_samples = log2_bpp + log2_samples;
1484      } else {
1485         if (vk_format_has_depth(image->vk.format) && image->info.array_size >= 8) {
1486            log2_bpp = 2;
1487         }
1488
1489         log2_bpp_and_samples = MIN2(6, log2_bpp + log2_samples);
1490      }
1491
1492      int num_pipes = G_0098F8_NUM_PIPES(rad_info->gb_addr_config);
1493      int overlap = MAX2(0, log2_bpp_and_samples + num_pipes - 8);
1494
1495      if (vk_format_has_depth(image->vk.format)) {
1496         if (radv_image_is_tc_compat_htile(image) && overlap) {
1497            return true;
1498         }
1499      } else {
1500         int max_compressed_frags = G_0098F8_MAX_COMPRESSED_FRAGS(rad_info->gb_addr_config);
1501         int log2_samples_frag_diff = MAX2(0, log2_samples - max_compressed_frags);
1502         int samples_overlap = MIN2(log2_samples, overlap);
1503
1504         /* TODO: It shouldn't be necessary if the image has DCC but
1505          * not readable by shader.
1506          */
1507         if ((radv_image_has_dcc(image) || radv_image_is_tc_compat_cmask(image)) &&
1508             (samples_overlap > log2_samples_frag_diff)) {
1509            return true;
1510         }
1511      }
1512   }
1513
1514   return false;
1515}
1516
1517static bool
1518radv_image_is_l2_coherent(const struct radv_device *device, const struct radv_image *image)
1519{
1520   if (device->physical_device->rad_info.gfx_level >= GFX10) {
1521      return !device->physical_device->rad_info.tcc_rb_non_coherent &&
1522             !radv_image_is_pipe_misaligned(device, image);
1523   } else if (device->physical_device->rad_info.gfx_level == GFX9) {
1524      if (image->info.samples == 1 &&
1525          (image->vk.usage &
1526           (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
1527          !vk_format_has_stencil(image->vk.format)) {
1528         /* Single-sample color and single-sample depth
1529          * (not stencil) are coherent with shaders on
1530          * GFX9.
1531          */
1532         return true;
1533      }
1534   }
1535
1536   return false;
1537}
1538
1539/**
1540 * Determine if the given image can be fast cleared.
1541 */
1542static bool
1543radv_image_can_fast_clear(const struct radv_device *device, const struct radv_image *image)
1544{
1545   if (device->instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
1546      return false;
1547
1548   if (vk_format_is_color(image->vk.format)) {
1549      if (!radv_image_has_cmask(image) && !radv_image_has_dcc(image))
1550         return false;
1551
1552      /* RB+ doesn't work with CMASK fast clear on Stoney. */
1553      if (!radv_image_has_dcc(image) && device->physical_device->rad_info.family == CHIP_STONEY)
1554         return false;
1555   } else {
1556      if (!radv_image_has_htile(image))
1557         return false;
1558   }
1559
1560   /* Do not fast clears 3D images. */
1561   if (image->vk.image_type == VK_IMAGE_TYPE_3D)
1562      return false;
1563
1564   return true;
1565}
1566
1567/**
1568 * Determine if the given image can be fast cleared using comp-to-single.
1569 */
1570static bool
1571radv_image_use_comp_to_single(const struct radv_device *device, const struct radv_image *image)
1572{
1573   /* comp-to-single is only available for GFX10+. */
1574   if (device->physical_device->rad_info.gfx_level < GFX10)
1575      return false;
1576
1577   /* If the image can't be fast cleared, comp-to-single can't be used. */
1578   if (!radv_image_can_fast_clear(device, image))
1579      return false;
1580
1581   /* If the image doesn't have DCC, it can't be fast cleared using comp-to-single */
1582   if (!radv_image_has_dcc(image))
1583      return false;
1584
1585   /* It seems 8bpp and 16bpp require RB+ to work. */
1586   unsigned bytes_per_pixel = vk_format_get_blocksize(image->vk.format);
1587   if (bytes_per_pixel <= 2 && !device->physical_device->rad_info.rbplus_allowed)
1588      return false;
1589
1590   return true;
1591}
1592
1593static unsigned
1594radv_get_internal_plane_count(const struct radv_physical_device *pdev, VkFormat fmt)
1595{
1596   if (pdev->emulate_etc2 && vk_format_description(fmt)->layout == UTIL_FORMAT_LAYOUT_ETC)
1597      return 2;
1598   return vk_format_get_plane_count(fmt);
1599}
1600
1601static void
1602radv_image_reset_layout(const struct radv_physical_device *pdev, struct radv_image *image)
1603{
1604   image->size = 0;
1605   image->alignment = 1;
1606
1607   image->tc_compatible_cmask = 0;
1608   image->fce_pred_offset = image->dcc_pred_offset = 0;
1609   image->clear_value_offset = image->tc_compat_zrange_offset = 0;
1610
1611   unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk.format);
1612   for (unsigned i = 0; i < plane_count; ++i) {
1613      VkFormat format = radv_image_get_plane_format(pdev, image, i);
1614      if (vk_format_has_depth(format))
1615         format = vk_format_depth_only(format);
1616
1617      uint64_t flags = image->planes[i].surface.flags;
1618      uint64_t modifier = image->planes[i].surface.modifier;
1619      memset(image->planes + i, 0, sizeof(image->planes[i]));
1620
1621      image->planes[i].surface.flags = flags;
1622      image->planes[i].surface.modifier = modifier;
1623      image->planes[i].surface.blk_w = vk_format_get_blockwidth(format);
1624      image->planes[i].surface.blk_h = vk_format_get_blockheight(format);
1625      image->planes[i].surface.bpe = vk_format_get_blocksize(format);
1626
1627      /* align byte per element on dword */
1628      if (image->planes[i].surface.bpe == 3) {
1629         image->planes[i].surface.bpe = 4;
1630      }
1631   }
1632}
1633
1634VkResult
1635radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info,
1636                         const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info,
1637                         struct radv_image *image)
1638{
1639   /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
1640    * common internal case. */
1641   create_info.vk_info = NULL;
1642
1643   struct ac_surf_info image_info = image->info;
1644   VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info);
1645   if (result != VK_SUCCESS)
1646      return result;
1647
1648   assert(!mod_info || mod_info->drmFormatModifierPlaneCount >= image->plane_count);
1649
1650   radv_image_reset_layout(device->physical_device, image);
1651
1652   unsigned plane_count = radv_get_internal_plane_count(device->physical_device, image->vk.format);
1653   for (unsigned plane = 0; plane < plane_count; ++plane) {
1654      struct ac_surf_info info = image_info;
1655      uint64_t offset;
1656      unsigned stride;
1657
1658      info.width = vk_format_get_plane_width(image->vk.format, plane, info.width);
1659      info.height = vk_format_get_plane_height(image->vk.format, plane, info.height);
1660
1661      if (create_info.no_metadata_planes || plane_count > 1) {
1662         image->planes[plane].surface.flags |=
1663            RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE;
1664      }
1665
1666      device->ws->surface_init(device->ws, &info, &image->planes[plane].surface);
1667
1668      if (plane == 0) {
1669         if (!radv_use_dcc_for_image_late(device, image))
1670            ac_surface_zero_dcc_fields(&image->planes[0].surface);
1671      }
1672
1673      if (create_info.bo_metadata && !mod_info &&
1674          !ac_surface_set_umd_metadata(&device->physical_device->rad_info,
1675                                       &image->planes[plane].surface, image_info.storage_samples,
1676                                       image_info.levels, create_info.bo_metadata->size_metadata,
1677                                       create_info.bo_metadata->metadata))
1678         return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1679
1680      if (!create_info.no_metadata_planes && !create_info.bo_metadata && plane_count == 1 &&
1681          !mod_info)
1682         radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface);
1683
1684      if (mod_info) {
1685         if (mod_info->pPlaneLayouts[plane].rowPitch % image->planes[plane].surface.bpe ||
1686             !mod_info->pPlaneLayouts[plane].rowPitch)
1687            return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1688
1689         offset = mod_info->pPlaneLayouts[plane].offset;
1690         stride = mod_info->pPlaneLayouts[plane].rowPitch / image->planes[plane].surface.bpe;
1691      } else {
1692         offset = image->disjoint ? 0 :
1693            align64(image->size, 1 << image->planes[plane].surface.alignment_log2);
1694         stride = 0; /* 0 means no override */
1695      }
1696
1697      if (!ac_surface_override_offset_stride(&device->physical_device->rad_info,
1698                                             &image->planes[plane].surface, image->info.levels,
1699                                             offset, stride))
1700         return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1701
1702      /* Validate DCC offsets in modifier layout. */
1703      if (plane_count == 1 && mod_info) {
1704         unsigned mem_planes = ac_surface_get_nplanes(&image->planes[plane].surface);
1705         if (mod_info->drmFormatModifierPlaneCount != mem_planes)
1706            return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1707
1708         for (unsigned i = 1; i < mem_planes; ++i) {
1709            if (ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level,
1710                                            &image->planes[plane].surface, i,
1711                                            0) != mod_info->pPlaneLayouts[i].offset)
1712               return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1713         }
1714      }
1715
1716      image->size = MAX2(image->size, offset + image->planes[plane].surface.total_size);
1717      image->alignment = MAX2(image->alignment, 1 << image->planes[plane].surface.alignment_log2);
1718
1719      image->planes[plane].format =
1720         radv_image_get_plane_format(device->physical_device, image, plane);
1721   }
1722
1723   image->tc_compatible_cmask =
1724      radv_image_has_cmask(image) && radv_use_tc_compat_cmask_for_image(device, image);
1725
1726   image->l2_coherent = radv_image_is_l2_coherent(device, image);
1727
1728   image->support_comp_to_single = radv_image_use_comp_to_single(device, image);
1729
1730   radv_image_alloc_values(device, image);
1731
1732   assert(image->planes[0].surface.surf_size);
1733   assert(image->planes[0].surface.modifier == DRM_FORMAT_MOD_INVALID ||
1734          ac_modifier_has_dcc(image->planes[0].surface.modifier) == radv_image_has_dcc(image));
1735   return VK_SUCCESS;
1736}
1737
1738static void
1739radv_destroy_image(struct radv_device *device, const VkAllocationCallbacks *pAllocator,
1740                   struct radv_image *image)
1741{
1742   if ((image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bindings[0].bo)
1743      device->ws->buffer_destroy(device->ws, image->bindings[0].bo);
1744
1745   if (image->owned_memory != VK_NULL_HANDLE) {
1746      RADV_FROM_HANDLE(radv_device_memory, mem, image->owned_memory);
1747      radv_free_memory(device, pAllocator, mem);
1748   }
1749
1750   vk_image_finish(&image->vk);
1751   vk_free2(&device->vk.alloc, pAllocator, image);
1752}
1753
1754static void
1755radv_image_print_info(struct radv_device *device, struct radv_image *image)
1756{
1757   fprintf(stderr, "Image:\n");
1758   fprintf(stderr,
1759           "  Info: size=%" PRIu64 ", alignment=%" PRIu32 ", "
1760           "width=%" PRIu32 ", height=%" PRIu32 ", "
1761           "array_size=%" PRIu32 ", levels=%" PRIu32 "\n",
1762           image->size, image->alignment, image->info.width, image->info.height,
1763           image->info.array_size, image->info.levels);
1764   for (unsigned i = 0; i < image->plane_count; ++i) {
1765      const struct radv_image_plane *plane = &image->planes[i];
1766      const struct radeon_surf *surf = &plane->surface;
1767      const struct util_format_description *desc = vk_format_description(plane->format);
1768      uint64_t offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level,
1769                                                    &plane->surface, 0, 0);
1770
1771      fprintf(stderr, "  Plane[%u]: vkformat=%s, offset=%" PRIu64 "\n", i, desc->name, offset);
1772
1773      ac_surface_print_info(stderr, &device->physical_device->rad_info, surf);
1774   }
1775}
1776
1777static uint64_t
1778radv_select_modifier(const struct radv_device *dev, VkFormat format,
1779                     const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list)
1780{
1781   const struct radv_physical_device *pdev = dev->physical_device;
1782   unsigned mod_count;
1783
1784   assert(mod_list->drmFormatModifierCount);
1785
1786   /* We can allow everything here as it does not affect order and the application
1787    * is only allowed to specify modifiers that we support. */
1788   const struct ac_modifier_options modifier_options = {
1789      .dcc = true,
1790      .dcc_retile = true,
1791   };
1792
1793   ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format),
1794                              &mod_count, NULL);
1795
1796   uint64_t *mods = calloc(mod_count, sizeof(*mods));
1797
1798   /* If allocations fail, fall back to a dumber solution. */
1799   if (!mods)
1800      return mod_list->pDrmFormatModifiers[0];
1801
1802   ac_get_supported_modifiers(&pdev->rad_info, &modifier_options, vk_format_to_pipe_format(format),
1803                              &mod_count, mods);
1804
1805   for (unsigned i = 0; i < mod_count; ++i) {
1806      for (uint32_t j = 0; j < mod_list->drmFormatModifierCount; ++j) {
1807         if (mods[i] == mod_list->pDrmFormatModifiers[j]) {
1808            free(mods);
1809            return mod_list->pDrmFormatModifiers[j];
1810         }
1811      }
1812   }
1813   unreachable("App specified an invalid modifier");
1814}
1815
1816VkResult
1817radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info,
1818                  const VkAllocationCallbacks *alloc, VkImage *pImage)
1819{
1820   RADV_FROM_HANDLE(radv_device, device, _device);
1821   const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
1822   uint64_t modifier = DRM_FORMAT_MOD_INVALID;
1823   struct radv_image *image = NULL;
1824   VkFormat format = radv_select_android_external_format(pCreateInfo->pNext, pCreateInfo->format);
1825   const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
1826      vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
1827   const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
1828      vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
1829   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
1830
1831   unsigned plane_count = radv_get_internal_plane_count(device->physical_device, format);
1832
1833   const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
1834
1835   radv_assert(pCreateInfo->mipLevels > 0);
1836   radv_assert(pCreateInfo->arrayLayers > 0);
1837   radv_assert(pCreateInfo->samples > 0);
1838   radv_assert(pCreateInfo->extent.width > 0);
1839   radv_assert(pCreateInfo->extent.height > 0);
1840   radv_assert(pCreateInfo->extent.depth > 0);
1841
1842   image =
1843      vk_zalloc2(&device->vk.alloc, alloc, image_struct_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1844   if (!image)
1845      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1846
1847   vk_image_init(&device->vk, &image->vk, pCreateInfo);
1848
1849   image->info.width = pCreateInfo->extent.width;
1850   image->info.height = pCreateInfo->extent.height;
1851   image->info.depth = pCreateInfo->extent.depth;
1852   image->info.samples = pCreateInfo->samples;
1853   image->info.storage_samples = pCreateInfo->samples;
1854   image->info.array_size = pCreateInfo->arrayLayers;
1855   image->info.levels = pCreateInfo->mipLevels;
1856   image->info.num_channels = vk_format_get_nr_components(format);
1857
1858   image->plane_count = vk_format_get_plane_count(format);
1859   image->disjoint = image->plane_count > 1 && pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
1860
1861   image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
1862   if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
1863      for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
1864         if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL ||
1865             pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT)
1866            image->queue_family_mask |= (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
1867         else
1868            image->queue_family_mask |= 1u << vk_queue_to_radv(device->physical_device,
1869                                                               pCreateInfo->pQueueFamilyIndices[i]);
1870   }
1871
1872   const VkExternalMemoryImageCreateInfo *external_info =
1873      vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
1874
1875   image->shareable = external_info;
1876   if (!vk_format_is_depth_or_stencil(format) && !image->shareable &&
1877       !(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_ALIASED_BIT) &&
1878       pCreateInfo->tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1879      image->info.surf_index = &device->image_mrt_offset_counter;
1880   }
1881
1882   if (mod_list)
1883      modifier = radv_select_modifier(device, format, mod_list);
1884   else if (explicit_mod)
1885      modifier = explicit_mod->drmFormatModifier;
1886
1887   for (unsigned plane = 0; plane < plane_count; ++plane) {
1888      image->planes[plane].surface.flags =
1889         radv_get_surface_flags(device, image, plane, pCreateInfo, format);
1890      image->planes[plane].surface.modifier = modifier;
1891   }
1892
1893   bool delay_layout =
1894      external_info && (external_info->handleTypes &
1895                        VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID);
1896
1897   if (delay_layout) {
1898      *pImage = radv_image_to_handle(image);
1899      assert(!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT));
1900      return VK_SUCCESS;
1901   }
1902
1903   VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, image);
1904   if (result != VK_SUCCESS) {
1905      radv_destroy_image(device, alloc, image);
1906      return result;
1907   }
1908
1909   if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1910      image->alignment = MAX2(image->alignment, 4096);
1911      image->size = align64(image->size, image->alignment);
1912      image->bindings[0].offset = 0;
1913
1914      result =
1915         device->ws->buffer_create(device->ws, image->size, image->alignment, 0,
1916                                   RADEON_FLAG_VIRTUAL, RADV_BO_PRIORITY_VIRTUAL, 0,
1917                                   &image->bindings[0].bo);
1918      if (result != VK_SUCCESS) {
1919         radv_destroy_image(device, alloc, image);
1920         return vk_error(device, result);
1921      }
1922   }
1923
1924   if (device->instance->debug_flags & RADV_DEBUG_IMG) {
1925      radv_image_print_info(device, image);
1926   }
1927
1928   *pImage = radv_image_to_handle(image);
1929
1930   return VK_SUCCESS;
1931}
1932
1933static void
1934radv_image_view_make_descriptor(struct radv_image_view *iview, struct radv_device *device,
1935                                VkFormat vk_format, const VkComponentMapping *components,
1936                                float min_lod,
1937                                bool is_storage_image, bool disable_compression,
1938                                bool enable_compression, unsigned plane_id,
1939                                unsigned descriptor_plane_id, VkImageCreateFlags img_create_flags)
1940{
1941   struct radv_image *image = iview->image;
1942   struct radv_image_plane *plane = &image->planes[plane_id];
1943   bool is_stencil = iview->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT;
1944   uint32_t blk_w;
1945   union radv_descriptor *descriptor;
1946   uint32_t hw_level = 0;
1947
1948   if (is_storage_image) {
1949      descriptor = &iview->storage_descriptor;
1950   } else {
1951      descriptor = &iview->descriptor;
1952   }
1953
1954   assert(vk_format_get_plane_count(vk_format) == 1);
1955   assert(plane->surface.blk_w % vk_format_get_blockwidth(plane->format) == 0);
1956   blk_w = plane->surface.blk_w / vk_format_get_blockwidth(plane->format) *
1957           vk_format_get_blockwidth(vk_format);
1958
1959   if (device->physical_device->rad_info.gfx_level >= GFX9)
1960      hw_level = iview->vk.base_mip_level;
1961   radv_make_texture_descriptor(
1962      device, image, is_storage_image, iview->vk.view_type, vk_format, components, hw_level,
1963      hw_level + iview->vk.level_count - 1, iview->vk.base_array_layer,
1964      iview->vk.base_array_layer + iview->vk.layer_count - 1,
1965      vk_format_get_plane_width(image->vk.format, plane_id, iview->extent.width),
1966      vk_format_get_plane_height(image->vk.format, plane_id, iview->extent.height),
1967      iview->extent.depth, min_lod, descriptor->plane_descriptors[descriptor_plane_id],
1968      descriptor_plane_id || is_storage_image ? NULL : descriptor->fmask_descriptor,
1969      img_create_flags);
1970
1971   const struct legacy_surf_level *base_level_info = NULL;
1972   if (device->physical_device->rad_info.gfx_level <= GFX9) {
1973      if (is_stencil)
1974         base_level_info = &plane->surface.u.legacy.zs.stencil_level[iview->vk.base_mip_level];
1975      else
1976         base_level_info = &plane->surface.u.legacy.level[iview->vk.base_mip_level];
1977   }
1978
1979   bool enable_write_compression = radv_image_use_dcc_image_stores(device, image);
1980   if (is_storage_image && !(enable_write_compression || enable_compression))
1981      disable_compression = true;
1982   si_set_mutable_tex_desc_fields(device, image, base_level_info, plane_id, iview->vk.base_mip_level,
1983                                  iview->vk.base_mip_level, blk_w, is_stencil, is_storage_image,
1984                                  disable_compression, enable_write_compression,
1985                                  descriptor->plane_descriptors[descriptor_plane_id]);
1986}
1987
1988static unsigned
1989radv_plane_from_aspect(VkImageAspectFlags mask)
1990{
1991   switch (mask) {
1992   case VK_IMAGE_ASPECT_PLANE_1_BIT:
1993   case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
1994      return 1;
1995   case VK_IMAGE_ASPECT_PLANE_2_BIT:
1996   case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
1997      return 2;
1998   case VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT:
1999      return 3;
2000   default:
2001      return 0;
2002   }
2003}
2004
2005VkFormat
2006radv_get_aspect_format(struct radv_image *image, VkImageAspectFlags mask)
2007{
2008   switch (mask) {
2009   case VK_IMAGE_ASPECT_PLANE_0_BIT:
2010      return image->planes[0].format;
2011   case VK_IMAGE_ASPECT_PLANE_1_BIT:
2012      return image->planes[1].format;
2013   case VK_IMAGE_ASPECT_PLANE_2_BIT:
2014      return image->planes[2].format;
2015   case VK_IMAGE_ASPECT_STENCIL_BIT:
2016      return vk_format_stencil_only(image->vk.format);
2017   case VK_IMAGE_ASPECT_DEPTH_BIT:
2018      return vk_format_depth_only(image->vk.format);
2019   case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
2020      return vk_format_depth_only(image->vk.format);
2021   default:
2022      return image->vk.format;
2023   }
2024}
2025
2026/**
2027 * Determine if the given image view can be fast cleared.
2028 */
2029static bool
2030radv_image_view_can_fast_clear(const struct radv_device *device,
2031                               const struct radv_image_view *iview)
2032{
2033   struct radv_image *image;
2034
2035   if (!iview)
2036      return false;
2037   image = iview->image;
2038
2039   /* Only fast clear if the image itself can be fast cleared. */
2040   if (!radv_image_can_fast_clear(device, image))
2041      return false;
2042
2043   /* Only fast clear if all layers are bound. */
2044   if (iview->vk.base_array_layer > 0 || iview->vk.layer_count != image->info.array_size)
2045      return false;
2046
2047   /* Only fast clear if the view covers the whole image. */
2048   if (!radv_image_extent_compare(image, &iview->extent))
2049      return false;
2050
2051   return true;
2052}
2053
2054void
2055radv_image_view_init(struct radv_image_view *iview, struct radv_device *device,
2056                     const VkImageViewCreateInfo *pCreateInfo,
2057                     VkImageCreateFlags img_create_flags,
2058                     const struct radv_image_view_extra_create_info *extra_create_info)
2059{
2060   RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
2061   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
2062   uint32_t plane_count = 1;
2063   float min_lod = 0.0f;
2064
2065   const struct VkImageViewMinLodCreateInfoEXT *min_lod_info =
2066      vk_find_struct_const(pCreateInfo->pNext, IMAGE_VIEW_MIN_LOD_CREATE_INFO_EXT);
2067
2068   if (min_lod_info)
2069      min_lod = min_lod_info->minLod;
2070
2071   bool from_client = extra_create_info && extra_create_info->from_client;
2072   vk_image_view_init(&device->vk, &iview->vk, !from_client, pCreateInfo);
2073
2074   switch (image->vk.image_type) {
2075   case VK_IMAGE_TYPE_1D:
2076   case VK_IMAGE_TYPE_2D:
2077      assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <=
2078             image->info.array_size);
2079      break;
2080   case VK_IMAGE_TYPE_3D:
2081      assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <=
2082             radv_minify(image->info.depth, range->baseMipLevel));
2083      break;
2084   default:
2085      unreachable("bad VkImageType");
2086   }
2087   iview->image = image;
2088   iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
2089
2090   /* If the image has an Android external format, pCreateInfo->format will be
2091    * VK_FORMAT_UNDEFINED. */
2092   if (iview->vk.format == VK_FORMAT_UNDEFINED) {
2093      iview->vk.format = image->vk.format;
2094      iview->vk.view_format = image->vk.format;
2095   }
2096
2097   /* Split out the right aspect. Note that for internal meta code we sometimes
2098    * use an equivalent color format for the aspect so we first have to check
2099    * if we actually got depth/stencil formats. */
2100   if (iview->vk.aspects == VK_IMAGE_ASPECT_STENCIL_BIT) {
2101      if (vk_format_has_stencil(iview->vk.view_format))
2102         iview->vk.view_format = vk_format_stencil_only(iview->vk.view_format);
2103   } else if (iview->vk.aspects == VK_IMAGE_ASPECT_DEPTH_BIT) {
2104      if (vk_format_has_depth(iview->vk.view_format))
2105         iview->vk.view_format = vk_format_depth_only(iview->vk.view_format);
2106   }
2107
2108   if (vk_format_get_plane_count(image->vk.format) > 1 &&
2109       pCreateInfo->subresourceRange.aspectMask == VK_IMAGE_ASPECT_COLOR_BIT) {
2110      plane_count = vk_format_get_plane_count(iview->vk.format);
2111   }
2112
2113   if (device->physical_device->emulate_etc2 &&
2114       vk_format_description(image->vk.format)->layout == UTIL_FORMAT_LAYOUT_ETC) {
2115      const struct util_format_description *desc = vk_format_description(iview->vk.format);
2116      if (desc->layout == UTIL_FORMAT_LAYOUT_ETC) {
2117         iview->plane_id = 1;
2118         iview->vk.format = etc2_emulation_format(iview->vk.format);
2119         iview->vk.view_format = etc2_emulation_format(iview->vk.format);
2120      }
2121
2122      plane_count = 1;
2123   }
2124
2125   if (device->physical_device->rad_info.gfx_level >= GFX9) {
2126      iview->extent = (VkExtent3D){
2127         .width = image->info.width,
2128         .height = image->info.height,
2129         .depth = image->info.depth,
2130      };
2131   } else {
2132      iview->extent = iview->vk.extent;
2133   }
2134
2135   if (iview->vk.format != image->planes[iview->plane_id].format) {
2136      unsigned view_bw = vk_format_get_blockwidth(iview->vk.format);
2137      unsigned view_bh = vk_format_get_blockheight(iview->vk.format);
2138      unsigned img_bw = vk_format_get_blockwidth(image->planes[iview->plane_id].format);
2139      unsigned img_bh = vk_format_get_blockheight(image->planes[iview->plane_id].format);
2140
2141      iview->extent.width = round_up_u32(iview->extent.width * view_bw, img_bw);
2142      iview->extent.height = round_up_u32(iview->extent.height * view_bh, img_bh);
2143
2144      /* Comment ported from amdvlk -
2145       * If we have the following image:
2146       *              Uncompressed pixels   Compressed block sizes (4x4)
2147       *      mip0:       22 x 22                   6 x 6
2148       *      mip1:       11 x 11                   3 x 3
2149       *      mip2:        5 x  5                   2 x 2
2150       *      mip3:        2 x  2                   1 x 1
2151       *      mip4:        1 x  1                   1 x 1
2152       *
2153       * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and
2154       * the HW is calculating the degradation of the block sizes down the mip-chain as follows
2155       * (straight-up divide-by-two integer math): mip0:  6x6 mip1:  3x3 mip2:  1x1 mip3:  1x1
2156       *
2157       * This means that mip2 will be missing texels.
2158       *
2159       * Fix this by calculating the base mip's width and height, then convert
2160       * that, and round it back up to get the level 0 size. Clamp the
2161       * converted size between the original values, and the physical extent
2162       * of the base mipmap.
2163       *
2164       * On GFX10 we have to take care to not go over the physical extent
2165       * of the base mipmap as otherwise the GPU computes a different layout.
2166       * Note that the GPU does use the same base-mip dimensions for both a
2167       * block compatible format and the compressed format, so even if we take
2168       * the plain converted dimensions the physical layout is correct.
2169       */
2170      if (device->physical_device->rad_info.gfx_level >= GFX9 &&
2171          vk_format_is_compressed(image->vk.format) && !vk_format_is_compressed(iview->vk.format)) {
2172         /* If we have multiple levels in the view we should ideally take the last level,
2173          * but the mip calculation has a max(..., 1) so walking back to the base mip in an
2174          * useful way is hard. */
2175         if (iview->vk.level_count > 1) {
2176            iview->extent.width = iview->image->planes[0].surface.u.gfx9.base_mip_width;
2177            iview->extent.height = iview->image->planes[0].surface.u.gfx9.base_mip_height;
2178         } else {
2179            unsigned lvl_width = radv_minify(image->info.width, range->baseMipLevel);
2180            unsigned lvl_height = radv_minify(image->info.height, range->baseMipLevel);
2181
2182            lvl_width = round_up_u32(lvl_width * view_bw, img_bw);
2183            lvl_height = round_up_u32(lvl_height * view_bh, img_bh);
2184
2185            lvl_width <<= range->baseMipLevel;
2186            lvl_height <<= range->baseMipLevel;
2187
2188            iview->extent.width = CLAMP(lvl_width, iview->extent.width,
2189                                        iview->image->planes[0].surface.u.gfx9.base_mip_width);
2190            iview->extent.height = CLAMP(lvl_height, iview->extent.height,
2191                                         iview->image->planes[0].surface.u.gfx9.base_mip_height);
2192         }
2193      }
2194   }
2195
2196   iview->support_fast_clear = radv_image_view_can_fast_clear(device, iview);
2197   iview->disable_dcc_mrt = extra_create_info ? extra_create_info->disable_dcc_mrt : false;
2198
2199   bool disable_compression = extra_create_info ? extra_create_info->disable_compression : false;
2200   bool enable_compression = extra_create_info ? extra_create_info->enable_compression : false;
2201   for (unsigned i = 0; i < plane_count; ++i) {
2202      VkFormat format = vk_format_get_plane_format(iview->vk.view_format, i);
2203      radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, false,
2204                                      disable_compression, enable_compression, iview->plane_id + i,
2205                                      i, img_create_flags);
2206      radv_image_view_make_descriptor(iview, device, format, &pCreateInfo->components, min_lod, true,
2207                                      disable_compression, enable_compression, iview->plane_id + i,
2208                                      i, img_create_flags);
2209   }
2210}
2211
2212void
2213radv_image_view_finish(struct radv_image_view *iview)
2214{
2215   vk_image_view_finish(&iview->vk);
2216}
2217
2218bool
2219radv_layout_is_htile_compressed(const struct radv_device *device, const struct radv_image *image,
2220                                VkImageLayout layout, bool in_render_loop, unsigned queue_mask)
2221{
2222   switch (layout) {
2223   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
2224   case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
2225   case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:
2226   case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
2227      return radv_image_has_htile(image);
2228   case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
2229      return radv_image_is_tc_compat_htile(image) ||
2230             (radv_image_has_htile(image) && queue_mask == (1u << RADV_QUEUE_GENERAL));
2231   case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
2232   case VK_IMAGE_LAYOUT_GENERAL:
2233      /* It should be safe to enable TC-compat HTILE with
2234       * VK_IMAGE_LAYOUT_GENERAL if we are not in a render loop and
2235       * if the image doesn't have the storage bit set. This
2236       * improves performance for apps that use GENERAL for the main
2237       * depth pass because this allows compression and this reduces
2238       * the number of decompressions from/to GENERAL.
2239       */
2240      /* FIXME: Enabling TC-compat HTILE in GENERAL on the compute
2241       * queue is likely broken for eg. depth/stencil copies.
2242       */
2243      if (radv_image_is_tc_compat_htile(image) && queue_mask & (1u << RADV_QUEUE_GENERAL) &&
2244          !in_render_loop && !device->instance->disable_tc_compat_htile_in_general) {
2245         return true;
2246      } else {
2247         return false;
2248      }
2249   case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
2250      /* Do not compress HTILE with feedback loops because we can't read&write it without
2251       * introducing corruption.
2252       */
2253      return false;
2254   case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
2255      if (radv_image_is_tc_compat_htile(image) ||
2256          (radv_image_has_htile(image) &&
2257           !(image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
2258                                VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))) {
2259         /* Keep HTILE compressed if the image is only going to
2260          * be used as a depth/stencil read-only attachment.
2261          */
2262         return true;
2263      } else {
2264         return false;
2265      }
2266      break;
2267   default:
2268      return radv_image_is_tc_compat_htile(image);
2269   }
2270}
2271
2272bool
2273radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image,
2274                           unsigned level, VkImageLayout layout, bool in_render_loop,
2275                           unsigned queue_mask)
2276{
2277   if (radv_dcc_enabled(image, level) &&
2278       !radv_layout_dcc_compressed(device, image, level, layout, in_render_loop, queue_mask))
2279      return false;
2280
2281   if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS))
2282      return false;
2283
2284   if (layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
2285       layout != VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL)
2286      return false;
2287
2288   /* Exclusive images with CMASK or DCC can always be fast-cleared on the gfx queue. Concurrent
2289    * images can only be fast-cleared if comp-to-single is supported because we don't yet support
2290    * FCE on the compute queue.
2291    */
2292   return queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_use_comp_to_single(device, image);
2293}
2294
2295bool
2296radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image,
2297                           unsigned level, VkImageLayout layout, bool in_render_loop,
2298                           unsigned queue_mask)
2299{
2300   if (!radv_dcc_enabled(image, level))
2301      return false;
2302
2303   if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT &&
2304       queue_mask & (1u << RADV_QUEUE_FOREIGN))
2305      return true;
2306
2307   /* If the image is read-only, we can always just keep it compressed */
2308   if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS))
2309      return true;
2310
2311   /* Don't compress compute transfer dst when image stores are not supported. */
2312   if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) &&
2313       (queue_mask & (1u << RADV_QUEUE_COMPUTE)) && !radv_image_use_dcc_image_stores(device, image))
2314      return false;
2315
2316   if (layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT) {
2317      /* Do not compress DCC with feedback loops because we can't read&write it without introducing
2318       * corruption.
2319       */
2320      return false;
2321   }
2322
2323   return device->physical_device->rad_info.gfx_level >= GFX10 || layout != VK_IMAGE_LAYOUT_GENERAL;
2324}
2325
2326bool
2327radv_layout_fmask_compressed(const struct radv_device *device, const struct radv_image *image,
2328                             VkImageLayout layout, unsigned queue_mask)
2329{
2330   if (!radv_image_has_fmask(image))
2331      return false;
2332
2333   /* Don't compress compute transfer dst because image stores ignore FMASK and it needs to be
2334    * expanded before.
2335    */
2336   if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) &&
2337       (queue_mask & (1u << RADV_QUEUE_COMPUTE)))
2338      return false;
2339
2340   /* Only compress concurrent images if TC-compat CMASK is enabled (no FMASK decompression). */
2341   return layout != VK_IMAGE_LAYOUT_GENERAL &&
2342          (queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_is_tc_compat_cmask(image));
2343}
2344
2345unsigned
2346radv_image_queue_family_mask(const struct radv_image *image,
2347                             enum radv_queue_family family,
2348                             enum radv_queue_family queue_family)
2349{
2350   if (!image->exclusive)
2351      return image->queue_family_mask;
2352   if (family == RADV_QUEUE_FOREIGN)
2353      return ((1u << RADV_MAX_QUEUE_FAMILIES) - 1u) | (1u << RADV_QUEUE_FOREIGN);
2354   if (family == RADV_QUEUE_IGNORED)
2355      return 1u << queue_family;
2356   return 1u << family;
2357}
2358
2359VKAPI_ATTR VkResult VKAPI_CALL
2360radv_CreateImage(VkDevice device, const VkImageCreateInfo *pCreateInfo,
2361                 const VkAllocationCallbacks *pAllocator, VkImage *pImage)
2362{
2363#ifdef ANDROID
2364   const VkNativeBufferANDROID *gralloc_info =
2365      vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
2366
2367   if (gralloc_info)
2368      return radv_image_from_gralloc(device, pCreateInfo, gralloc_info, pAllocator, pImage);
2369#endif
2370
2371   const struct wsi_image_create_info *wsi_info =
2372      vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
2373   bool scanout = wsi_info && wsi_info->scanout;
2374   bool prime_blit_src = wsi_info && wsi_info->buffer_blit_src;
2375
2376   return radv_image_create(device,
2377                            &(struct radv_image_create_info){
2378                               .vk_info = pCreateInfo,
2379                               .scanout = scanout,
2380                               .prime_blit_src = prime_blit_src,
2381                            },
2382                            pAllocator, pImage);
2383}
2384
2385VKAPI_ATTR void VKAPI_CALL
2386radv_DestroyImage(VkDevice _device, VkImage _image, const VkAllocationCallbacks *pAllocator)
2387{
2388   RADV_FROM_HANDLE(radv_device, device, _device);
2389   RADV_FROM_HANDLE(radv_image, image, _image);
2390
2391   if (!image)
2392      return;
2393
2394   radv_destroy_image(device, pAllocator, image);
2395}
2396
2397VKAPI_ATTR void VKAPI_CALL
2398radv_GetImageSubresourceLayout(VkDevice _device, VkImage _image,
2399                               const VkImageSubresource *pSubresource, VkSubresourceLayout *pLayout)
2400{
2401   RADV_FROM_HANDLE(radv_image, image, _image);
2402   RADV_FROM_HANDLE(radv_device, device, _device);
2403   int level = pSubresource->mipLevel;
2404   int layer = pSubresource->arrayLayer;
2405
2406   unsigned plane_id = 0;
2407   if (vk_format_get_plane_count(image->vk.format) > 1)
2408      plane_id = radv_plane_from_aspect(pSubresource->aspectMask);
2409
2410   struct radv_image_plane *plane = &image->planes[plane_id];
2411   struct radeon_surf *surface = &plane->surface;
2412
2413   if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
2414      unsigned mem_plane_id = radv_plane_from_aspect(pSubresource->aspectMask);
2415
2416      assert(level == 0);
2417      assert(layer == 0);
2418
2419      pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level,
2420                                                    surface, mem_plane_id, 0);
2421      pLayout->rowPitch = ac_surface_get_plane_stride(device->physical_device->rad_info.gfx_level,
2422                                                      surface, mem_plane_id, level);
2423      pLayout->arrayPitch = 0;
2424      pLayout->depthPitch = 0;
2425      pLayout->size = ac_surface_get_plane_size(surface, mem_plane_id);
2426   } else if (device->physical_device->rad_info.gfx_level >= GFX9) {
2427      uint64_t level_offset = surface->is_linear ? surface->u.gfx9.offset[level] : 0;
2428
2429      pLayout->offset = ac_surface_get_plane_offset(device->physical_device->rad_info.gfx_level,
2430                                                    &plane->surface, 0, layer) +
2431                        level_offset;
2432      if (image->vk.format == VK_FORMAT_R32G32B32_UINT ||
2433          image->vk.format == VK_FORMAT_R32G32B32_SINT ||
2434          image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) {
2435         /* Adjust the number of bytes between each row because
2436          * the pitch is actually the number of components per
2437          * row.
2438          */
2439         pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe / 3;
2440      } else {
2441         uint32_t pitch =
2442            surface->is_linear ? surface->u.gfx9.pitch[level] : surface->u.gfx9.surf_pitch;
2443
2444         assert(util_is_power_of_two_nonzero(surface->bpe));
2445         pLayout->rowPitch = pitch * surface->bpe;
2446      }
2447
2448      pLayout->arrayPitch = surface->u.gfx9.surf_slice_size;
2449      pLayout->depthPitch = surface->u.gfx9.surf_slice_size;
2450      pLayout->size = surface->u.gfx9.surf_slice_size;
2451      if (image->vk.image_type == VK_IMAGE_TYPE_3D)
2452         pLayout->size *= u_minify(image->info.depth, level);
2453   } else {
2454      pLayout->offset = (uint64_t)surface->u.legacy.level[level].offset_256B * 256 +
2455                        (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer;
2456      pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
2457      pLayout->arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2458      pLayout->depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2459      pLayout->size = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
2460      if (image->vk.image_type == VK_IMAGE_TYPE_3D)
2461         pLayout->size *= u_minify(image->info.depth, level);
2462   }
2463}
2464
2465VKAPI_ATTR VkResult VKAPI_CALL
2466radv_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device, VkImage _image,
2467                                            VkImageDrmFormatModifierPropertiesEXT *pProperties)
2468{
2469   RADV_FROM_HANDLE(radv_image, image, _image);
2470
2471   pProperties->drmFormatModifier = image->planes[0].surface.modifier;
2472   return VK_SUCCESS;
2473}
2474
2475VKAPI_ATTR VkResult VKAPI_CALL
2476radv_CreateImageView(VkDevice _device, const VkImageViewCreateInfo *pCreateInfo,
2477                     const VkAllocationCallbacks *pAllocator, VkImageView *pView)
2478{
2479   RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
2480   RADV_FROM_HANDLE(radv_device, device, _device);
2481   struct radv_image_view *view;
2482
2483   view =
2484      vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2485   if (view == NULL)
2486      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2487
2488   radv_image_view_init(view, device, pCreateInfo, image->vk.create_flags,
2489                        &(struct radv_image_view_extra_create_info){.from_client = true});
2490
2491   *pView = radv_image_view_to_handle(view);
2492
2493   return VK_SUCCESS;
2494}
2495
2496VKAPI_ATTR void VKAPI_CALL
2497radv_DestroyImageView(VkDevice _device, VkImageView _iview, const VkAllocationCallbacks *pAllocator)
2498{
2499   RADV_FROM_HANDLE(radv_device, device, _device);
2500   RADV_FROM_HANDLE(radv_image_view, iview, _iview);
2501
2502   if (!iview)
2503      return;
2504
2505   radv_image_view_finish(iview);
2506   vk_free2(&device->vk.alloc, pAllocator, iview);
2507}
2508
2509void
2510radv_buffer_view_init(struct radv_buffer_view *view, struct radv_device *device,
2511                      const VkBufferViewCreateInfo *pCreateInfo)
2512{
2513   RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
2514
2515   vk_object_base_init(&device->vk, &view->base, VK_OBJECT_TYPE_BUFFER_VIEW);
2516
2517   view->bo = buffer->bo;
2518   view->range = vk_buffer_range(&buffer->vk, pCreateInfo->offset, pCreateInfo->range);
2519   view->vk_format = pCreateInfo->format;
2520
2521   radv_make_buffer_descriptor(device, buffer, view->vk_format, pCreateInfo->offset, view->range,
2522                               view->state);
2523}
2524
2525void
2526radv_buffer_view_finish(struct radv_buffer_view *view)
2527{
2528   vk_object_base_finish(&view->base);
2529}
2530
2531VKAPI_ATTR VkResult VKAPI_CALL
2532radv_CreateBufferView(VkDevice _device, const VkBufferViewCreateInfo *pCreateInfo,
2533                      const VkAllocationCallbacks *pAllocator, VkBufferView *pView)
2534{
2535   RADV_FROM_HANDLE(radv_device, device, _device);
2536   struct radv_buffer_view *view;
2537
2538   view =
2539      vk_alloc2(&device->vk.alloc, pAllocator, sizeof(*view), 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
2540   if (!view)
2541      return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
2542
2543   radv_buffer_view_init(view, device, pCreateInfo);
2544
2545   *pView = radv_buffer_view_to_handle(view);
2546
2547   return VK_SUCCESS;
2548}
2549
2550VKAPI_ATTR void VKAPI_CALL
2551radv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
2552                       const VkAllocationCallbacks *pAllocator)
2553{
2554   RADV_FROM_HANDLE(radv_device, device, _device);
2555   RADV_FROM_HANDLE(radv_buffer_view, view, bufferView);
2556
2557   if (!view)
2558      return;
2559
2560   radv_buffer_view_finish(view);
2561   vk_free2(&device->vk.alloc, pAllocator, view);
2562}
2563