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