• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  * SPDX-License-Identifier: MIT
9  */
10 
11 #include "radv_image.h"
12 #include "util/u_atomic.h"
13 #include "util/u_debug.h"
14 #include "ac_drm_fourcc.h"
15 #include "ac_formats.h"
16 #include "radv_android.h"
17 #include "radv_buffer.h"
18 #include "radv_buffer_view.h"
19 #include "radv_debug.h"
20 #include "radv_device_memory.h"
21 #include "radv_entrypoints.h"
22 #include "radv_formats.h"
23 #include "radv_image_view.h"
24 #include "radv_radeon_winsys.h"
25 #include "radv_rmv.h"
26 #include "radv_video.h"
27 #include "radv_wsi.h"
28 #include "sid.h"
29 #include "vk_debug_utils.h"
30 #include "vk_format.h"
31 #include "vk_log.h"
32 #include "vk_render_pass.h"
33 #include "vk_util.h"
34 
35 #include "gfx10_format_table.h"
36 
37 static unsigned
radv_choose_tiling(struct radv_device * device,const VkImageCreateInfo * pCreateInfo,VkFormat format)38 radv_choose_tiling(struct radv_device *device, const VkImageCreateInfo *pCreateInfo, VkFormat format)
39 {
40    const struct radv_physical_device *pdev = radv_device_physical(device);
41 
42    if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
43       assert(pCreateInfo->samples <= 1);
44       return RADEON_SURF_MODE_LINEAR_ALIGNED;
45    }
46 
47    if (pCreateInfo->usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR | VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR))
48       return RADEON_SURF_MODE_LINEAR_ALIGNED;
49 
50    if (pCreateInfo->usage & (VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR | VK_IMAGE_USAGE_VIDEO_ENCODE_SRC_BIT_KHR))
51       return RADEON_SURF_MODE_LINEAR_ALIGNED;
52 
53    /* MSAA resources must be 2D tiled. */
54    if (pCreateInfo->samples > 1)
55       return RADEON_SURF_MODE_2D;
56 
57    if (!vk_format_is_compressed(format) && !vk_format_is_depth_or_stencil(format) && pdev->info.gfx_level <= GFX8) {
58       /* this causes hangs in some VK CTS tests on GFX9. */
59       /* Textures with a very small height are recommended to be linear. */
60       if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
61           /* Only very thin and long 2D textures should benefit from
62            * linear_aligned. */
63           (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
64          return RADEON_SURF_MODE_LINEAR_ALIGNED;
65    }
66 
67    return RADEON_SURF_MODE_2D;
68 }
69 
70 static bool
radv_use_tc_compat_htile_for_image(struct radv_device * device,const VkImageCreateInfo * pCreateInfo,VkFormat format)71 radv_use_tc_compat_htile_for_image(struct radv_device *device, const VkImageCreateInfo *pCreateInfo, VkFormat format)
72 {
73    const struct radv_physical_device *pdev = radv_device_physical(device);
74 
75    if (!pdev->info.has_tc_compatible_htile)
76       return false;
77 
78    if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
79       return false;
80 
81    /* Do not enable TC-compatible HTILE if the image isn't readable by a
82     * shader because no texture fetches will happen.
83     */
84    if (!(pCreateInfo->usage &
85          (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
86       return false;
87 
88    if (pdev->info.gfx_level < GFX9) {
89       /* TC-compat HTILE for MSAA depth/stencil images is broken
90        * on GFX8 because the tiling doesn't match.
91        */
92       if (pCreateInfo->samples >= 2 && format == VK_FORMAT_D32_SFLOAT_S8_UINT)
93          return false;
94 
95       /* GFX9+ supports compression for both 32-bit and 16-bit depth
96        * surfaces, while GFX8 only supports 32-bit natively. Though,
97        * the driver allows TC-compat HTILE for 16-bit depth surfaces
98        * with no Z planes compression.
99        */
100       if (format != VK_FORMAT_D32_SFLOAT_S8_UINT && format != VK_FORMAT_D32_SFLOAT && format != VK_FORMAT_D16_UNORM)
101          return false;
102 
103       /* TC-compat HTILE for layered images can have interleaved slices (see sliceInterleaved flag
104        * in addrlib).  radv_clear_htile does not work.
105        */
106       if (pCreateInfo->arrayLayers > 1)
107          return false;
108    }
109 
110    /* GFX9 has issues when the sample count is 4 and the format is D16 */
111    if (pdev->info.gfx_level == GFX9 && pCreateInfo->samples == 4 && format == VK_FORMAT_D16_UNORM)
112       return false;
113 
114    return true;
115 }
116 
117 static bool
radv_surface_has_scanout(struct radv_device * device,const struct radv_image_create_info * info)118 radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info)
119 {
120    const struct radv_physical_device *pdev = radv_device_physical(device);
121 
122    if (info->bo_metadata) {
123       if (pdev->info.gfx_level >= GFX9)
124          return info->bo_metadata->u.gfx9.scanout;
125       else
126          return info->bo_metadata->u.legacy.scanout;
127    }
128 
129    return info->scanout;
130 }
131 
132 static bool
radv_image_use_fast_clear_for_image_early(const struct radv_device * device,const struct radv_image * image)133 radv_image_use_fast_clear_for_image_early(const struct radv_device *device, const struct radv_image *image)
134 {
135    const struct radv_physical_device *pdev = radv_device_physical(device);
136    const struct radv_instance *instance = radv_physical_device_instance(pdev);
137 
138    if (instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
139       return true;
140 
141    if (image->vk.samples <= 1 && image->vk.extent.width * image->vk.extent.height <= 512 * 512) {
142       /* Do not enable CMASK or DCC for small surfaces where the cost
143        * of the eliminate pass can be higher than the benefit of fast
144        * clear. RadeonSI does this, but the image threshold is
145        * different.
146        */
147       return false;
148    }
149 
150    return !!(image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
151 }
152 
153 static bool
radv_image_use_fast_clear_for_image(const struct radv_device * device,const struct radv_image * image)154 radv_image_use_fast_clear_for_image(const struct radv_device *device, const struct radv_image *image)
155 {
156    const struct radv_physical_device *pdev = radv_device_physical(device);
157    const struct radv_instance *instance = radv_physical_device_instance(pdev);
158 
159    if (instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)
160       return true;
161 
162    return radv_image_use_fast_clear_for_image_early(device, image) && (image->exclusive ||
163                                                                        /* Enable DCC for concurrent images if stores are
164                                                                         * supported because that means we can keep DCC
165                                                                         * compressed on all layouts/queues.
166                                                                         */
167                                                                        radv_image_use_dcc_image_stores(device, image));
168 }
169 
170 bool
radv_are_formats_dcc_compatible(const struct radv_physical_device * pdev,const void * pNext,VkFormat format,VkImageCreateFlags flags,bool * sign_reinterpret)171 radv_are_formats_dcc_compatible(const struct radv_physical_device *pdev, const void *pNext, VkFormat format,
172                                 VkImageCreateFlags flags, bool *sign_reinterpret)
173 {
174    if (!radv_is_colorbuffer_format_supported(pdev, format))
175       return false;
176 
177    if (sign_reinterpret != NULL)
178       *sign_reinterpret = false;
179 
180    /* All formats are compatible on GFX11. */
181    if ((flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && pdev->info.gfx_level < GFX11) {
182       const struct VkImageFormatListCreateInfo *format_list =
183          (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
184 
185       /* We have to ignore the existence of the list if viewFormatCount = 0 */
186       if (format_list && format_list->viewFormatCount) {
187          /* compatibility is transitive, so we only need to check
188           * one format with everything else. */
189          for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
190             if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
191                continue;
192 
193             if (!radv_dcc_formats_compatible(pdev->info.gfx_level, format, format_list->pViewFormats[i],
194                                              sign_reinterpret))
195                return false;
196          }
197       } else {
198          return false;
199       }
200    }
201 
202    return true;
203 }
204 
205 static bool
radv_format_is_atomic_allowed(struct radv_device * device,VkFormat format)206 radv_format_is_atomic_allowed(struct radv_device *device, VkFormat format)
207 {
208    if (format == VK_FORMAT_R32_SFLOAT && !radv_uses_image_float32_atomics(device))
209       return false;
210 
211    return radv_is_atomic_format_supported(format);
212 }
213 
214 static bool
radv_formats_is_atomic_allowed(struct radv_device * device,const void * pNext,VkFormat format,VkImageCreateFlags flags)215 radv_formats_is_atomic_allowed(struct radv_device *device, const void *pNext, VkFormat format, VkImageCreateFlags flags)
216 {
217    if (radv_format_is_atomic_allowed(device, format))
218       return true;
219 
220    if (flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
221       const struct VkImageFormatListCreateInfo *format_list =
222          (const struct VkImageFormatListCreateInfo *)vk_find_struct_const(pNext, IMAGE_FORMAT_LIST_CREATE_INFO);
223 
224       /* We have to ignore the existence of the list if viewFormatCount = 0 */
225       if (format_list && format_list->viewFormatCount) {
226          for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
227             if (radv_format_is_atomic_allowed(device, format_list->pViewFormats[i]))
228                return true;
229          }
230       }
231    }
232 
233    return false;
234 }
235 
236 static bool
radv_use_dcc_for_image_early(struct radv_device * device,struct radv_image * image,const VkImageCreateInfo * pCreateInfo,VkFormat format,bool * sign_reinterpret)237 radv_use_dcc_for_image_early(struct radv_device *device, struct radv_image *image, const VkImageCreateInfo *pCreateInfo,
238                              VkFormat format, bool *sign_reinterpret)
239 {
240    const struct radv_physical_device *pdev = radv_device_physical(device);
241    const struct radv_instance *instance = radv_physical_device_instance(pdev);
242 
243    /* DCC (Delta Color Compression) is only available for GFX8+. */
244    if (pdev->info.gfx_level < GFX8)
245       return false;
246 
247    const VkImageCompressionControlEXT *compression =
248       vk_find_struct_const(pCreateInfo->pNext, IMAGE_COMPRESSION_CONTROL_EXT);
249 
250    if (instance->debug_flags & RADV_DEBUG_NO_DCC ||
251        (compression && compression->flags == VK_IMAGE_COMPRESSION_DISABLED_EXT)) {
252       return false;
253    }
254 
255    if (image->shareable && image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
256       return false;
257 
258    /*
259     * TODO: Enable DCC for storage images on GFX9 and earlier.
260     *
261     * Also disable DCC with atomics because even when DCC stores are
262     * supported atomics will always decompress. So if we are
263     * decompressing a lot anyway we might as well not have DCC.
264     */
265    if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
266        (pdev->info.gfx_level < GFX10 ||
267         radv_formats_is_atomic_allowed(device, pCreateInfo->pNext, format, pCreateInfo->flags)))
268       return false;
269 
270    if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
271       return false;
272 
273    if (vk_format_is_subsampled(format) || vk_format_get_plane_count(format) > 1)
274       return false;
275 
276    if (!radv_image_use_fast_clear_for_image_early(device, image) &&
277        image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
278       return false;
279 
280    /* Do not enable DCC for mipmapped arrays because performance is worse. */
281    if (pCreateInfo->arrayLayers > 1 && pCreateInfo->mipLevels > 1)
282       return false;
283 
284    if (pdev->info.gfx_level < GFX10) {
285       /* TODO: Add support for DCC MSAA on GFX8-9. */
286       if (pCreateInfo->samples > 1 && !pdev->dcc_msaa_allowed)
287          return false;
288 
289       /* TODO: Add support for DCC layers/mipmaps on GFX9. */
290       if ((pCreateInfo->arrayLayers > 1 || pCreateInfo->mipLevels > 1) && pdev->info.gfx_level == GFX9)
291          return false;
292    }
293 
294    /* Force disable DCC for mips to workaround game bugs. */
295    if (instance->drirc.disable_dcc_mips && pCreateInfo->mipLevels > 1)
296       return false;
297 
298    /* Force disable DCC for stores to workaround game bugs. */
299    if (instance->drirc.disable_dcc_stores && (pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT))
300       return false;
301 
302    /* DCC MSAA can't work on GFX10.3 and earlier without FMASK. */
303    if (pCreateInfo->samples > 1 && pdev->info.gfx_level < GFX11 && (instance->debug_flags & RADV_DEBUG_NO_FMASK))
304       return false;
305 
306    return radv_are_formats_dcc_compatible(pdev, pCreateInfo->pNext, format, pCreateInfo->flags, sign_reinterpret);
307 }
308 
309 static bool
radv_use_dcc_for_image_late(struct radv_device * device,struct radv_image * image)310 radv_use_dcc_for_image_late(struct radv_device *device, struct radv_image *image)
311 {
312    if (!radv_image_has_dcc(image))
313       return false;
314 
315    if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
316       return true;
317 
318    if (!radv_image_use_fast_clear_for_image(device, image))
319       return false;
320 
321    /* TODO: Fix storage images with DCC without DCC image stores.
322     * Disabling it for now. */
323    if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) && !radv_image_use_dcc_image_stores(device, image))
324       return false;
325 
326    return true;
327 }
328 
329 /*
330  * Whether to enable image stores with DCC compression for this image. If
331  * this function returns false the image subresource should be decompressed
332  * before using it with image stores.
333  *
334  * Note that this can have mixed performance implications, see
335  * https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/6796#note_643299
336  *
337  * This function assumes the image uses DCC compression.
338  */
339 bool
radv_image_use_dcc_image_stores(const struct radv_device * device,const struct radv_image * image)340 radv_image_use_dcc_image_stores(const struct radv_device *device, const struct radv_image *image)
341 {
342    const struct radv_physical_device *pdev = radv_device_physical(device);
343 
344    return ac_surface_supports_dcc_image_stores(pdev->info.gfx_level, &image->planes[0].surface);
345 }
346 
347 /*
348  * Whether to use a predicate to determine whether DCC is in a compressed
349  * state. This can be used to avoid decompressing an image multiple times.
350  */
351 bool
radv_image_use_dcc_predication(const struct radv_device * device,const struct radv_image * image)352 radv_image_use_dcc_predication(const struct radv_device *device, const struct radv_image *image)
353 {
354    return radv_image_has_dcc(image) && !radv_image_use_dcc_image_stores(device, image);
355 }
356 
357 static inline bool
radv_use_fmask_for_image(const struct radv_device * device,const struct radv_image * image)358 radv_use_fmask_for_image(const struct radv_device *device, const struct radv_image *image)
359 {
360    const struct radv_physical_device *pdev = radv_device_physical(device);
361    const struct radv_instance *instance = radv_physical_device_instance(pdev);
362 
363    if (pdev->info.gfx_level == GFX9 && image->vk.array_layers > 1) {
364       /* On GFX9, FMASK can be interleaved with layers and this isn't properly supported. */
365       return false;
366    }
367 
368    return pdev->use_fmask && image->vk.samples > 1 &&
369           ((image->vk.usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) ||
370            (instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS));
371 }
372 
373 static inline bool
radv_use_htile_for_image(const struct radv_device * device,const struct radv_image * image,const VkImageCreateInfo * pCreateInfo)374 radv_use_htile_for_image(const struct radv_device *device, const struct radv_image *image,
375                          const VkImageCreateInfo *pCreateInfo)
376 {
377    const struct radv_physical_device *pdev = radv_device_physical(device);
378    const struct radv_instance *instance = radv_physical_device_instance(pdev);
379    const enum amd_gfx_level gfx_level = pdev->info.gfx_level;
380 
381    const VkImageCompressionControlEXT *compression =
382       vk_find_struct_const(pCreateInfo->pNext, IMAGE_COMPRESSION_CONTROL_EXT);
383 
384    if (instance->debug_flags & RADV_DEBUG_NO_HIZ ||
385        (compression && compression->flags == VK_IMAGE_COMPRESSION_DISABLED_EXT))
386       return false;
387 
388    if (image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT)
389       return false;
390 
391    /* TODO:
392     * - Investigate about mips+layers.
393     * - Enable on other gens.
394     */
395    bool use_htile_for_mips = image->vk.array_layers == 1 && pdev->info.gfx_level >= GFX10;
396 
397    /* Stencil texturing with HTILE doesn't work with mipmapping on Navi10-14. */
398    if (pdev->info.gfx_level == GFX10 && image->vk.format == VK_FORMAT_D32_SFLOAT_S8_UINT && image->vk.mip_levels > 1)
399       return false;
400 
401    /* Do not enable HTILE for very small images because it seems less performant but make sure it's
402     * allowed with VRS attachments because we need HTILE on GFX10.3.
403     */
404    if (image->vk.extent.width * image->vk.extent.height < 8 * 8 &&
405        !(instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS) &&
406        !(gfx_level == GFX10_3 && device->vk.enabled_features.attachmentFragmentShadingRate))
407       return false;
408 
409    return (image->vk.mip_levels == 1 || use_htile_for_mips) && !image->shareable;
410 }
411 
412 static bool
radv_use_tc_compat_cmask_for_image(struct radv_device * device,struct radv_image * image)413 radv_use_tc_compat_cmask_for_image(struct radv_device *device, struct radv_image *image)
414 {
415    const struct radv_physical_device *pdev = radv_device_physical(device);
416    const struct radv_instance *instance = radv_physical_device_instance(pdev);
417 
418    /* TC-compat CMASK is only available for GFX8+. */
419    if (pdev->info.gfx_level < GFX8)
420       return false;
421 
422    /* GFX9 has issues when sample count is greater than 2 */
423    if (pdev->info.gfx_level == GFX9 && image->vk.samples > 2)
424       return false;
425 
426    if (instance->debug_flags & RADV_DEBUG_NO_TC_COMPAT_CMASK)
427       return false;
428 
429    /* TC-compat CMASK with storage images is supported on GFX10+. */
430    if ((image->vk.usage & VK_IMAGE_USAGE_STORAGE_BIT) && pdev->info.gfx_level < GFX10)
431       return false;
432 
433    /* Do not enable TC-compatible if the image isn't readable by a shader
434     * because no texture fetches will happen.
435     */
436    if (!(image->vk.usage &
437          (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT)))
438       return false;
439 
440    /* If the image doesn't have FMASK, it can't be fetchable. */
441    if (!radv_image_has_fmask(image))
442       return false;
443 
444    return true;
445 }
446 
447 static uint32_t
radv_get_bo_metadata_word1(const struct radv_device * device)448 radv_get_bo_metadata_word1(const struct radv_device *device)
449 {
450    const struct radv_physical_device *pdev = radv_device_physical(device);
451 
452    return (ATI_VENDOR_ID << 16) | pdev->info.pci_id;
453 }
454 
455 static bool
radv_is_valid_opaque_metadata(const struct radv_device * device,const struct radeon_bo_metadata * md)456 radv_is_valid_opaque_metadata(const struct radv_device *device, const struct radeon_bo_metadata *md)
457 {
458    if (md->metadata[0] != 1 || md->metadata[1] != radv_get_bo_metadata_word1(device))
459       return false;
460 
461    if (md->size_metadata < 40)
462       return false;
463 
464    return true;
465 }
466 
467 static void
radv_patch_surface_from_metadata(struct radv_device * device,struct radeon_surf * surface,const struct radeon_bo_metadata * md)468 radv_patch_surface_from_metadata(struct radv_device *device, struct radeon_surf *surface,
469                                  const struct radeon_bo_metadata *md)
470 {
471    const struct radv_physical_device *pdev = radv_device_physical(device);
472 
473    surface->flags = RADEON_SURF_CLR(surface->flags, MODE);
474 
475    if (pdev->info.gfx_level >= GFX9) {
476       if (md->u.gfx9.swizzle_mode > 0)
477          surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
478       else
479          surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
480 
481       surface->u.gfx9.swizzle_mode = md->u.gfx9.swizzle_mode;
482    } else {
483       surface->u.legacy.pipe_config = md->u.legacy.pipe_config;
484       surface->u.legacy.bankw = md->u.legacy.bankw;
485       surface->u.legacy.bankh = md->u.legacy.bankh;
486       surface->u.legacy.tile_split = md->u.legacy.tile_split;
487       surface->u.legacy.mtilea = md->u.legacy.mtilea;
488       surface->u.legacy.num_banks = md->u.legacy.num_banks;
489 
490       if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
491          surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
492       else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
493          surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
494       else
495          surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
496    }
497 }
498 
499 static VkResult
radv_patch_image_dimensions(struct radv_device * device,struct radv_image * image,const struct radv_image_create_info * create_info,struct ac_surf_info * image_info)500 radv_patch_image_dimensions(struct radv_device *device, struct radv_image *image,
501                             const struct radv_image_create_info *create_info, struct ac_surf_info *image_info)
502 {
503    const struct radv_physical_device *pdev = radv_device_physical(device);
504    unsigned width = image->vk.extent.width;
505    unsigned height = image->vk.extent.height;
506 
507    /*
508     * minigbm sometimes allocates bigger images which is going to result in
509     * weird strides and other properties. Lets be lenient where possible and
510     * fail it on GFX10 (as we cannot cope there).
511     *
512     * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
513     */
514    if (create_info->bo_metadata && radv_is_valid_opaque_metadata(device, create_info->bo_metadata)) {
515       const struct radeon_bo_metadata *md = create_info->bo_metadata;
516 
517       if (pdev->info.gfx_level >= GFX10) {
518          width = G_00A004_WIDTH_LO(md->metadata[3]) + (G_00A008_WIDTH_HI(md->metadata[4]) << 2) + 1;
519          height = G_00A008_HEIGHT(md->metadata[4]) + 1;
520       } else {
521          width = G_008F18_WIDTH(md->metadata[4]) + 1;
522          height = G_008F18_HEIGHT(md->metadata[4]) + 1;
523       }
524    }
525 
526    if (image->vk.extent.width == width && image->vk.extent.height == height)
527       return VK_SUCCESS;
528 
529    if (width < image->vk.extent.width || height < image->vk.extent.height) {
530       fprintf(stderr,
531               "The imported image has smaller dimensions than the internal\n"
532               "dimensions. Using it is going to fail badly, so we reject\n"
533               "this import.\n"
534               "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
535               image->vk.extent.width, image->vk.extent.height, width, height);
536       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
537    } else if (pdev->info.gfx_level >= GFX10) {
538       fprintf(stderr,
539               "Tried to import an image with inconsistent width on GFX10.\n"
540               "As GFX10 has no separate stride fields we cannot cope with\n"
541               "an inconsistency in width and will fail this import.\n"
542               "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
543               image->vk.extent.width, image->vk.extent.height, width, height);
544       return VK_ERROR_INVALID_EXTERNAL_HANDLE;
545    } else {
546       fprintf(stderr,
547               "Tried to import an image with inconsistent width on pre-GFX10.\n"
548               "As GFX10 has no separate stride fields we cannot cope with\n"
549               "an inconsistency and would fail on GFX10.\n"
550               "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
551               image->vk.extent.width, image->vk.extent.height, width, height);
552    }
553    image_info->width = width;
554    image_info->height = height;
555 
556    return VK_SUCCESS;
557 }
558 
559 static VkResult
radv_patch_image_from_extra_info(struct radv_device * device,struct radv_image * image,const struct radv_image_create_info * create_info,struct ac_surf_info * image_info)560 radv_patch_image_from_extra_info(struct radv_device *device, struct radv_image *image,
561                                  const struct radv_image_create_info *create_info, struct ac_surf_info *image_info)
562 {
563    const struct radv_physical_device *pdev = radv_device_physical(device);
564    const struct radv_instance *instance = radv_physical_device_instance(pdev);
565 
566    VkResult result = radv_patch_image_dimensions(device, image, create_info, image_info);
567    if (result != VK_SUCCESS)
568       return result;
569 
570    for (unsigned plane = 0; plane < image->plane_count; ++plane) {
571       if (create_info->bo_metadata) {
572          radv_patch_surface_from_metadata(device, &image->planes[plane].surface, create_info->bo_metadata);
573       }
574 
575       if (radv_surface_has_scanout(device, create_info)) {
576          image->planes[plane].surface.flags |= RADEON_SURF_SCANOUT;
577          if (instance->debug_flags & RADV_DEBUG_NO_DISPLAY_DCC)
578             image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
579 
580          image_info->surf_index = NULL;
581       }
582 
583       if (create_info->prime_blit_src && !pdev->info.sdma_supports_compression) {
584          /* Older SDMA hw can't handle DCC */
585          image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC;
586       }
587    }
588    return VK_SUCCESS;
589 }
590 
591 static VkFormat
radv_image_get_plane_format(const struct radv_physical_device * pdev,const struct radv_image * image,unsigned plane)592 radv_image_get_plane_format(const struct radv_physical_device *pdev, const struct radv_image *image, unsigned plane)
593 {
594    if (radv_is_format_emulated(pdev, image->vk.format)) {
595       if (plane == 0)
596          return image->vk.format;
597       if (vk_format_description(image->vk.format)->layout == UTIL_FORMAT_LAYOUT_ASTC)
598          return vk_texcompress_astc_emulation_format(image->vk.format);
599       else
600          return vk_texcompress_etc2_emulation_format(image->vk.format);
601    }
602 
603    return vk_format_get_plane_format(image->vk.format, plane);
604 }
605 
606 static uint64_t
radv_get_surface_flags(struct radv_device * device,struct radv_image * image,unsigned plane_id,const VkImageCreateInfo * pCreateInfo,VkFormat image_format)607 radv_get_surface_flags(struct radv_device *device, struct radv_image *image, unsigned plane_id,
608                        const VkImageCreateInfo *pCreateInfo, VkFormat image_format)
609 {
610    const struct radv_physical_device *pdev = radv_device_physical(device);
611    const struct radv_instance *instance = radv_physical_device_instance(pdev);
612    uint64_t flags;
613    unsigned array_mode = radv_choose_tiling(device, pCreateInfo, image_format);
614    VkFormat format = radv_image_get_plane_format(pdev, image, plane_id);
615    const struct util_format_description *desc = vk_format_description(format);
616    const VkImageAlignmentControlCreateInfoMESA *alignment =
617          vk_find_struct_const(pCreateInfo->pNext, IMAGE_ALIGNMENT_CONTROL_CREATE_INFO_MESA);
618    bool is_depth, is_stencil;
619 
620    is_depth = util_format_has_depth(desc);
621    is_stencil = util_format_has_stencil(desc);
622 
623    flags = RADEON_SURF_SET(array_mode, MODE);
624 
625    switch (pCreateInfo->imageType) {
626    case VK_IMAGE_TYPE_1D:
627       if (pCreateInfo->arrayLayers > 1)
628          flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
629       else
630          flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
631       break;
632    case VK_IMAGE_TYPE_2D:
633       if (pCreateInfo->arrayLayers > 1)
634          flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
635       else
636          flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
637       break;
638    case VK_IMAGE_TYPE_3D:
639       flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
640       break;
641    default:
642       unreachable("unhandled image type");
643    }
644 
645    /* Required for clearing/initializing a specific layer on GFX8. */
646    flags |= RADEON_SURF_CONTIGUOUS_DCC_LAYERS;
647 
648    if (is_depth) {
649       flags |= RADEON_SURF_ZBUFFER;
650 
651       if (is_depth && is_stencil && pdev->info.gfx_level <= GFX8) {
652          if (!(pCreateInfo->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT))
653             flags |= RADEON_SURF_NO_RENDER_TARGET;
654 
655          /* RADV doesn't support stencil pitch adjustment. As a result there are some spec gaps that
656           * are not covered by CTS.
657           *
658           * For D+S images with pitch constraints due to rendertarget usage it can happen that
659           * sampling from mipmaps beyond the base level of the descriptor is broken as the pitch
660           * adjustment can't be applied to anything beyond the first level.
661           */
662          flags |= RADEON_SURF_NO_STENCIL_ADJUST;
663       }
664 
665       if (radv_use_htile_for_image(device, image, pCreateInfo) && !(flags & RADEON_SURF_NO_RENDER_TARGET)) {
666          if (radv_use_tc_compat_htile_for_image(device, pCreateInfo, image_format))
667             flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
668       } else {
669          flags |= RADEON_SURF_NO_HTILE;
670       }
671    }
672 
673    if (is_stencil)
674       flags |= RADEON_SURF_SBUFFER;
675 
676    if (pdev->info.gfx_level >= GFX9 && pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
677        vk_format_get_blocksizebits(image_format) == 128 && vk_format_is_compressed(image_format))
678       flags |= RADEON_SURF_NO_RENDER_TARGET;
679 
680    if (!radv_use_dcc_for_image_early(device, image, pCreateInfo, image_format, &image->dcc_sign_reinterpret))
681       flags |= RADEON_SURF_DISABLE_DCC;
682 
683    if (!radv_use_fmask_for_image(device, image))
684       flags |= RADEON_SURF_NO_FMASK;
685 
686    if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT) {
687       flags |= RADEON_SURF_PRT | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE | RADEON_SURF_DISABLE_DCC;
688    }
689 
690    if (image->queue_family_mask & BITFIELD_BIT(RADV_QUEUE_TRANSFER)) {
691       if (!pdev->info.sdma_supports_compression)
692          flags |= RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_HTILE;
693    }
694 
695    /* Disable DCC for VRS rate images because the hw can't handle compression. */
696    if (pCreateInfo->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)
697       flags |= RADEON_SURF_VRS_RATE | RADEON_SURF_DISABLE_DCC;
698    if (!(pCreateInfo->usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT)))
699       flags |= RADEON_SURF_NO_TEXTURE;
700 
701    if (alignment && alignment->maximumRequestedAlignment && !(instance->debug_flags & RADV_DEBUG_FORCE_COMPRESS)) {
702       bool is_4k_capable;
703 
704       if (!vk_format_is_depth_or_stencil(image_format)) {
705          is_4k_capable =
706                !(pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) && (flags & RADEON_SURF_DISABLE_DCC) &&
707                (flags & RADEON_SURF_NO_FMASK);
708       } else {
709          /* Depth-stencil format without DEPTH_STENCIL usage does not work either. */
710          is_4k_capable = false;
711       }
712 
713       if (is_4k_capable && alignment->maximumRequestedAlignment <= 4096)
714          flags |= RADEON_SURF_PREFER_4K_ALIGNMENT;
715       if (alignment->maximumRequestedAlignment <= 64 * 1024)
716          flags |= RADEON_SURF_PREFER_64K_ALIGNMENT;
717    }
718 
719    return flags;
720 }
721 
722 void
radv_compose_swizzle(const struct util_format_description * desc,const VkComponentMapping * mapping,enum pipe_swizzle swizzle[4])723 radv_compose_swizzle(const struct util_format_description *desc, const VkComponentMapping *mapping,
724                      enum pipe_swizzle swizzle[4])
725 {
726    if (desc->format == PIPE_FORMAT_R64_UINT || desc->format == PIPE_FORMAT_R64_SINT) {
727       /* 64-bit formats only support storage images and storage images
728        * require identity component mappings. We use 32-bit
729        * instructions to access 64-bit images, so we need a special
730        * case here.
731        *
732        * The zw components are 1,0 so that they can be easily be used
733        * by loads to create the w component, which has to be 0 for
734        * NULL descriptors.
735        */
736       swizzle[0] = PIPE_SWIZZLE_X;
737       swizzle[1] = PIPE_SWIZZLE_Y;
738       swizzle[2] = PIPE_SWIZZLE_1;
739       swizzle[3] = PIPE_SWIZZLE_0;
740    } else if (!mapping) {
741       for (unsigned i = 0; i < 4; i++)
742          swizzle[i] = desc->swizzle[i];
743    } else if (desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
744       const unsigned char swizzle_xxxx[4] = {PIPE_SWIZZLE_X, PIPE_SWIZZLE_0, PIPE_SWIZZLE_0, PIPE_SWIZZLE_1};
745       vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
746    } else {
747       vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
748    }
749 }
750 
751 static void
radv_query_opaque_metadata(struct radv_device * device,struct radv_image * image,unsigned plane_id,struct radeon_bo_metadata * md)752 radv_query_opaque_metadata(struct radv_device *device, struct radv_image *image, unsigned plane_id,
753                            struct radeon_bo_metadata *md)
754 {
755    const struct radv_physical_device *pdev = radv_device_physical(device);
756    const struct radv_instance *instance = radv_physical_device_instance(pdev);
757    static const VkComponentMapping fixedmapping;
758    const VkFormat plane_format = radv_image_get_plane_format(pdev, image, plane_id);
759    const unsigned plane_width = vk_format_get_plane_width(image->vk.format, plane_id, image->vk.extent.width);
760    const unsigned plane_height = vk_format_get_plane_height(image->vk.format, plane_id, image->vk.extent.height);
761    struct radeon_surf *surface = &image->planes[plane_id].surface;
762    const struct legacy_surf_level *base_level_info = pdev->info.gfx_level <= GFX8 ? &surface->u.legacy.level[0] : NULL;
763    uint32_t desc[8];
764 
765    radv_make_texture_descriptor(device, image, false, (VkImageViewType)image->vk.image_type, plane_format,
766                                 &fixedmapping, 0, image->vk.mip_levels - 1, 0, image->vk.array_layers - 1, plane_width,
767                                 plane_height, image->vk.extent.depth, 0.0f, desc, NULL, NULL, NULL);
768 
769    radv_set_mutable_tex_desc_fields(device, image, base_level_info, plane_id, 0, 0, surface->blk_w, false, false, false,
770                                     false, desc, NULL, 0);
771 
772    ac_surface_compute_umd_metadata(&pdev->info, surface, image->vk.mip_levels, desc, &md->size_metadata, md->metadata,
773                                    instance->debug_flags & RADV_DEBUG_EXTRA_MD);
774 }
775 
776 void
radv_init_metadata(struct radv_device * device,struct radv_image * image,struct radeon_bo_metadata * metadata)777 radv_init_metadata(struct radv_device *device, struct radv_image *image, struct radeon_bo_metadata *metadata)
778 {
779    const struct radv_physical_device *pdev = radv_device_physical(device);
780 
781    /* use plane 0, even when there are multiple planes, to follow radeonsi */
782    const unsigned plane_id = 0;
783    struct radeon_surf *surface = &image->planes[plane_id].surface;
784 
785    memset(metadata, 0, sizeof(*metadata));
786 
787    if (pdev->info.gfx_level >= GFX9) {
788       uint64_t dcc_offset =
789          image->bindings[0].offset + (surface->display_dcc_offset ? surface->display_dcc_offset : surface->meta_offset);
790       metadata->u.gfx9.swizzle_mode = surface->u.gfx9.swizzle_mode;
791       metadata->u.gfx9.dcc_offset_256b = dcc_offset >> 8;
792       metadata->u.gfx9.dcc_pitch_max = surface->u.gfx9.color.display_dcc_pitch_max;
793       metadata->u.gfx9.dcc_independent_64b_blocks = surface->u.gfx9.color.dcc.independent_64B_blocks;
794       metadata->u.gfx9.dcc_independent_128b_blocks = surface->u.gfx9.color.dcc.independent_128B_blocks;
795       metadata->u.gfx9.dcc_max_compressed_block_size = surface->u.gfx9.color.dcc.max_compressed_block_size;
796       metadata->u.gfx9.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
797    } else {
798       metadata->u.legacy.microtile =
799          surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D ? RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
800       metadata->u.legacy.macrotile =
801          surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D ? RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
802       metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
803       metadata->u.legacy.bankw = surface->u.legacy.bankw;
804       metadata->u.legacy.bankh = surface->u.legacy.bankh;
805       metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
806       metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
807       metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
808       metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
809       metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
810    }
811    radv_query_opaque_metadata(device, image, plane_id, metadata);
812 }
813 
814 void
radv_image_override_offset_stride(struct radv_device * device,struct radv_image * image,uint64_t offset,uint32_t stride)815 radv_image_override_offset_stride(struct radv_device *device, struct radv_image *image, uint64_t offset,
816                                   uint32_t stride)
817 {
818    const struct radv_physical_device *pdev = radv_device_physical(device);
819    ac_surface_override_offset_stride(&pdev->info, &image->planes[0].surface, image->vk.array_layers,
820                                      image->vk.mip_levels, offset, stride);
821 }
822 
823 static void
radv_image_alloc_single_sample_cmask(const struct radv_device * device,const struct radv_image * image,struct radeon_surf * surf)824 radv_image_alloc_single_sample_cmask(const struct radv_device *device, const struct radv_image *image,
825                                      struct radeon_surf *surf)
826 {
827    if (!surf->cmask_size || surf->cmask_offset || surf->bpe > 8 || image->vk.mip_levels > 1 ||
828        image->vk.extent.depth > 1 || radv_image_has_dcc(image) || !radv_image_use_fast_clear_for_image(device, image) ||
829        (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT))
830       return;
831 
832    assert(image->vk.samples == 1);
833 
834    surf->cmask_offset = align64(surf->total_size, 1ull << surf->cmask_alignment_log2);
835    surf->total_size = surf->cmask_offset + surf->cmask_size;
836    surf->alignment_log2 = MAX2(surf->alignment_log2, surf->cmask_alignment_log2);
837 }
838 
839 static void
radv_image_alloc_values(const struct radv_device * device,struct radv_image * image)840 radv_image_alloc_values(const struct radv_device *device, struct radv_image *image)
841 {
842    const struct radv_physical_device *pdev = radv_device_physical(device);
843 
844    /* images with modifiers can be potentially imported */
845    if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT)
846       return;
847 
848    if (radv_image_has_cmask(image) || (radv_image_has_dcc(image) && !image->support_comp_to_single)) {
849       image->fce_pred_offset = image->size;
850       image->size += 8 * image->vk.mip_levels;
851    }
852 
853    if (radv_image_use_dcc_predication(device, image)) {
854       image->dcc_pred_offset = image->size;
855       image->size += 8 * image->vk.mip_levels;
856    }
857 
858    if ((radv_image_has_dcc(image) && !image->support_comp_to_single) || radv_image_has_cmask(image) ||
859        radv_image_has_htile(image)) {
860       image->clear_value_offset = image->size;
861       image->size += 8 * image->vk.mip_levels;
862    }
863 
864    if (radv_image_is_tc_compat_htile(image) && pdev->info.has_tc_compat_zrange_bug) {
865       /* Metadata for the TC-compatible HTILE hardware bug which
866        * have to be fixed by updating ZRANGE_PRECISION when doing
867        * fast depth clears to 0.0f.
868        */
869       image->tc_compat_zrange_offset = image->size;
870       image->size += image->vk.mip_levels * 4;
871    }
872 }
873 
874 /* Determine if the image is affected by the pipe misaligned metadata issue
875  * which requires to invalidate L2.
876  */
877 static bool
radv_image_is_pipe_misaligned(const struct radv_image * image,const VkImageSubresourceRange * range)878 radv_image_is_pipe_misaligned(const struct radv_image *image, const VkImageSubresourceRange *range)
879 {
880    for (unsigned i = 0; i < image->plane_count; ++i) {
881       const uint32_t first_mip_pipe_misaligned = image->planes[i].first_mip_pipe_misaligned;
882 
883       if (range) {
884          if (range->baseMipLevel + range->levelCount - 1 >= first_mip_pipe_misaligned)
885             return true;
886       } else {
887          /* Be conservative when the range is unknown because it's not possible to know which mips
888           * are used.
889           */
890          if (first_mip_pipe_misaligned != UINT32_MAX)
891             return true;
892       }
893    }
894 
895    return false;
896 }
897 
898 bool
radv_image_is_l2_coherent(const struct radv_device * device,const struct radv_image * image,const VkImageSubresourceRange * range)899 radv_image_is_l2_coherent(const struct radv_device *device, const struct radv_image *image,
900                           const VkImageSubresourceRange *range)
901 {
902    const struct radv_physical_device *pdev = radv_device_physical(device);
903 
904    if (pdev->info.gfx_level >= GFX12) {
905       return true; /* Everything is coherent with TC L2. */
906    } else if (pdev->info.gfx_level >= GFX10) {
907       return !radv_image_is_pipe_misaligned(image, range);
908    } else if (pdev->info.gfx_level == GFX9) {
909       if (image->vk.samples == 1 &&
910           (image->vk.usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) &&
911           !vk_format_has_stencil(image->vk.format)) {
912          /* Single-sample color and single-sample depth
913           * (not stencil) are coherent with shaders on
914           * GFX9.
915           */
916          return true;
917       }
918    }
919 
920    return false;
921 }
922 
923 /**
924  * Determine if the given image can be fast cleared.
925  */
926 bool
radv_image_can_fast_clear(const struct radv_device * device,const struct radv_image * image)927 radv_image_can_fast_clear(const struct radv_device *device, const struct radv_image *image)
928 {
929    const struct radv_physical_device *pdev = radv_device_physical(device);
930    const struct radv_instance *instance = radv_physical_device_instance(pdev);
931 
932    if (instance->debug_flags & RADV_DEBUG_NO_FAST_CLEARS)
933       return false;
934 
935    if (vk_format_is_color(image->vk.format)) {
936       if (!radv_image_has_cmask(image) && !radv_image_has_dcc(image))
937          return false;
938 
939       /* RB+ doesn't work with CMASK fast clear on Stoney. */
940       if (!radv_image_has_dcc(image) && pdev->info.family == CHIP_STONEY)
941          return false;
942 
943       /* Fast-clears with CMASK aren't supported for 128-bit formats. */
944       if (radv_image_has_cmask(image) && vk_format_get_blocksizebits(image->vk.format) > 64)
945          return false;
946    } else {
947       if (!radv_image_has_htile(image))
948          return false;
949    }
950 
951    /* Do not fast clears 3D images. */
952    if (image->vk.image_type == VK_IMAGE_TYPE_3D)
953       return false;
954 
955    return true;
956 }
957 
958 /**
959  * Determine if the given image can be fast cleared using comp-to-single.
960  */
961 static bool
radv_image_use_comp_to_single(const struct radv_device * device,const struct radv_image * image)962 radv_image_use_comp_to_single(const struct radv_device *device, const struct radv_image *image)
963 {
964    const struct radv_physical_device *pdev = radv_device_physical(device);
965 
966    /* comp-to-single is only available for GFX10+. */
967    if (pdev->info.gfx_level < GFX10)
968       return false;
969 
970    /* If the image can't be fast cleared, comp-to-single can't be used. */
971    if (!radv_image_can_fast_clear(device, image))
972       return false;
973 
974    /* If the image doesn't have DCC, it can't be fast cleared using comp-to-single */
975    if (!radv_image_has_dcc(image))
976       return false;
977 
978    /* It seems 8bpp and 16bpp require RB+ to work. */
979    unsigned bytes_per_pixel = vk_format_get_blocksize(image->vk.format);
980    if (bytes_per_pixel <= 2 && !pdev->info.rbplus_allowed)
981       return false;
982 
983    return true;
984 }
985 
986 static unsigned
radv_get_internal_plane_count(const struct radv_physical_device * pdev,VkFormat fmt)987 radv_get_internal_plane_count(const struct radv_physical_device *pdev, VkFormat fmt)
988 {
989    if (radv_is_format_emulated(pdev, fmt))
990       return 2;
991    return vk_format_get_plane_count(fmt);
992 }
993 
994 static void
radv_image_reset_layout(const struct radv_physical_device * pdev,struct radv_image * image)995 radv_image_reset_layout(const struct radv_physical_device *pdev, struct radv_image *image)
996 {
997    image->size = 0;
998    image->alignment = 1;
999 
1000    image->tc_compatible_cmask = 0;
1001    image->fce_pred_offset = image->dcc_pred_offset = 0;
1002    image->clear_value_offset = image->tc_compat_zrange_offset = 0;
1003 
1004    unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk.format);
1005    for (unsigned i = 0; i < plane_count; ++i) {
1006       VkFormat format = radv_image_get_plane_format(pdev, image, i);
1007       if (vk_format_has_depth(format))
1008          format = vk_format_depth_only(format);
1009 
1010       uint64_t flags = image->planes[i].surface.flags;
1011       uint64_t modifier = image->planes[i].surface.modifier;
1012       memset(image->planes + i, 0, sizeof(image->planes[i]));
1013 
1014       image->planes[i].surface.flags = flags;
1015       image->planes[i].surface.modifier = modifier;
1016       image->planes[i].surface.blk_w = vk_format_get_blockwidth(format);
1017       image->planes[i].surface.blk_h = vk_format_get_blockheight(format);
1018       image->planes[i].surface.bpe = vk_format_get_blocksize(format);
1019 
1020       /* align byte per element on dword */
1021       if (image->planes[i].surface.bpe == 3) {
1022          image->planes[i].surface.bpe = 4;
1023       }
1024    }
1025 }
1026 
1027 struct ac_surf_info
radv_get_ac_surf_info(struct radv_device * device,const struct radv_image * image)1028 radv_get_ac_surf_info(struct radv_device *device, const struct radv_image *image)
1029 {
1030    struct ac_surf_info info;
1031 
1032    memset(&info, 0, sizeof(info));
1033 
1034    info.width = image->vk.extent.width;
1035    info.height = image->vk.extent.height;
1036    info.depth = image->vk.extent.depth;
1037    info.samples = image->vk.samples;
1038    info.storage_samples = image->vk.samples;
1039    info.array_size = image->vk.array_layers;
1040    info.levels = image->vk.mip_levels;
1041    info.num_channels = vk_format_get_nr_components(image->vk.format);
1042 
1043    if (!vk_format_is_depth_or_stencil(image->vk.format) && !image->shareable &&
1044        !(image->vk.create_flags & (VK_IMAGE_CREATE_SPARSE_ALIASED_BIT | VK_IMAGE_CREATE_ALIAS_BIT |
1045                                    VK_IMAGE_CREATE_DESCRIPTOR_BUFFER_CAPTURE_REPLAY_BIT_EXT)) &&
1046        image->vk.tiling != VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT) {
1047       info.surf_index = &device->image_mrt_offset_counter;
1048       info.fmask_surf_index = &device->fmask_mrt_offset_counter;
1049    }
1050 
1051    return info;
1052 }
1053 
1054 static void
radv_surface_init(struct radv_physical_device * pdev,const struct ac_surf_info * surf_info,struct radeon_surf * surf)1055 radv_surface_init(struct radv_physical_device *pdev, const struct ac_surf_info *surf_info, struct radeon_surf *surf)
1056 {
1057    uint32_t type = RADEON_SURF_GET(surf->flags, TYPE);
1058    uint32_t mode = RADEON_SURF_GET(surf->flags, MODE);
1059 
1060    struct ac_surf_config config;
1061 
1062    memcpy(&config.info, surf_info, sizeof(config.info));
1063    config.is_1d = type == RADEON_SURF_TYPE_1D || type == RADEON_SURF_TYPE_1D_ARRAY;
1064    config.is_3d = type == RADEON_SURF_TYPE_3D;
1065    config.is_cube = type == RADEON_SURF_TYPE_CUBEMAP;
1066    config.is_array = type == RADEON_SURF_TYPE_1D_ARRAY || type == RADEON_SURF_TYPE_2D_ARRAY;
1067 
1068    ac_compute_surface(pdev->addrlib, &pdev->info, &config, mode, surf);
1069 }
1070 
1071 /* Return the first mip level which is pipe-misaligned with metadata, UINT32_MAX means no mips are
1072  * affected and zero means all mips.
1073  */
1074 static uint32_t
radv_image_get_first_mip_pipe_misaligned(const struct radv_device * device,const struct radv_image * image,uint32_t plane_id)1075 radv_image_get_first_mip_pipe_misaligned(const struct radv_device *device, const struct radv_image *image,
1076                                          uint32_t plane_id)
1077 {
1078    const struct radv_physical_device *pdev = radv_device_physical(device);
1079    const int log2_samples = util_logbase2(image->vk.samples);
1080    uint32_t first_mip = UINT32_MAX;
1081 
1082    /* Add a special case for mips in the metadata mip-tail for GFX11. */
1083    if (pdev->info.gfx_level >= GFX11) {
1084       if (image->vk.mip_levels > 1 && (radv_image_has_dcc(image) || radv_image_has_htile(image))) {
1085          first_mip = image->planes[plane_id].surface.num_meta_levels;
1086       }
1087    }
1088 
1089    VkFormat fmt = radv_image_get_plane_format(pdev, image, plane_id);
1090    int log2_bpp = util_logbase2(vk_format_get_blocksize(fmt));
1091    int log2_bpp_and_samples;
1092 
1093    if (pdev->info.gfx_level >= GFX10_3) {
1094       log2_bpp_and_samples = log2_bpp + log2_samples;
1095    } else {
1096       if (vk_format_has_depth(image->vk.format) && image->vk.array_layers >= 8) {
1097          log2_bpp = 2;
1098       }
1099 
1100       log2_bpp_and_samples = MIN2(6, log2_bpp + log2_samples);
1101    }
1102 
1103    int num_pipes = G_0098F8_NUM_PIPES(pdev->info.gb_addr_config);
1104    int overlap = MAX2(0, log2_bpp_and_samples + num_pipes - 8);
1105 
1106    if (vk_format_has_depth(image->vk.format)) {
1107       if (radv_image_is_tc_compat_htile(image) && (pdev->info.tcc_rb_non_coherent || overlap)) {
1108          first_mip = 0;
1109       }
1110    } else {
1111       int max_compressed_frags = G_0098F8_MAX_COMPRESSED_FRAGS(pdev->info.gb_addr_config);
1112       int log2_samples_frag_diff = MAX2(0, log2_samples - max_compressed_frags);
1113       int samples_overlap = MIN2(log2_samples, overlap);
1114 
1115       /* TODO: It shouldn't be necessary if the image has DCC but
1116        * not readable by shader.
1117        */
1118       if ((radv_image_has_dcc(image) || radv_image_is_tc_compat_cmask(image)) &&
1119           (pdev->info.tcc_rb_non_coherent || (samples_overlap > log2_samples_frag_diff))) {
1120          first_mip = 0;
1121       }
1122    }
1123 
1124    return first_mip;
1125 }
1126 
1127 static void
radv_image_init_first_mip_pipe_misaligned(const struct radv_device * device,struct radv_image * image)1128 radv_image_init_first_mip_pipe_misaligned(const struct radv_device *device, struct radv_image *image)
1129 {
1130    for (uint32_t i = 0; i < image->plane_count; i++) {
1131       image->planes[i].first_mip_pipe_misaligned = radv_image_get_first_mip_pipe_misaligned(device, image, i);
1132    }
1133 }
1134 
1135 VkResult
radv_image_create_layout(struct radv_device * device,struct radv_image_create_info create_info,const struct VkImageDrmFormatModifierExplicitCreateInfoEXT * mod_info,const struct VkVideoProfileListInfoKHR * profile_list,struct radv_image * image)1136 radv_image_create_layout(struct radv_device *device, struct radv_image_create_info create_info,
1137                          const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *mod_info,
1138                          const struct VkVideoProfileListInfoKHR *profile_list, struct radv_image *image)
1139 {
1140    struct radv_physical_device *pdev = radv_device_physical(device);
1141 
1142    /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
1143     * common internal case. */
1144    create_info.vk_info = NULL;
1145 
1146    struct ac_surf_info image_info = radv_get_ac_surf_info(device, image);
1147    VkResult result = radv_patch_image_from_extra_info(device, image, &create_info, &image_info);
1148    if (result != VK_SUCCESS)
1149       return result;
1150 
1151    assert(!mod_info || mod_info->drmFormatModifierPlaneCount >= image->plane_count);
1152 
1153    radv_image_reset_layout(pdev, image);
1154 
1155    /*
1156     * Due to how the decoder works, the user can't supply an oversized image, because if it attempts
1157     * to sample it later with a linear filter, it will get garbage after the height it wants,
1158     * so we let the user specify the width/height unaligned, and align them preallocation.
1159     */
1160    if (image->vk.usage & (VK_IMAGE_USAGE_VIDEO_DECODE_DST_BIT_KHR |
1161                           VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR |
1162                           VK_IMAGE_USAGE_VIDEO_ENCODE_DPB_BIT_KHR)) {
1163       if (!device->vk.enabled_features.videoMaintenance1)
1164          assert(profile_list);
1165       uint32_t width_align, height_align;
1166       radv_video_get_profile_alignments(pdev, profile_list, &width_align, &height_align);
1167       image_info.width = align(image_info.width, width_align);
1168       image_info.height = align(image_info.height, height_align);
1169 
1170       if (radv_has_uvd(pdev) && image->vk.usage & VK_IMAGE_USAGE_VIDEO_DECODE_DPB_BIT_KHR) {
1171          /* UVD and kernel demand a full DPB allocation. */
1172          image_info.array_size = MIN2(16, image_info.array_size);
1173       }
1174    }
1175 
1176    unsigned plane_count = radv_get_internal_plane_count(pdev, image->vk.format);
1177    for (unsigned plane = 0; plane < plane_count; ++plane) {
1178       struct ac_surf_info info = image_info;
1179       uint64_t offset;
1180       unsigned stride;
1181 
1182       info.width = vk_format_get_plane_width(image->vk.format, plane, info.width);
1183       info.height = vk_format_get_plane_height(image->vk.format, plane, info.height);
1184 
1185       if (create_info.no_metadata_planes || plane_count > 1) {
1186          image->planes[plane].surface.flags |= RADEON_SURF_DISABLE_DCC | RADEON_SURF_NO_FMASK | RADEON_SURF_NO_HTILE;
1187       }
1188 
1189       radv_surface_init(pdev, &info, &image->planes[plane].surface);
1190 
1191       if (plane == 0) {
1192          if (!radv_use_dcc_for_image_late(device, image))
1193             ac_surface_zero_dcc_fields(&image->planes[0].surface);
1194       }
1195 
1196       if (create_info.bo_metadata && !mod_info &&
1197           !ac_surface_apply_umd_metadata(&pdev->info, &image->planes[plane].surface, image->vk.samples,
1198                                          image->vk.mip_levels, create_info.bo_metadata->size_metadata,
1199                                          create_info.bo_metadata->metadata))
1200          return VK_ERROR_INVALID_EXTERNAL_HANDLE;
1201 
1202       if (!create_info.no_metadata_planes && !create_info.bo_metadata && plane_count == 1 && !mod_info)
1203          radv_image_alloc_single_sample_cmask(device, image, &image->planes[plane].surface);
1204 
1205       if (mod_info) {
1206          if (mod_info->pPlaneLayouts[plane].rowPitch % image->planes[plane].surface.bpe ||
1207              !mod_info->pPlaneLayouts[plane].rowPitch)
1208             return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1209 
1210          offset = mod_info->pPlaneLayouts[plane].offset;
1211          stride = mod_info->pPlaneLayouts[plane].rowPitch / image->planes[plane].surface.bpe;
1212       } else {
1213          offset = image->disjoint ? 0 : align64(image->size, 1ull << image->planes[plane].surface.alignment_log2);
1214          stride = 0; /* 0 means no override */
1215       }
1216 
1217       if (!ac_surface_override_offset_stride(&pdev->info, &image->planes[plane].surface, image->vk.array_layers,
1218                                              image->vk.mip_levels, offset, stride))
1219          return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1220 
1221       /* Validate DCC offsets in modifier layout. */
1222       if (plane_count == 1 && mod_info) {
1223          unsigned mem_planes = ac_surface_get_nplanes(&image->planes[plane].surface);
1224          if (mod_info->drmFormatModifierPlaneCount != mem_planes)
1225             return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1226 
1227          for (unsigned i = 1; i < mem_planes; ++i) {
1228             if (ac_surface_get_plane_offset(pdev->info.gfx_level, &image->planes[plane].surface, i, 0) !=
1229                 mod_info->pPlaneLayouts[i].offset)
1230                return VK_ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT;
1231          }
1232       }
1233 
1234       image->size = MAX2(image->size, offset + image->planes[plane].surface.total_size);
1235       image->alignment = MAX2(image->alignment, 1 << image->planes[plane].surface.alignment_log2);
1236 
1237       image->planes[plane].format = radv_image_get_plane_format(pdev, image, plane);
1238    }
1239 
1240    image->tc_compatible_cmask = radv_image_has_cmask(image) && radv_use_tc_compat_cmask_for_image(device, image);
1241 
1242    if (pdev->info.gfx_level >= GFX10 && pdev->info.gfx_level < GFX12)
1243       radv_image_init_first_mip_pipe_misaligned(device, image);
1244 
1245    image->support_comp_to_single = radv_image_use_comp_to_single(device, image);
1246 
1247    radv_image_alloc_values(device, image);
1248 
1249    assert(image->planes[0].surface.surf_size);
1250    assert(image->planes[0].surface.modifier == DRM_FORMAT_MOD_INVALID ||
1251           ac_modifier_has_dcc(image->planes[0].surface.modifier) == radv_image_has_dcc(image));
1252    return VK_SUCCESS;
1253 }
1254 
1255 static void
radv_destroy_image(struct radv_device * device,const VkAllocationCallbacks * pAllocator,struct radv_image * image)1256 radv_destroy_image(struct radv_device *device, const VkAllocationCallbacks *pAllocator, struct radv_image *image)
1257 {
1258    struct radv_physical_device *pdev = radv_device_physical(device);
1259    struct radv_instance *instance = radv_physical_device_instance(pdev);
1260 
1261    if ((image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && image->bindings[0].bo)
1262       radv_bo_destroy(device, &image->vk.base, image->bindings[0].bo);
1263 
1264    if (image->owned_memory != VK_NULL_HANDLE) {
1265       VK_FROM_HANDLE(radv_device_memory, mem, image->owned_memory);
1266       radv_free_memory(device, pAllocator, mem);
1267    }
1268 
1269    for (uint32_t i = 0; i < ARRAY_SIZE(image->bindings); i++) {
1270       if (!image->bindings[i].bo_va)
1271          continue;
1272 
1273       vk_address_binding_report(&instance->vk, &image->vk.base, image->bindings[i].bo_va + image->bindings[i].offset,
1274                                 image->bindings[i].range, VK_DEVICE_ADDRESS_BINDING_TYPE_UNBIND_EXT);
1275    }
1276 
1277    radv_rmv_log_resource_destroy(device, (uint64_t)radv_image_to_handle(image));
1278    vk_image_finish(&image->vk);
1279    vk_free2(&device->vk.alloc, pAllocator, image);
1280 }
1281 
1282 static void
radv_image_print_info(struct radv_device * device,struct radv_image * image)1283 radv_image_print_info(struct radv_device *device, struct radv_image *image)
1284 {
1285    const struct radv_physical_device *pdev = radv_device_physical(device);
1286 
1287    fprintf(stderr, "Image:\n");
1288    fprintf(stderr,
1289            "  Info: size=%" PRIu64 ", alignment=%" PRIu32 ", "
1290            "width=%" PRIu32 ", height=%" PRIu32 ", depth=%" PRIu32 ", "
1291            "array_size=%" PRIu32 ", levels=%" PRIu32 "\n",
1292            image->size, image->alignment, image->vk.extent.width, image->vk.extent.height, image->vk.extent.depth,
1293            image->vk.array_layers, image->vk.mip_levels);
1294    for (unsigned i = 0; i < image->plane_count; ++i) {
1295       const struct radv_image_plane *plane = &image->planes[i];
1296       const struct radeon_surf *surf = &plane->surface;
1297       const struct util_format_description *desc = vk_format_description(plane->format);
1298       uint64_t offset = ac_surface_get_plane_offset(pdev->info.gfx_level, &plane->surface, 0, 0);
1299 
1300       fprintf(stderr, "  Plane[%u]: vkformat=%s, offset=%" PRIu64 "\n", i, desc->name, offset);
1301 
1302       ac_surface_print_info(stderr, &pdev->info, surf);
1303    }
1304 }
1305 
1306 static uint64_t
radv_select_modifier(const struct radv_device * dev,VkFormat format,const struct VkImageDrmFormatModifierListCreateInfoEXT * mod_list)1307 radv_select_modifier(const struct radv_device *dev, VkFormat format,
1308                      const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list)
1309 {
1310    const struct radv_physical_device *pdev = radv_device_physical(dev);
1311    unsigned mod_count;
1312 
1313    assert(mod_list->drmFormatModifierCount);
1314 
1315    /* We can allow everything here as it does not affect order and the application
1316     * is only allowed to specify modifiers that we support. */
1317    const struct ac_modifier_options modifier_options = {
1318       .dcc = true,
1319       .dcc_retile = true,
1320    };
1321 
1322    ac_get_supported_modifiers(&pdev->info, &modifier_options, radv_format_to_pipe_format(format), &mod_count, NULL);
1323 
1324    uint64_t *mods = calloc(mod_count, sizeof(*mods));
1325 
1326    /* If allocations fail, fall back to a dumber solution. */
1327    if (!mods)
1328       return mod_list->pDrmFormatModifiers[0];
1329 
1330    ac_get_supported_modifiers(&pdev->info, &modifier_options, radv_format_to_pipe_format(format), &mod_count, mods);
1331 
1332    for (unsigned i = 0; i < mod_count; ++i) {
1333       for (uint32_t j = 0; j < mod_list->drmFormatModifierCount; ++j) {
1334          if (mods[i] == mod_list->pDrmFormatModifiers[j]) {
1335             free(mods);
1336             return mod_list->pDrmFormatModifiers[j];
1337          }
1338       }
1339    }
1340    unreachable("App specified an invalid modifier");
1341 }
1342 
1343 VkResult
radv_image_create(VkDevice _device,const struct radv_image_create_info * create_info,const VkAllocationCallbacks * alloc,VkImage * pImage,bool is_internal)1344 radv_image_create(VkDevice _device, const struct radv_image_create_info *create_info,
1345                   const VkAllocationCallbacks *alloc, VkImage *pImage, bool is_internal)
1346 {
1347    VK_FROM_HANDLE(radv_device, device, _device);
1348    const struct radv_physical_device *pdev = radv_device_physical(device);
1349    const struct radv_instance *instance = radv_physical_device_instance(pdev);
1350    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
1351    uint64_t modifier = DRM_FORMAT_MOD_INVALID;
1352    struct radv_image *image = NULL;
1353    VkFormat format = radv_select_android_external_format(pCreateInfo->pNext, pCreateInfo->format);
1354    const struct VkImageDrmFormatModifierListCreateInfoEXT *mod_list =
1355       vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_LIST_CREATE_INFO_EXT);
1356    const struct VkImageDrmFormatModifierExplicitCreateInfoEXT *explicit_mod =
1357       vk_find_struct_const(pCreateInfo->pNext, IMAGE_DRM_FORMAT_MODIFIER_EXPLICIT_CREATE_INFO_EXT);
1358    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
1359    const struct VkVideoProfileListInfoKHR *profile_list =
1360       vk_find_struct_const(pCreateInfo->pNext, VIDEO_PROFILE_LIST_INFO_KHR);
1361 
1362    unsigned plane_count = radv_get_internal_plane_count(pdev, format);
1363 
1364    const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
1365 
1366    image = vk_zalloc2(&device->vk.alloc, alloc, image_struct_size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1367    if (!image)
1368       return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY);
1369 
1370    vk_image_init(&device->vk, &image->vk, pCreateInfo);
1371 
1372    image->plane_count = vk_format_get_plane_count(format);
1373    image->disjoint = image->plane_count > 1 && pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
1374 
1375    image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
1376    if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
1377       for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
1378          if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL ||
1379              pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT)
1380             image->queue_family_mask |= (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
1381          else
1382             image->queue_family_mask |= 1u << vk_queue_to_radv(pdev, pCreateInfo->pQueueFamilyIndices[i]);
1383 
1384       /* This queue never really accesses the image. */
1385       image->queue_family_mask &= ~(1u << RADV_QUEUE_SPARSE);
1386    }
1387 
1388    const VkExternalMemoryImageCreateInfo *external_info =
1389       vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
1390 
1391    image->shareable = external_info;
1392 
1393    if (mod_list)
1394       modifier = radv_select_modifier(device, format, mod_list);
1395    else if (explicit_mod)
1396       modifier = explicit_mod->drmFormatModifier;
1397 
1398    for (unsigned plane = 0; plane < plane_count; ++plane) {
1399       image->planes[plane].surface.flags = radv_get_surface_flags(device, image, plane, pCreateInfo, format);
1400       image->planes[plane].surface.modifier = modifier;
1401    }
1402 
1403    if (image->vk.external_handle_types & VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID) {
1404 #if DETECT_OS_ANDROID
1405       image->vk.ahb_format = radv_ahb_format_for_vk_format(image->vk.format);
1406 #endif
1407 
1408       *pImage = radv_image_to_handle(image);
1409       assert(!(image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT));
1410       return VK_SUCCESS;
1411    }
1412 
1413    VkResult result = radv_image_create_layout(device, *create_info, explicit_mod, profile_list, image);
1414    if (result != VK_SUCCESS) {
1415       radv_destroy_image(device, alloc, image);
1416       return result;
1417    }
1418 
1419    if (image->vk.create_flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1420       image->alignment = MAX2(image->alignment, 4096);
1421       image->size = align64(image->size, image->alignment);
1422       image->bindings[0].offset = 0;
1423 
1424       result = radv_bo_create(device, &image->vk.base, image->size, image->alignment, 0, RADEON_FLAG_VIRTUAL,
1425                               RADV_BO_PRIORITY_VIRTUAL, 0, true, &image->bindings[0].bo);
1426       if (result != VK_SUCCESS) {
1427          radv_destroy_image(device, alloc, image);
1428          return vk_error(device, result);
1429       }
1430    }
1431 
1432    if (instance->debug_flags & RADV_DEBUG_IMG) {
1433       radv_image_print_info(device, image);
1434    }
1435 
1436    *pImage = radv_image_to_handle(image);
1437 
1438    radv_rmv_log_image_create(device, pCreateInfo, is_internal, *pImage);
1439    if (image->bindings[0].bo)
1440       radv_rmv_log_image_bind(device, 0, *pImage);
1441    return VK_SUCCESS;
1442 }
1443 
1444 unsigned
radv_plane_from_aspect(VkImageAspectFlags mask)1445 radv_plane_from_aspect(VkImageAspectFlags mask)
1446 {
1447    switch (mask) {
1448    case VK_IMAGE_ASPECT_PLANE_1_BIT:
1449    case VK_IMAGE_ASPECT_MEMORY_PLANE_1_BIT_EXT:
1450       return 1;
1451    case VK_IMAGE_ASPECT_PLANE_2_BIT:
1452    case VK_IMAGE_ASPECT_MEMORY_PLANE_2_BIT_EXT:
1453       return 2;
1454    case VK_IMAGE_ASPECT_MEMORY_PLANE_3_BIT_EXT:
1455       return 3;
1456    default:
1457       return 0;
1458    }
1459 }
1460 
1461 VkFormat
radv_get_aspect_format(struct radv_image * image,VkImageAspectFlags mask)1462 radv_get_aspect_format(struct radv_image *image, VkImageAspectFlags mask)
1463 {
1464    switch (mask) {
1465    case VK_IMAGE_ASPECT_PLANE_0_BIT:
1466       return image->planes[0].format;
1467    case VK_IMAGE_ASPECT_PLANE_1_BIT:
1468       return image->planes[1].format;
1469    case VK_IMAGE_ASPECT_PLANE_2_BIT:
1470       return image->planes[2].format;
1471    case VK_IMAGE_ASPECT_STENCIL_BIT:
1472       return vk_format_stencil_only(image->vk.format);
1473    case VK_IMAGE_ASPECT_DEPTH_BIT:
1474       return vk_format_depth_only(image->vk.format);
1475    case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
1476       return vk_format_depth_only(image->vk.format);
1477    default:
1478       return image->vk.format;
1479    }
1480 }
1481 
1482 bool
radv_layout_is_htile_compressed(const struct radv_device * device,const struct radv_image * image,VkImageLayout layout,unsigned queue_mask)1483 radv_layout_is_htile_compressed(const struct radv_device *device, const struct radv_image *image, VkImageLayout layout,
1484                                 unsigned queue_mask)
1485 {
1486    const struct radv_physical_device *pdev = radv_device_physical(device);
1487    const struct radv_instance *instance = radv_physical_device_instance(pdev);
1488 
1489    /* Don't compress exclusive images used on transfer queues when SDMA doesn't support HTILE.
1490     * Note that HTILE is already disabled on concurrent images when not supported.
1491     */
1492    if (queue_mask == BITFIELD_BIT(RADV_QUEUE_TRANSFER) && !pdev->info.sdma_supports_compression)
1493       return false;
1494 
1495    switch (layout) {
1496    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
1497    case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
1498    case VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL:
1499    case VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL:
1500       return radv_image_has_htile(image);
1501    case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
1502       return radv_image_is_tc_compat_htile(image) ||
1503              (radv_image_has_htile(image) && queue_mask == (1u << RADV_QUEUE_GENERAL));
1504    case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
1505    case VK_IMAGE_LAYOUT_GENERAL:
1506       /* It should be safe to enable TC-compat HTILE with
1507        * VK_IMAGE_LAYOUT_GENERAL if we are not in a render loop and
1508        * if the image doesn't have the storage bit set. This
1509        * improves performance for apps that use GENERAL for the main
1510        * depth pass because this allows compression and this reduces
1511        * the number of decompressions from/to GENERAL.
1512        */
1513       if (radv_image_is_tc_compat_htile(image) && queue_mask & (1u << RADV_QUEUE_GENERAL) &&
1514           !instance->drirc.disable_tc_compat_htile_in_general) {
1515          return true;
1516       } else {
1517          return false;
1518       }
1519    case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
1520       /* Do not compress HTILE with feedback loops because we can't read&write it without
1521        * introducing corruption.
1522        */
1523       return false;
1524    case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
1525    case VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL:
1526       if (radv_image_is_tc_compat_htile(image) ||
1527           (radv_image_has_htile(image) &&
1528            !(image->vk.usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)))) {
1529          /* Keep HTILE compressed if the image is only going to
1530           * be used as a depth/stencil read-only attachment.
1531           */
1532          return true;
1533       } else {
1534          return false;
1535       }
1536       break;
1537    default:
1538       return radv_image_is_tc_compat_htile(image);
1539    }
1540 }
1541 
1542 bool
radv_layout_can_fast_clear(const struct radv_device * device,const struct radv_image * image,unsigned level,VkImageLayout layout,unsigned queue_mask)1543 radv_layout_can_fast_clear(const struct radv_device *device, const struct radv_image *image, unsigned level,
1544                            VkImageLayout layout, unsigned queue_mask)
1545 {
1546    if (radv_dcc_enabled(image, level) && !radv_layout_dcc_compressed(device, image, level, layout, queue_mask))
1547       return false;
1548 
1549    if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS))
1550       return false;
1551 
1552    if (layout != VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL && layout != VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL)
1553       return false;
1554 
1555    /* Exclusive images with CMASK or DCC can always be fast-cleared on the gfx queue. Concurrent
1556     * images can only be fast-cleared if comp-to-single is supported because we don't yet support
1557     * FCE on the compute queue.
1558     */
1559    return queue_mask == (1u << RADV_QUEUE_GENERAL) || radv_image_use_comp_to_single(device, image);
1560 }
1561 
1562 bool
radv_layout_dcc_compressed(const struct radv_device * device,const struct radv_image * image,unsigned level,VkImageLayout layout,unsigned queue_mask)1563 radv_layout_dcc_compressed(const struct radv_device *device, const struct radv_image *image, unsigned level,
1564                            VkImageLayout layout, unsigned queue_mask)
1565 {
1566    const struct radv_physical_device *pdev = radv_device_physical(device);
1567 
1568    if (!radv_dcc_enabled(image, level))
1569       return false;
1570 
1571    if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && queue_mask & (1u << RADV_QUEUE_FOREIGN))
1572       return true;
1573 
1574    /* If the image is read-only, we can always just keep it compressed */
1575    if (!(image->vk.usage & RADV_IMAGE_USAGE_WRITE_BITS))
1576       return true;
1577 
1578    /* Don't compress compute transfer dst when image stores are not supported. */
1579    if ((layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL || layout == VK_IMAGE_LAYOUT_GENERAL) &&
1580        (queue_mask & (1u << RADV_QUEUE_COMPUTE)) && !radv_image_use_dcc_image_stores(device, image))
1581       return false;
1582 
1583    /* Don't compress exclusive images used on transfer queues when SDMA doesn't support DCC.
1584     * Note that DCC is already disabled on concurrent images when not supported.
1585     */
1586    if (queue_mask == BITFIELD_BIT(RADV_QUEUE_TRANSFER) && !pdev->info.sdma_supports_compression)
1587       return false;
1588 
1589    if (layout == VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT) {
1590       /* Do not compress DCC with feedback loops because we can't read&write it without introducing
1591        * corruption.
1592        */
1593       return false;
1594    }
1595 
1596    return pdev->info.gfx_level >= GFX10 || layout != VK_IMAGE_LAYOUT_GENERAL;
1597 }
1598 
1599 enum radv_fmask_compression
radv_layout_fmask_compression(const struct radv_device * device,const struct radv_image * image,VkImageLayout layout,unsigned queue_mask)1600 radv_layout_fmask_compression(const struct radv_device *device, const struct radv_image *image, VkImageLayout layout,
1601                               unsigned queue_mask)
1602 {
1603    if (!radv_image_has_fmask(image))
1604       return RADV_FMASK_COMPRESSION_NONE;
1605 
1606    if (layout == VK_IMAGE_LAYOUT_GENERAL)
1607       return RADV_FMASK_COMPRESSION_NONE;
1608 
1609    /* Don't compress compute transfer dst because image stores ignore FMASK and it needs to be
1610     * expanded before.
1611     */
1612    if (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL && (queue_mask & (1u << RADV_QUEUE_COMPUTE)))
1613       return RADV_FMASK_COMPRESSION_NONE;
1614 
1615    /* Compress images if TC-compat CMASK is enabled. */
1616    if (radv_image_is_tc_compat_cmask(image))
1617       return RADV_FMASK_COMPRESSION_FULL;
1618 
1619    switch (layout) {
1620    case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
1621    case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
1622       /* Don't compress images but no need to expand FMASK. */
1623       return RADV_FMASK_COMPRESSION_PARTIAL;
1624    case VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT:
1625       /* Don't compress images that are in feedback loops. */
1626       return RADV_FMASK_COMPRESSION_NONE;
1627    default:
1628       /* Don't compress images that are concurrent. */
1629       return queue_mask == (1u << RADV_QUEUE_GENERAL) ? RADV_FMASK_COMPRESSION_FULL : RADV_FMASK_COMPRESSION_NONE;
1630    }
1631 }
1632 
1633 unsigned
radv_image_queue_family_mask(const struct radv_image * image,enum radv_queue_family family,enum radv_queue_family queue_family)1634 radv_image_queue_family_mask(const struct radv_image *image, enum radv_queue_family family,
1635                              enum radv_queue_family queue_family)
1636 {
1637    if (!image->exclusive)
1638       return image->queue_family_mask;
1639    if (family == RADV_QUEUE_FOREIGN)
1640       return ((1u << RADV_MAX_QUEUE_FAMILIES) - 1u) | (1u << RADV_QUEUE_FOREIGN);
1641    if (family == RADV_QUEUE_IGNORED)
1642       return 1u << queue_family;
1643    return 1u << family;
1644 }
1645 
1646 bool
radv_image_is_renderable(const struct radv_device * device,const struct radv_image * image)1647 radv_image_is_renderable(const struct radv_device *device, const struct radv_image *image)
1648 {
1649    const struct radv_physical_device *pdev = radv_device_physical(device);
1650 
1651    if (image->vk.format == VK_FORMAT_R32G32B32_UINT || image->vk.format == VK_FORMAT_R32G32B32_SINT ||
1652        image->vk.format == VK_FORMAT_R32G32B32_SFLOAT)
1653       return false;
1654 
1655    if (pdev->info.gfx_level >= GFX9 && image->vk.image_type == VK_IMAGE_TYPE_3D &&
1656        vk_format_get_blocksizebits(image->vk.format) == 128 && vk_format_is_compressed(image->vk.format))
1657       return false;
1658 
1659    if (image->planes[0].surface.flags & RADEON_SURF_NO_RENDER_TARGET)
1660       return false;
1661 
1662    return true;
1663 }
1664 
1665 VKAPI_ATTR VkResult VKAPI_CALL
radv_CreateImage(VkDevice _device,const VkImageCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkImage * pImage)1666 radv_CreateImage(VkDevice _device, const VkImageCreateInfo *pCreateInfo, const VkAllocationCallbacks *pAllocator,
1667                  VkImage *pImage)
1668 {
1669 #if DETECT_OS_ANDROID
1670    const VkNativeBufferANDROID *gralloc_info = vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
1671 
1672    if (gralloc_info)
1673       return radv_image_from_gralloc(_device, pCreateInfo, gralloc_info, pAllocator, pImage);
1674 #endif
1675 
1676 #ifdef RADV_USE_WSI_PLATFORM
1677    /* Ignore swapchain creation info on Android. Since we don't have an implementation in Mesa,
1678     * we're guaranteed to access an Android object incorrectly.
1679     */
1680    VK_FROM_HANDLE(radv_device, device, _device);
1681    const struct radv_physical_device *pdev = radv_device_physical(device);
1682    const VkImageSwapchainCreateInfoKHR *swapchain_info =
1683       vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
1684    if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) {
1685       return wsi_common_create_swapchain_image(pdev->vk.wsi_device, pCreateInfo, swapchain_info->swapchain, pImage);
1686    }
1687 #endif
1688 
1689    const struct wsi_image_create_info *wsi_info = vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
1690    bool scanout = wsi_info && wsi_info->scanout;
1691    bool prime_blit_src = wsi_info && wsi_info->blit_src;
1692 
1693    return radv_image_create(_device,
1694                             &(struct radv_image_create_info){
1695                                .vk_info = pCreateInfo,
1696                                .scanout = scanout,
1697                                .prime_blit_src = prime_blit_src,
1698                             },
1699                             pAllocator, pImage, false);
1700 }
1701 
1702 VKAPI_ATTR void VKAPI_CALL
radv_DestroyImage(VkDevice _device,VkImage _image,const VkAllocationCallbacks * pAllocator)1703 radv_DestroyImage(VkDevice _device, VkImage _image, const VkAllocationCallbacks *pAllocator)
1704 {
1705    VK_FROM_HANDLE(radv_device, device, _device);
1706    VK_FROM_HANDLE(radv_image, image, _image);
1707 
1708    if (!image)
1709       return;
1710 
1711    radv_destroy_image(device, pAllocator, image);
1712 }
1713 
1714 static void
radv_bind_image_memory(struct radv_device * device,struct radv_image * image,uint32_t bind_idx,struct radeon_winsys_bo * bo,uint64_t offset,uint64_t range)1715 radv_bind_image_memory(struct radv_device *device, struct radv_image *image, uint32_t bind_idx,
1716                        struct radeon_winsys_bo *bo, uint64_t offset, uint64_t range)
1717 {
1718    struct radv_physical_device *pdev = radv_device_physical(device);
1719    struct radv_instance *instance = radv_physical_device_instance(pdev);
1720 
1721    assert(bind_idx < 3);
1722 
1723    image->bindings[bind_idx].bo = bo;
1724    image->bindings[bind_idx].offset = offset;
1725    image->bindings[bind_idx].bo_va = radv_buffer_get_va(bo);
1726    image->bindings[bind_idx].range = range;
1727 
1728    radv_rmv_log_image_bind(device, bind_idx, radv_image_to_handle(image));
1729 
1730    vk_address_binding_report(&instance->vk, &image->vk.base,
1731                              image->bindings[bind_idx].bo_va + image->bindings[bind_idx].offset,
1732                              image->bindings[bind_idx].range, VK_DEVICE_ADDRESS_BINDING_TYPE_BIND_EXT);
1733 }
1734 
1735 VKAPI_ATTR VkResult VKAPI_CALL
radv_BindImageMemory2(VkDevice _device,uint32_t bindInfoCount,const VkBindImageMemoryInfo * pBindInfos)1736 radv_BindImageMemory2(VkDevice _device, uint32_t bindInfoCount, const VkBindImageMemoryInfo *pBindInfos)
1737 {
1738    VK_FROM_HANDLE(radv_device, device, _device);
1739 
1740    for (uint32_t i = 0; i < bindInfoCount; ++i) {
1741       VK_FROM_HANDLE(radv_device_memory, mem, pBindInfos[i].memory);
1742       VK_FROM_HANDLE(radv_image, image, pBindInfos[i].image);
1743       VkBindMemoryStatus *status = (void *)vk_find_struct_const(&pBindInfos[i], BIND_MEMORY_STATUS);
1744 
1745       if (status)
1746          *status->pResult = VK_SUCCESS;
1747 
1748          /* Ignore this struct on Android, we cannot access swapchain structures there. */
1749 #ifdef RADV_USE_WSI_PLATFORM
1750       const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
1751          vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR);
1752 
1753       if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE) {
1754          struct radv_image *swapchain_img =
1755             radv_image_from_handle(wsi_common_get_image(swapchain_info->swapchain, swapchain_info->imageIndex));
1756 
1757          radv_bind_image_memory(device, image, 0,
1758                                 swapchain_img->bindings[0].bo, swapchain_img->bindings[0].offset,
1759                                 swapchain_img->bindings[0].range);
1760          continue;
1761       }
1762 #endif
1763 
1764       const VkBindImagePlaneMemoryInfo *plane_info = NULL;
1765       uint32_t bind_idx = 0;
1766 
1767       if (image->disjoint) {
1768          plane_info = vk_find_struct_const(pBindInfos[i].pNext, BIND_IMAGE_PLANE_MEMORY_INFO);
1769          bind_idx = radv_plane_from_aspect(plane_info->planeAspect);
1770       }
1771 
1772       VkImagePlaneMemoryRequirementsInfo plane = {
1773          .sType = VK_STRUCTURE_TYPE_IMAGE_PLANE_MEMORY_REQUIREMENTS_INFO,
1774          .planeAspect = plane_info ? plane_info->planeAspect : 0,
1775       };
1776       VkImageMemoryRequirementsInfo2 info = {
1777          .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_REQUIREMENTS_INFO_2,
1778          .pNext = image->disjoint ? &plane : NULL,
1779          .image = pBindInfos[i].image,
1780       };
1781       VkMemoryRequirements2 reqs = {
1782          .sType = VK_STRUCTURE_TYPE_MEMORY_REQUIREMENTS_2,
1783       };
1784 
1785       radv_GetImageMemoryRequirements2(_device, &info, &reqs);
1786 
1787       if (mem->alloc_size) {
1788          if (pBindInfos[i].memoryOffset + reqs.memoryRequirements.size > mem->alloc_size) {
1789             if (status)
1790                *status->pResult = VK_ERROR_UNKNOWN;
1791             return vk_errorf(device, VK_ERROR_UNKNOWN, "Device memory object too small for the image.\n");
1792          }
1793       }
1794 
1795       radv_bind_image_memory(device, image, bind_idx, mem->bo, pBindInfos[i].memoryOffset,
1796                              reqs.memoryRequirements.size);
1797    }
1798    return VK_SUCCESS;
1799 }
1800 
1801 VKAPI_ATTR void VKAPI_CALL
radv_GetImageSubresourceLayout2(VkDevice _device,VkImage _image,const VkImageSubresource2 * pSubresource,VkSubresourceLayout2 * pLayout)1802 radv_GetImageSubresourceLayout2(VkDevice _device, VkImage _image, const VkImageSubresource2 *pSubresource,
1803                                 VkSubresourceLayout2 *pLayout)
1804 {
1805    VK_FROM_HANDLE(radv_image, image, _image);
1806    VK_FROM_HANDLE(radv_device, device, _device);
1807    const struct radv_physical_device *pdev = radv_device_physical(device);
1808    int level = pSubresource->imageSubresource.mipLevel;
1809    int layer = pSubresource->imageSubresource.arrayLayer;
1810 
1811    const unsigned plane_count = vk_format_get_plane_count(image->vk.format);
1812    unsigned plane_id = 0;
1813    if (plane_count > 1)
1814       plane_id = radv_plane_from_aspect(pSubresource->imageSubresource.aspectMask);
1815 
1816    struct radv_image_plane *plane = &image->planes[plane_id];
1817    struct radeon_surf *surface = &plane->surface;
1818 
1819    if (image->vk.tiling == VK_IMAGE_TILING_DRM_FORMAT_MODIFIER_EXT && plane_count == 1) {
1820       unsigned mem_plane_id = radv_plane_from_aspect(pSubresource->imageSubresource.aspectMask);
1821 
1822       assert(level == 0);
1823       assert(layer == 0);
1824 
1825       pLayout->subresourceLayout.offset = ac_surface_get_plane_offset(pdev->info.gfx_level, surface, mem_plane_id, 0);
1826       pLayout->subresourceLayout.rowPitch =
1827          ac_surface_get_plane_stride(pdev->info.gfx_level, surface, mem_plane_id, level);
1828       pLayout->subresourceLayout.arrayPitch = 0;
1829       pLayout->subresourceLayout.depthPitch = 0;
1830       pLayout->subresourceLayout.size = ac_surface_get_plane_size(surface, mem_plane_id);
1831    } else if (pdev->info.gfx_level >= GFX9) {
1832       uint64_t level_offset = surface->is_linear ? surface->u.gfx9.offset[level] : 0;
1833 
1834       pLayout->subresourceLayout.offset =
1835          ac_surface_get_plane_offset(pdev->info.gfx_level, &plane->surface, 0, layer) + level_offset;
1836       if (image->vk.format == VK_FORMAT_R32G32B32_UINT || image->vk.format == VK_FORMAT_R32G32B32_SINT ||
1837           image->vk.format == VK_FORMAT_R32G32B32_SFLOAT) {
1838          /* Adjust the number of bytes between each row because
1839           * the pitch is actually the number of components per
1840           * row.
1841           */
1842          pLayout->subresourceLayout.rowPitch = surface->u.gfx9.surf_pitch * surface->bpe / 3;
1843       } else {
1844          uint32_t pitch = surface->is_linear ? surface->u.gfx9.pitch[level] : surface->u.gfx9.surf_pitch;
1845 
1846          assert(util_is_power_of_two_nonzero(surface->bpe));
1847          pLayout->subresourceLayout.rowPitch = pitch * surface->bpe;
1848       }
1849 
1850       pLayout->subresourceLayout.arrayPitch = surface->u.gfx9.surf_slice_size;
1851       pLayout->subresourceLayout.depthPitch = surface->u.gfx9.surf_slice_size;
1852       pLayout->subresourceLayout.size = surface->u.gfx9.surf_slice_size;
1853       if (image->vk.image_type == VK_IMAGE_TYPE_3D)
1854          pLayout->subresourceLayout.size *= u_minify(image->vk.extent.depth, level);
1855    } else {
1856       pLayout->subresourceLayout.offset = (uint64_t)surface->u.legacy.level[level].offset_256B * 256 +
1857                                           (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer;
1858       pLayout->subresourceLayout.rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
1859       pLayout->subresourceLayout.arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1860       pLayout->subresourceLayout.depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1861       pLayout->subresourceLayout.size = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1862       if (image->vk.image_type == VK_IMAGE_TYPE_3D)
1863          pLayout->subresourceLayout.size *= u_minify(image->vk.extent.depth, level);
1864    }
1865 
1866    VkImageCompressionPropertiesEXT *image_compression_props =
1867       vk_find_struct(pLayout->pNext, IMAGE_COMPRESSION_PROPERTIES_EXT);
1868    if (image_compression_props) {
1869       image_compression_props->imageCompressionFixedRateFlags = VK_IMAGE_COMPRESSION_FIXED_RATE_NONE_EXT;
1870 
1871       if (image->vk.aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1872          image_compression_props->imageCompressionFlags =
1873             radv_image_has_htile(image) ? VK_IMAGE_COMPRESSION_DEFAULT_EXT : VK_IMAGE_COMPRESSION_DISABLED_EXT;
1874       } else {
1875          image_compression_props->imageCompressionFlags =
1876             radv_image_has_dcc(image) ? VK_IMAGE_COMPRESSION_DEFAULT_EXT : VK_IMAGE_COMPRESSION_DISABLED_EXT;
1877       }
1878    }
1879 }
1880 
1881 VKAPI_ATTR VkResult VKAPI_CALL
radv_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device,VkImage _image,VkImageDrmFormatModifierPropertiesEXT * pProperties)1882 radv_GetImageDrmFormatModifierPropertiesEXT(VkDevice _device, VkImage _image,
1883                                             VkImageDrmFormatModifierPropertiesEXT *pProperties)
1884 {
1885    VK_FROM_HANDLE(radv_image, image, _image);
1886 
1887    pProperties->drmFormatModifier = image->planes[0].surface.modifier;
1888    return VK_SUCCESS;
1889 }
1890