2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 #include "radv_debug.h"
29 #include "radv_private.h"
30 #include "vk_format.h"
32 #include "radv_radeon_winsys.h"
34 #include "util/debug.h"
35 #include "util/u_atomic.h"
36 #include "vulkan/util/vk_format.h"
38 #include "gfx10_format_table.h"
41 radv_choose_tiling(struct radv_device
*device
,
42 const VkImageCreateInfo
*pCreateInfo
,
45 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
) {
46 assert(pCreateInfo
->samples
<= 1);
47 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
50 if (!vk_format_is_compressed(format
) &&
51 !vk_format_is_depth_or_stencil(format
)
52 && device
->physical_device
->rad_info
.chip_class
<= GFX8
) {
53 /* this causes hangs in some VK CTS tests on GFX9. */
54 /* Textures with a very small height are recommended to be linear. */
55 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_1D
||
56 /* Only very thin and long 2D textures should benefit from
58 (pCreateInfo
->extent
.width
> 8 && pCreateInfo
->extent
.height
<= 2))
59 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
62 /* MSAA resources must be 2D tiled. */
63 if (pCreateInfo
->samples
> 1)
64 return RADEON_SURF_MODE_2D
;
66 return RADEON_SURF_MODE_2D
;
70 radv_use_tc_compat_htile_for_image(struct radv_device
*device
,
71 const VkImageCreateInfo
*pCreateInfo
,
74 /* TC-compat HTILE is only available for GFX8+. */
75 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
78 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
))
81 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
)
84 if (pCreateInfo
->mipLevels
> 1)
87 /* Do not enable TC-compatible HTILE if the image isn't readable by a
88 * shader because no texture fetches will happen.
90 if (!(pCreateInfo
->usage
& (VK_IMAGE_USAGE_SAMPLED_BIT
|
91 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT
|
92 VK_IMAGE_USAGE_TRANSFER_SRC_BIT
)))
95 /* FIXME: for some reason TC compat with 2/4/8 samples breaks some cts
96 * tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
98 if (pCreateInfo
->samples
>= 2 &&
99 (format
== VK_FORMAT_D32_SFLOAT_S8_UINT
||
100 (format
== VK_FORMAT_D32_SFLOAT
&&
101 device
->physical_device
->rad_info
.chip_class
>= GFX10
)))
104 /* GFX9 supports both 32-bit and 16-bit depth surfaces, while GFX8 only
105 * supports 32-bit. Though, it's possible to enable TC-compat for
106 * 16-bit depth surfaces if no Z planes are compressed.
108 if (format
!= VK_FORMAT_D32_SFLOAT_S8_UINT
&&
109 format
!= VK_FORMAT_D32_SFLOAT
&&
110 format
!= VK_FORMAT_D16_UNORM
)
113 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) {
114 const struct VkImageFormatListCreateInfo
*format_list
=
115 (const struct VkImageFormatListCreateInfo
*)
116 vk_find_struct_const(pCreateInfo
->pNext
,
117 IMAGE_FORMAT_LIST_CREATE_INFO
);
119 /* We have to ignore the existence of the list if viewFormatCount = 0 */
120 if (format_list
&& format_list
->viewFormatCount
) {
121 /* compatibility is transitive, so we only need to check
122 * one format with everything else.
124 for (unsigned i
= 0; i
< format_list
->viewFormatCount
; ++i
) {
125 if (format_list
->pViewFormats
[i
] == VK_FORMAT_UNDEFINED
)
128 if (format
!= format_list
->pViewFormats
[i
])
140 radv_surface_has_scanout(struct radv_device
*device
, const struct radv_image_create_info
*info
)
142 if (info
->bo_metadata
) {
143 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
)
144 return info
->bo_metadata
->u
.gfx9
.scanout
;
146 return info
->bo_metadata
->u
.legacy
.scanout
;
149 return info
->scanout
;
153 radv_image_use_fast_clear_for_image(const struct radv_device
*device
,
154 const struct radv_image
*image
)
156 if (device
->instance
->debug_flags
& RADV_DEBUG_FORCE_COMPRESS
)
159 if (image
->info
.samples
<= 1 &&
160 image
->info
.width
* image
->info
.height
<= 512 * 512) {
161 /* Do not enable CMASK or DCC for small surfaces where the cost
162 * of the eliminate pass can be higher than the benefit of fast
163 * clear. RadeonSI does this, but the image threshold is
169 return image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
&&
170 (image
->exclusive
|| image
->queue_family_mask
== 1);
174 radv_use_dcc_for_image(struct radv_device
*device
,
175 const struct radv_image
*image
,
176 const VkImageCreateInfo
*pCreateInfo
,
179 bool dcc_compatible_formats
;
182 /* DCC (Delta Color Compression) is only available for GFX8+. */
183 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
186 if (device
->instance
->debug_flags
& RADV_DEBUG_NO_DCC
)
189 if (image
->shareable
)
192 /* TODO: Enable DCC for storage images. */
193 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
))
196 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
)
199 if (vk_format_is_subsampled(format
) ||
200 vk_format_get_plane_count(format
) > 1)
203 if (!radv_image_use_fast_clear_for_image(device
, image
))
206 /* TODO: Enable DCC for mipmaps on GFX9+. */
207 if ((pCreateInfo
->arrayLayers
> 1 || pCreateInfo
->mipLevels
> 1) &&
208 device
->physical_device
->rad_info
.chip_class
>= GFX9
)
211 /* Do not enable DCC for mipmapped arrays because performance is worse. */
212 if (pCreateInfo
->arrayLayers
> 1 && pCreateInfo
->mipLevels
> 1)
215 /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while
216 * 2x can be enabled with an option.
218 if (pCreateInfo
->samples
> 2 ||
219 (pCreateInfo
->samples
== 2 &&
220 !device
->physical_device
->dcc_msaa_allowed
))
223 /* Determine if the formats are DCC compatible. */
224 dcc_compatible_formats
=
225 radv_is_colorbuffer_format_supported(format
,
228 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) {
229 const struct VkImageFormatListCreateInfo
*format_list
=
230 (const struct VkImageFormatListCreateInfo
*)
231 vk_find_struct_const(pCreateInfo
->pNext
,
232 IMAGE_FORMAT_LIST_CREATE_INFO
);
234 /* We have to ignore the existence of the list if viewFormatCount = 0 */
235 if (format_list
&& format_list
->viewFormatCount
) {
236 /* compatibility is transitive, so we only need to check
237 * one format with everything else. */
238 for (unsigned i
= 0; i
< format_list
->viewFormatCount
; ++i
) {
239 if (format_list
->pViewFormats
[i
] == VK_FORMAT_UNDEFINED
)
242 if (!radv_dcc_formats_compatible(format
,
243 format_list
->pViewFormats
[i
]))
244 dcc_compatible_formats
= false;
247 dcc_compatible_formats
= false;
251 if (!dcc_compatible_formats
)
258 radv_use_fmask_for_image(const struct radv_device
*device
,
259 const struct radv_image
*image
)
261 return image
->info
.samples
> 1 &&
262 ((image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) ||
263 (device
->instance
->debug_flags
& RADV_DEBUG_FORCE_COMPRESS
));
267 radv_use_htile_for_image(const struct radv_device
*device
,
268 const struct radv_image
*image
)
270 return image
->info
.levels
== 1 &&
271 ((image
->info
.width
* image
->info
.height
>= 8 * 8) ||
272 (device
->instance
->debug_flags
& RADV_DEBUG_FORCE_COMPRESS
));
276 radv_use_tc_compat_cmask_for_image(struct radv_device
*device
,
277 struct radv_image
*image
)
279 if (!(device
->instance
->perftest_flags
& RADV_PERFTEST_TC_COMPAT_CMASK
))
282 /* TC-compat CMASK is only available for GFX8+. */
283 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
286 if (image
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
)
289 if (radv_image_has_dcc(image
))
292 if (!radv_image_has_cmask(image
))
298 static uint32_t si_get_bo_metadata_word1(const struct radv_device
*device
)
300 return (ATI_VENDOR_ID
<< 16) | device
->physical_device
->rad_info
.pci_id
;
304 radv_is_valid_opaque_metadata(const struct radv_device
*device
,
305 const struct radeon_bo_metadata
*md
)
307 if (md
->metadata
[0] != 1 ||
308 md
->metadata
[1] != si_get_bo_metadata_word1(device
))
311 if (md
->size_metadata
< 40)
318 radv_patch_surface_from_metadata(struct radv_device
*device
,
319 struct radeon_surf
*surface
,
320 const struct radeon_bo_metadata
*md
)
322 surface
->flags
= RADEON_SURF_CLR(surface
->flags
, MODE
);
324 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
325 if (md
->u
.gfx9
.swizzle_mode
> 0)
326 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
328 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
330 surface
->u
.gfx9
.surf
.swizzle_mode
= md
->u
.gfx9
.swizzle_mode
;
332 surface
->u
.legacy
.pipe_config
= md
->u
.legacy
.pipe_config
;
333 surface
->u
.legacy
.bankw
= md
->u
.legacy
.bankw
;
334 surface
->u
.legacy
.bankh
= md
->u
.legacy
.bankh
;
335 surface
->u
.legacy
.tile_split
= md
->u
.legacy
.tile_split
;
336 surface
->u
.legacy
.mtilea
= md
->u
.legacy
.mtilea
;
337 surface
->u
.legacy
.num_banks
= md
->u
.legacy
.num_banks
;
339 if (md
->u
.legacy
.macrotile
== RADEON_LAYOUT_TILED
)
340 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
341 else if (md
->u
.legacy
.microtile
== RADEON_LAYOUT_TILED
)
342 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
344 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
350 radv_patch_image_dimensions(struct radv_device
*device
,
351 struct radv_image
*image
,
352 const struct radv_image_create_info
*create_info
,
353 struct ac_surf_info
*image_info
)
355 unsigned width
= image
->info
.width
;
356 unsigned height
= image
->info
.height
;
359 * minigbm sometimes allocates bigger images which is going to result in
360 * weird strides and other properties. Lets be lenient where possible and
361 * fail it on GFX10 (as we cannot cope there).
363 * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
365 if (create_info
->bo_metadata
&&
366 radv_is_valid_opaque_metadata(device
, create_info
->bo_metadata
)) {
367 const struct radeon_bo_metadata
*md
= create_info
->bo_metadata
;
369 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
370 width
= G_00A004_WIDTH_LO(md
->metadata
[3]) +
371 (G_00A008_WIDTH_HI(md
->metadata
[4]) << 2) + 1;
372 height
= S_00A008_HEIGHT(md
->metadata
[4]) + 1;
374 width
= G_008F18_WIDTH(md
->metadata
[4]) + 1;
375 height
= G_008F18_HEIGHT(md
->metadata
[4]) + 1;
379 if (image
->info
.width
== width
&& image
->info
.height
== height
)
382 if (width
< image
->info
.width
|| height
< image
->info
.height
) {
384 "The imported image has smaller dimensions than the internal\n"
385 "dimensions. Using it is going to fail badly, so we reject\n"
387 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
388 image
->info
.width
, image
->info
.height
, width
, height
);
389 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
390 } else if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
392 "Tried to import an image with inconsistent width on GFX10.\n"
393 "As GFX10 has no separate stride fields we cannot cope with\n"
394 "an inconsistency in width and will fail this import.\n"
395 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
396 image
->info
.width
, image
->info
.height
, width
, height
);
397 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
400 "Tried to import an image with inconsistent width on pre-GFX10.\n"
401 "As GFX10 has no separate stride fields we cannot cope with\n"
402 "an inconsistency and would fail on GFX10.\n"
403 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
404 image
->info
.width
, image
->info
.height
, width
, height
);
406 image_info
->width
= width
;
407 image_info
->height
= height
;
413 radv_patch_image_from_extra_info(struct radv_device
*device
,
414 struct radv_image
*image
,
415 const struct radv_image_create_info
*create_info
,
416 struct ac_surf_info
*image_info
)
418 VkResult result
= radv_patch_image_dimensions(device
, image
, create_info
, image_info
);
419 if (result
!= VK_SUCCESS
)
422 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
423 if (create_info
->bo_metadata
) {
424 radv_patch_surface_from_metadata(device
, &image
->planes
[plane
].surface
,
425 create_info
->bo_metadata
);
428 if (radv_surface_has_scanout(device
, create_info
)) {
429 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_SCANOUT
;
430 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_DISABLE_DCC
;
432 image
->info
.surf_index
= NULL
;
439 radv_init_surface(struct radv_device
*device
,
440 const struct radv_image
*image
,
441 struct radeon_surf
*surface
,
443 const VkImageCreateInfo
*pCreateInfo
,
444 VkFormat image_format
)
446 unsigned array_mode
= radv_choose_tiling(device
, pCreateInfo
, image_format
);
447 VkFormat format
= vk_format_get_plane_format(image_format
, plane_id
);
448 const struct vk_format_description
*desc
= vk_format_description(format
);
449 bool is_depth
, is_stencil
;
451 is_depth
= vk_format_has_depth(desc
);
452 is_stencil
= vk_format_has_stencil(desc
);
454 surface
->blk_w
= vk_format_get_blockwidth(format
);
455 surface
->blk_h
= vk_format_get_blockheight(format
);
457 surface
->bpe
= vk_format_get_blocksize(vk_format_depth_only(format
));
458 /* align byte per element on dword */
459 if (surface
->bpe
== 3) {
463 surface
->flags
= RADEON_SURF_SET(array_mode
, MODE
);
465 switch (pCreateInfo
->imageType
){
466 case VK_IMAGE_TYPE_1D
:
467 if (pCreateInfo
->arrayLayers
> 1)
468 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY
, TYPE
);
470 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D
, TYPE
);
472 case VK_IMAGE_TYPE_2D
:
473 if (pCreateInfo
->arrayLayers
> 1)
474 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY
, TYPE
);
476 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D
, TYPE
);
478 case VK_IMAGE_TYPE_3D
:
479 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_3D
, TYPE
);
482 unreachable("unhandled image type");
485 /* Required for clearing/initializing a specific layer on GFX8. */
486 surface
->flags
|= RADEON_SURF_CONTIGUOUS_DCC_LAYERS
;
489 surface
->flags
|= RADEON_SURF_ZBUFFER
;
490 if (!radv_use_htile_for_image(device
, image
) ||
491 (device
->instance
->debug_flags
& RADV_DEBUG_NO_HIZ
))
492 surface
->flags
|= RADEON_SURF_NO_HTILE
;
493 if (radv_use_tc_compat_htile_for_image(device
, pCreateInfo
, image_format
))
494 surface
->flags
|= RADEON_SURF_TC_COMPATIBLE_HTILE
;
498 surface
->flags
|= RADEON_SURF_SBUFFER
;
500 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
501 pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
&&
502 vk_format_get_blocksizebits(image_format
) == 128 &&
503 vk_format_is_compressed(image_format
))
504 surface
->flags
|= RADEON_SURF_NO_RENDER_TARGET
;
506 if (!radv_use_dcc_for_image(device
, image
, pCreateInfo
, image_format
))
507 surface
->flags
|= RADEON_SURF_DISABLE_DCC
;
509 if (!radv_use_fmask_for_image(device
, image
))
510 surface
->flags
|= RADEON_SURF_NO_FMASK
;
515 static inline unsigned
516 si_tile_mode_index(const struct radv_image_plane
*plane
, unsigned level
, bool stencil
)
519 return plane
->surface
.u
.legacy
.stencil_tiling_index
[level
];
521 return plane
->surface
.u
.legacy
.tiling_index
[level
];
524 static unsigned radv_map_swizzle(unsigned swizzle
)
528 return V_008F0C_SQ_SEL_Y
;
530 return V_008F0C_SQ_SEL_Z
;
532 return V_008F0C_SQ_SEL_W
;
534 return V_008F0C_SQ_SEL_0
;
536 return V_008F0C_SQ_SEL_1
;
537 default: /* VK_SWIZZLE_X */
538 return V_008F0C_SQ_SEL_X
;
543 radv_make_buffer_descriptor(struct radv_device
*device
,
544 struct radv_buffer
*buffer
,
550 const struct vk_format_description
*desc
;
552 uint64_t gpu_address
= radv_buffer_get_va(buffer
->bo
);
553 uint64_t va
= gpu_address
+ buffer
->offset
;
554 unsigned num_format
, data_format
;
556 desc
= vk_format_description(vk_format
);
557 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
558 stride
= desc
->block
.bits
/ 8;
562 state
[1] = S_008F04_BASE_ADDRESS_HI(va
>> 32) |
563 S_008F04_STRIDE(stride
);
565 if (device
->physical_device
->rad_info
.chip_class
!= GFX8
&& stride
) {
570 state
[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc
->swizzle
[0])) |
571 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc
->swizzle
[1])) |
572 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc
->swizzle
[2])) |
573 S_008F0C_DST_SEL_W(radv_map_swizzle(desc
->swizzle
[3]));
575 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
576 const struct gfx10_format
*fmt
= &gfx10_format_table
[vk_format_to_pipe_format(vk_format
)];
578 /* OOB_SELECT chooses the out-of-bounds check:
579 * - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
580 * - 1: index >= NUM_RECORDS
581 * - 2: NUM_RECORDS == 0
582 * - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
583 * else: swizzle_address >= NUM_RECORDS
585 state
[3] |= S_008F0C_FORMAT(fmt
->img_format
) |
586 S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET
) |
587 S_008F0C_RESOURCE_LEVEL(1);
589 num_format
= radv_translate_buffer_numformat(desc
, first_non_void
);
590 data_format
= radv_translate_buffer_dataformat(desc
, first_non_void
);
592 assert(data_format
!= V_008F0C_BUF_DATA_FORMAT_INVALID
);
593 assert(num_format
!= ~0);
595 state
[3] |= S_008F0C_NUM_FORMAT(num_format
) |
596 S_008F0C_DATA_FORMAT(data_format
);
601 si_set_mutable_tex_desc_fields(struct radv_device
*device
,
602 struct radv_image
*image
,
603 const struct legacy_surf_level
*base_level_info
,
605 unsigned base_level
, unsigned first_level
,
606 unsigned block_width
, bool is_stencil
,
607 bool is_storage_image
, bool disable_compression
,
610 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
611 uint64_t gpu_address
= image
->bo
? radv_buffer_get_va(image
->bo
) + image
->offset
: 0;
612 uint64_t va
= gpu_address
+ plane
->offset
;
613 enum chip_class chip_class
= device
->physical_device
->rad_info
.chip_class
;
614 uint64_t meta_va
= 0;
615 if (chip_class
>= GFX9
) {
617 va
+= plane
->surface
.u
.gfx9
.stencil_offset
;
619 va
+= plane
->surface
.u
.gfx9
.surf_offset
;
621 va
+= base_level_info
->offset
;
624 if (chip_class
>= GFX9
||
625 base_level_info
->mode
== RADEON_SURF_MODE_2D
)
626 state
[0] |= plane
->surface
.tile_swizzle
;
627 state
[1] &= C_008F14_BASE_ADDRESS_HI
;
628 state
[1] |= S_008F14_BASE_ADDRESS_HI(va
>> 40);
630 if (chip_class
>= GFX8
) {
631 state
[6] &= C_008F28_COMPRESSION_EN
;
633 if (!disable_compression
&& radv_dcc_enabled(image
, first_level
)) {
634 meta_va
= gpu_address
+ plane
->surface
.dcc_offset
;
635 if (chip_class
<= GFX8
)
636 meta_va
+= base_level_info
->dcc_offset
;
638 unsigned dcc_tile_swizzle
= plane
->surface
.tile_swizzle
<< 8;
639 dcc_tile_swizzle
&= plane
->surface
.dcc_alignment
- 1;
640 meta_va
|= dcc_tile_swizzle
;
641 } else if (!disable_compression
&&
642 radv_image_is_tc_compat_htile(image
)) {
643 meta_va
= gpu_address
+ plane
->surface
.htile_offset
;
647 state
[6] |= S_008F28_COMPRESSION_EN(1);
648 if (chip_class
<= GFX9
)
649 state
[7] = meta_va
>> 8;
653 if (chip_class
>= GFX10
) {
654 state
[3] &= C_00A00C_SW_MODE
;
657 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
659 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
662 state
[6] &= C_00A018_META_DATA_ADDRESS_LO
&
663 C_00A018_META_PIPE_ALIGNED
;
666 struct gfx9_surf_meta_flags meta
= {
671 if (plane
->surface
.dcc_offset
)
672 meta
= plane
->surface
.u
.gfx9
.dcc
;
674 state
[6] |= S_00A018_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
675 S_00A018_META_DATA_ADDRESS_LO(meta_va
>> 8);
678 state
[7] = meta_va
>> 16;
679 } else if (chip_class
== GFX9
) {
680 state
[3] &= C_008F1C_SW_MODE
;
681 state
[4] &= C_008F20_PITCH
;
684 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
685 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.stencil
.epitch
);
687 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
688 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.surf
.epitch
);
691 state
[5] &= C_008F24_META_DATA_ADDRESS
&
692 C_008F24_META_PIPE_ALIGNED
&
693 C_008F24_META_RB_ALIGNED
;
695 struct gfx9_surf_meta_flags meta
= {
700 if (plane
->surface
.dcc_offset
)
701 meta
= plane
->surface
.u
.gfx9
.dcc
;
703 state
[5] |= S_008F24_META_DATA_ADDRESS(meta_va
>> 40) |
704 S_008F24_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
705 S_008F24_META_RB_ALIGNED(meta
.rb_aligned
);
709 unsigned pitch
= base_level_info
->nblk_x
* block_width
;
710 unsigned index
= si_tile_mode_index(plane
, base_level
, is_stencil
);
712 state
[3] &= C_008F1C_TILING_INDEX
;
713 state
[3] |= S_008F1C_TILING_INDEX(index
);
714 state
[4] &= C_008F20_PITCH
;
715 state
[4] |= S_008F20_PITCH(pitch
- 1);
719 static unsigned radv_tex_dim(VkImageType image_type
, VkImageViewType view_type
,
720 unsigned nr_layers
, unsigned nr_samples
, bool is_storage_image
, bool gfx9
)
722 if (view_type
== VK_IMAGE_VIEW_TYPE_CUBE
|| view_type
== VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
)
723 return is_storage_image
? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_CUBE
;
725 /* GFX9 allocates 1D textures as 2D. */
726 if (gfx9
&& image_type
== VK_IMAGE_TYPE_1D
)
727 image_type
= VK_IMAGE_TYPE_2D
;
728 switch (image_type
) {
729 case VK_IMAGE_TYPE_1D
:
730 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY
: V_008F1C_SQ_RSRC_IMG_1D
;
731 case VK_IMAGE_TYPE_2D
:
733 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D_MSAA
;
735 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D
;
736 case VK_IMAGE_TYPE_3D
:
737 if (view_type
== VK_IMAGE_VIEW_TYPE_3D
)
738 return V_008F1C_SQ_RSRC_IMG_3D
;
740 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY
;
742 unreachable("illegal image type");
746 static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle
[4])
748 unsigned bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
750 if (swizzle
[3] == VK_SWIZZLE_X
) {
751 /* For the pre-defined border color values (white, opaque
752 * black, transparent black), the only thing that matters is
753 * that the alpha channel winds up in the correct place
754 * (because the RGB channels are all the same) so either of
755 * these enumerations will work.
757 if (swizzle
[2] == VK_SWIZZLE_Y
)
758 bc_swizzle
= V_008F20_BC_SWIZZLE_WZYX
;
760 bc_swizzle
= V_008F20_BC_SWIZZLE_WXYZ
;
761 } else if (swizzle
[0] == VK_SWIZZLE_X
) {
762 if (swizzle
[1] == VK_SWIZZLE_Y
)
763 bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
765 bc_swizzle
= V_008F20_BC_SWIZZLE_XWYZ
;
766 } else if (swizzle
[1] == VK_SWIZZLE_X
) {
767 bc_swizzle
= V_008F20_BC_SWIZZLE_YXWZ
;
768 } else if (swizzle
[2] == VK_SWIZZLE_X
) {
769 bc_swizzle
= V_008F20_BC_SWIZZLE_ZYXW
;
775 bool vi_alpha_is_on_msb(struct radv_device
*device
, VkFormat format
)
777 const struct vk_format_description
*desc
= vk_format_description(format
);
779 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
&& desc
->nr_channels
== 1)
780 return desc
->swizzle
[3] == VK_SWIZZLE_X
;
782 return radv_translate_colorswap(format
, false) <= 1;
785 * Build the sampler view descriptor for a texture (GFX10).
788 gfx10_make_texture_descriptor(struct radv_device
*device
,
789 struct radv_image
*image
,
790 bool is_storage_image
,
791 VkImageViewType view_type
,
793 const VkComponentMapping
*mapping
,
794 unsigned first_level
, unsigned last_level
,
795 unsigned first_layer
, unsigned last_layer
,
796 unsigned width
, unsigned height
, unsigned depth
,
798 uint32_t *fmask_state
)
800 const struct vk_format_description
*desc
;
801 enum vk_swizzle swizzle
[4];
805 desc
= vk_format_description(vk_format
);
806 img_format
= gfx10_format_table
[vk_format_to_pipe_format(vk_format
)].img_format
;
808 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
809 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
810 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
812 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
815 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
816 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
817 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
819 depth
= image
->info
.array_size
;
820 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
821 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
822 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
823 depth
= image
->info
.array_size
;
824 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
825 depth
= image
->info
.array_size
/ 6;
828 state
[1] = S_00A004_FORMAT(img_format
) |
829 S_00A004_WIDTH_LO(width
- 1);
830 state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
831 S_00A008_HEIGHT(height
- 1) |
832 S_00A008_RESOURCE_LEVEL(1);
833 state
[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
834 S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
835 S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
836 S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
837 S_00A00C_BASE_LEVEL(image
->info
.samples
> 1 ?
839 S_00A00C_LAST_LEVEL(image
->info
.samples
> 1 ?
840 util_logbase2(image
->info
.samples
) :
842 S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(swizzle
)) |
844 /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
845 * to know the total number of layers.
847 state
[4] = S_00A010_DEPTH(type
== V_008F1C_SQ_RSRC_IMG_3D
? depth
- 1 : last_layer
) |
848 S_00A010_BASE_ARRAY(first_layer
);
849 state
[5] = S_00A014_ARRAY_PITCH(0) |
850 S_00A014_MAX_MIP(image
->info
.samples
> 1 ?
851 util_logbase2(image
->info
.samples
) :
852 image
->info
.levels
- 1) |
853 S_00A014_PERF_MOD(4);
857 if (radv_dcc_enabled(image
, first_level
)) {
858 state
[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B
) |
859 S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B
) |
860 S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
863 /* Initialize the sampler view for FMASK. */
864 if (radv_image_has_fmask(image
)) {
865 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
869 assert(image
->plane_count
== 1);
871 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.fmask_offset
;
873 switch (image
->info
.samples
) {
875 format
= V_008F0C_IMG_FORMAT_FMASK8_S2_F2
;
878 format
= V_008F0C_IMG_FORMAT_FMASK8_S4_F4
;
881 format
= V_008F0C_IMG_FORMAT_FMASK32_S8_F8
;
884 unreachable("invalid nr_samples");
887 fmask_state
[0] = (va
>> 8) | image
->planes
[0].surface
.fmask_tile_swizzle
;
888 fmask_state
[1] = S_00A004_BASE_ADDRESS_HI(va
>> 40) |
889 S_00A004_FORMAT(format
) |
890 S_00A004_WIDTH_LO(width
- 1);
891 fmask_state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
892 S_00A008_HEIGHT(height
- 1) |
893 S_00A008_RESOURCE_LEVEL(1);
894 fmask_state
[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
895 S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
896 S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
897 S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
898 S_00A00C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
) |
899 S_00A00C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
900 fmask_state
[4] = S_00A010_DEPTH(last_layer
) |
901 S_00A010_BASE_ARRAY(first_layer
);
903 fmask_state
[6] = S_00A018_META_PIPE_ALIGNED(1);
905 } else if (fmask_state
)
906 memset(fmask_state
, 0, 8 * 4);
910 * Build the sampler view descriptor for a texture (SI-GFX9)
913 si_make_texture_descriptor(struct radv_device
*device
,
914 struct radv_image
*image
,
915 bool is_storage_image
,
916 VkImageViewType view_type
,
918 const VkComponentMapping
*mapping
,
919 unsigned first_level
, unsigned last_level
,
920 unsigned first_layer
, unsigned last_layer
,
921 unsigned width
, unsigned height
, unsigned depth
,
923 uint32_t *fmask_state
)
925 const struct vk_format_description
*desc
;
926 enum vk_swizzle swizzle
[4];
928 unsigned num_format
, data_format
, type
;
930 desc
= vk_format_description(vk_format
);
932 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
933 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
934 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
936 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
939 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
941 num_format
= radv_translate_tex_numformat(vk_format
, desc
, first_non_void
);
942 if (num_format
== ~0) {
946 data_format
= radv_translate_tex_dataformat(vk_format
, desc
, first_non_void
);
947 if (data_format
== ~0) {
951 /* S8 with either Z16 or Z32 HTILE need a special format. */
952 if (device
->physical_device
->rad_info
.chip_class
== GFX9
&&
953 vk_format
== VK_FORMAT_S8_UINT
&&
954 radv_image_is_tc_compat_htile(image
)) {
955 if (image
->vk_format
== VK_FORMAT_D32_SFLOAT_S8_UINT
)
956 data_format
= V_008F14_IMG_DATA_FORMAT_S8_32
;
957 else if (image
->vk_format
== VK_FORMAT_D16_UNORM_S8_UINT
)
958 data_format
= V_008F14_IMG_DATA_FORMAT_S8_16
;
960 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
961 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
962 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
964 depth
= image
->info
.array_size
;
965 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
966 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
967 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
968 depth
= image
->info
.array_size
;
969 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
970 depth
= image
->info
.array_size
/ 6;
973 state
[1] = (S_008F14_DATA_FORMAT(data_format
) |
974 S_008F14_NUM_FORMAT(num_format
));
975 state
[2] = (S_008F18_WIDTH(width
- 1) |
976 S_008F18_HEIGHT(height
- 1) |
977 S_008F18_PERF_MOD(4));
978 state
[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
979 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
980 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
981 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
982 S_008F1C_BASE_LEVEL(image
->info
.samples
> 1 ?
984 S_008F1C_LAST_LEVEL(image
->info
.samples
> 1 ?
985 util_logbase2(image
->info
.samples
) :
987 S_008F1C_TYPE(type
));
989 state
[5] = S_008F24_BASE_ARRAY(first_layer
);
993 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
994 unsigned bc_swizzle
= gfx9_border_color_swizzle(swizzle
);
996 /* Depth is the last accessible layer on Gfx9.
997 * The hw doesn't need to know the total number of layers.
999 if (type
== V_008F1C_SQ_RSRC_IMG_3D
)
1000 state
[4] |= S_008F20_DEPTH(depth
- 1);
1002 state
[4] |= S_008F20_DEPTH(last_layer
);
1004 state
[4] |= S_008F20_BC_SWIZZLE(bc_swizzle
);
1005 state
[5] |= S_008F24_MAX_MIP(image
->info
.samples
> 1 ?
1006 util_logbase2(image
->info
.samples
) :
1007 image
->info
.levels
- 1);
1009 state
[3] |= S_008F1C_POW2_PAD(image
->info
.levels
> 1);
1010 state
[4] |= S_008F20_DEPTH(depth
- 1);
1011 state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
1013 if (image
->planes
[0].surface
.dcc_offset
) {
1014 state
[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
1016 /* The last dword is unused by hw. The shader uses it to clear
1017 * bits in the first dword of sampler state.
1019 if (device
->physical_device
->rad_info
.chip_class
<= GFX7
&& image
->info
.samples
<= 1) {
1020 if (first_level
== last_level
)
1021 state
[7] = C_008F30_MAX_ANISO_RATIO
;
1023 state
[7] = 0xffffffff;
1027 /* Initialize the sampler view for FMASK. */
1028 if (radv_image_has_fmask(image
)) {
1029 uint32_t fmask_format
, num_format
;
1030 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
1033 assert(image
->plane_count
== 1);
1035 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.fmask_offset
;
1037 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
1038 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK
;
1039 switch (image
->info
.samples
) {
1041 num_format
= V_008F14_IMG_FMASK_8_2_2
;
1044 num_format
= V_008F14_IMG_FMASK_8_4_4
;
1047 num_format
= V_008F14_IMG_FMASK_32_8_8
;
1050 unreachable("invalid nr_samples");
1053 switch (image
->info
.samples
) {
1055 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2
;
1058 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4
;
1061 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8
;
1065 fmask_format
= V_008F14_IMG_DATA_FORMAT_INVALID
;
1067 num_format
= V_008F14_IMG_NUM_FORMAT_UINT
;
1070 fmask_state
[0] = va
>> 8;
1071 fmask_state
[0] |= image
->planes
[0].surface
.fmask_tile_swizzle
;
1072 fmask_state
[1] = S_008F14_BASE_ADDRESS_HI(va
>> 40) |
1073 S_008F14_DATA_FORMAT(fmask_format
) |
1074 S_008F14_NUM_FORMAT(num_format
);
1075 fmask_state
[2] = S_008F18_WIDTH(width
- 1) |
1076 S_008F18_HEIGHT(height
- 1);
1077 fmask_state
[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
1078 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
1079 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
1080 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
1081 S_008F1C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
1083 fmask_state
[5] = S_008F24_BASE_ARRAY(first_layer
);
1087 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
1088 fmask_state
[3] |= S_008F1C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
);
1089 fmask_state
[4] |= S_008F20_DEPTH(last_layer
) |
1090 S_008F20_PITCH(image
->planes
[0].surface
.u
.gfx9
.fmask
.epitch
);
1091 fmask_state
[5] |= S_008F24_META_PIPE_ALIGNED(1) |
1092 S_008F24_META_RB_ALIGNED(1);
1094 if (radv_image_is_tc_compat_cmask(image
)) {
1095 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.cmask_offset
;
1097 fmask_state
[5] |= S_008F24_META_DATA_ADDRESS(va
>> 40);
1098 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
1099 fmask_state
[7] |= va
>> 8;
1102 fmask_state
[3] |= S_008F1C_TILING_INDEX(image
->planes
[0].surface
.u
.legacy
.fmask
.tiling_index
);
1103 fmask_state
[4] |= S_008F20_DEPTH(depth
- 1) |
1104 S_008F20_PITCH(image
->planes
[0].surface
.u
.legacy
.fmask
.pitch_in_pixels
- 1);
1105 fmask_state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
1107 if (radv_image_is_tc_compat_cmask(image
)) {
1108 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.cmask_offset
;
1110 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
1111 fmask_state
[7] |= va
>> 8;
1114 } else if (fmask_state
)
1115 memset(fmask_state
, 0, 8 * 4);
1119 radv_make_texture_descriptor(struct radv_device
*device
,
1120 struct radv_image
*image
,
1121 bool is_storage_image
,
1122 VkImageViewType view_type
,
1124 const VkComponentMapping
*mapping
,
1125 unsigned first_level
, unsigned last_level
,
1126 unsigned first_layer
, unsigned last_layer
,
1127 unsigned width
, unsigned height
, unsigned depth
,
1129 uint32_t *fmask_state
)
1131 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
1132 gfx10_make_texture_descriptor(device
, image
, is_storage_image
,
1133 view_type
, vk_format
, mapping
,
1134 first_level
, last_level
,
1135 first_layer
, last_layer
,
1136 width
, height
, depth
,
1137 state
, fmask_state
);
1139 si_make_texture_descriptor(device
, image
, is_storage_image
,
1140 view_type
, vk_format
, mapping
,
1141 first_level
, last_level
,
1142 first_layer
, last_layer
,
1143 width
, height
, depth
,
1144 state
, fmask_state
);
1149 radv_query_opaque_metadata(struct radv_device
*device
,
1150 struct radv_image
*image
,
1151 struct radeon_bo_metadata
*md
)
1153 static const VkComponentMapping fixedmapping
;
1154 uint32_t desc
[8], i
;
1156 assert(image
->plane_count
== 1);
1158 /* Metadata image format format version 1:
1159 * [0] = 1 (metadata format identifier)
1160 * [1] = (VENDOR_ID << 16) | PCI_ID
1161 * [2:9] = image descriptor for the whole resource
1162 * [2] is always 0, because the base address is cleared
1163 * [9] is the DCC offset bits [39:8] from the beginning of
1165 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
1167 md
->metadata
[0] = 1; /* metadata image format version 1 */
1169 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
1170 md
->metadata
[1] = si_get_bo_metadata_word1(device
);
1173 radv_make_texture_descriptor(device
, image
, false,
1174 (VkImageViewType
)image
->type
, image
->vk_format
,
1175 &fixedmapping
, 0, image
->info
.levels
- 1, 0,
1176 image
->info
.array_size
- 1,
1177 image
->info
.width
, image
->info
.height
,
1181 si_set_mutable_tex_desc_fields(device
, image
, &image
->planes
[0].surface
.u
.legacy
.level
[0], 0, 0, 0,
1182 image
->planes
[0].surface
.blk_w
, false, false, false, desc
);
1184 /* Clear the base address and set the relative DCC offset. */
1186 desc
[1] &= C_008F14_BASE_ADDRESS_HI
;
1187 desc
[7] = image
->planes
[0].surface
.dcc_offset
>> 8;
1189 /* Dwords [2:9] contain the image descriptor. */
1190 memcpy(&md
->metadata
[2], desc
, sizeof(desc
));
1192 /* Dwords [10:..] contain the mipmap level offsets. */
1193 if (device
->physical_device
->rad_info
.chip_class
<= GFX8
) {
1194 for (i
= 0; i
<= image
->info
.levels
- 1; i
++)
1195 md
->metadata
[10+i
] = image
->planes
[0].surface
.u
.legacy
.level
[i
].offset
>> 8;
1196 md
->size_metadata
= (11 + image
->info
.levels
- 1) * 4;
1198 md
->size_metadata
= 10 * 4;
1202 radv_init_metadata(struct radv_device
*device
,
1203 struct radv_image
*image
,
1204 struct radeon_bo_metadata
*metadata
)
1206 struct radeon_surf
*surface
= &image
->planes
[0].surface
;
1208 memset(metadata
, 0, sizeof(*metadata
));
1210 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1211 metadata
->u
.gfx9
.swizzle_mode
= surface
->u
.gfx9
.surf
.swizzle_mode
;
1212 metadata
->u
.gfx9
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
1214 metadata
->u
.legacy
.microtile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_1D
?
1215 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1216 metadata
->u
.legacy
.macrotile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_2D
?
1217 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1218 metadata
->u
.legacy
.pipe_config
= surface
->u
.legacy
.pipe_config
;
1219 metadata
->u
.legacy
.bankw
= surface
->u
.legacy
.bankw
;
1220 metadata
->u
.legacy
.bankh
= surface
->u
.legacy
.bankh
;
1221 metadata
->u
.legacy
.tile_split
= surface
->u
.legacy
.tile_split
;
1222 metadata
->u
.legacy
.mtilea
= surface
->u
.legacy
.mtilea
;
1223 metadata
->u
.legacy
.num_banks
= surface
->u
.legacy
.num_banks
;
1224 metadata
->u
.legacy
.stride
= surface
->u
.legacy
.level
[0].nblk_x
* surface
->bpe
;
1225 metadata
->u
.legacy
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
1227 radv_query_opaque_metadata(device
, image
, metadata
);
1231 radv_image_override_offset_stride(struct radv_device
*device
,
1232 struct radv_image
*image
,
1233 uint64_t offset
, uint32_t stride
)
1235 ac_surface_override_offset_stride(&device
->physical_device
->rad_info
,
1236 &image
->planes
[0].surface
,
1237 image
->info
.levels
, offset
, stride
);
1241 radv_image_alloc_single_sample_cmask(const struct radv_device
*device
,
1242 const struct radv_image
*image
,
1243 struct radeon_surf
*surf
)
1245 if (!surf
->cmask_size
|| surf
->cmask_offset
|| surf
->bpe
> 8 ||
1246 image
->info
.levels
> 1 || image
->info
.depth
> 1 ||
1247 radv_image_has_dcc(image
) ||
1248 !radv_image_use_fast_clear_for_image(device
, image
))
1251 assert(image
->info
.storage_samples
== 1);
1253 surf
->cmask_offset
= align64(surf
->total_size
, surf
->cmask_alignment
);
1254 surf
->total_size
= surf
->cmask_offset
+ surf
->cmask_size
;
1255 surf
->alignment
= MAX2(surf
->alignment
, surf
->cmask_alignment
);
1259 radv_image_alloc_values(const struct radv_device
*device
, struct radv_image
*image
)
1261 if (radv_image_has_dcc(image
)) {
1262 image
->fce_pred_offset
= image
->size
;
1263 image
->size
+= 8 * image
->info
.levels
;
1265 image
->dcc_pred_offset
= image
->size
;
1266 image
->size
+= 8 * image
->info
.levels
;
1269 if (radv_image_has_dcc(image
) || radv_image_has_cmask(image
) ||
1270 radv_image_has_htile(image
)) {
1271 image
->clear_value_offset
= image
->size
;
1272 image
->size
+= 8 * image
->info
.levels
;
1275 if (radv_image_is_tc_compat_htile(image
) &&
1276 device
->physical_device
->rad_info
.has_tc_compat_zrange_bug
) {
1277 /* Metadata for the TC-compatible HTILE hardware bug which
1278 * have to be fixed by updating ZRANGE_PRECISION when doing
1279 * fast depth clears to 0.0f.
1281 image
->tc_compat_zrange_offset
= image
->size
;
1282 image
->size
+= image
->info
.levels
* 4;
1288 radv_image_reset_layout(struct radv_image
*image
)
1291 image
->alignment
= 1;
1293 image
->tc_compatible_cmask
= image
->tc_compatible_htile
= 0;
1294 image
->fce_pred_offset
= image
->dcc_pred_offset
= 0;
1295 image
->clear_value_offset
= image
->tc_compat_zrange_offset
= 0;
1297 for (unsigned i
= 0; i
< image
->plane_count
; ++i
) {
1298 VkFormat format
= vk_format_get_plane_format(image
->vk_format
, i
);
1300 uint32_t flags
= image
->planes
[i
].surface
.flags
;
1301 memset(image
->planes
+ i
, 0, sizeof(image
->planes
[i
]));
1303 image
->planes
[i
].surface
.flags
= flags
;
1304 image
->planes
[i
].surface
.blk_w
= vk_format_get_blockwidth(format
);
1305 image
->planes
[i
].surface
.blk_h
= vk_format_get_blockheight(format
);
1306 image
->planes
[i
].surface
.bpe
= vk_format_get_blocksize(vk_format_depth_only(format
));
1308 /* align byte per element on dword */
1309 if (image
->planes
[i
].surface
.bpe
== 3) {
1310 image
->planes
[i
].surface
.bpe
= 4;
1316 radv_image_create_layout(struct radv_device
*device
,
1317 struct radv_image_create_info create_info
,
1318 struct radv_image
*image
)
1320 /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
1321 * common internal case. */
1322 create_info
.vk_info
= NULL
;
1324 struct ac_surf_info image_info
= image
->info
;
1325 VkResult result
= radv_patch_image_from_extra_info(device
, image
, &create_info
, &image_info
);
1326 if (result
!= VK_SUCCESS
)
1329 radv_image_reset_layout(image
);
1331 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1332 struct ac_surf_info info
= image_info
;
1335 const struct vk_format_description
*desc
= vk_format_description(image
->vk_format
);
1336 assert(info
.width
% desc
->width_divisor
== 0);
1337 assert(info
.height
% desc
->height_divisor
== 0);
1339 info
.width
/= desc
->width_divisor
;
1340 info
.height
/= desc
->height_divisor
;
1343 if (create_info
.no_metadata_planes
|| image
->plane_count
> 1) {
1344 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_DISABLE_DCC
|
1345 RADEON_SURF_NO_FMASK
|
1346 RADEON_SURF_NO_HTILE
;
1349 device
->ws
->surface_init(device
->ws
, &info
, &image
->planes
[plane
].surface
);
1351 if (!create_info
.no_metadata_planes
&& image
->plane_count
== 1)
1352 radv_image_alloc_single_sample_cmask(device
, image
, &image
->planes
[plane
].surface
);
1354 image
->planes
[plane
].offset
= align(image
->size
, image
->planes
[plane
].surface
.alignment
);
1355 image
->size
= image
->planes
[plane
].offset
+ image
->planes
[plane
].surface
.total_size
;
1356 image
->alignment
= MAX2(image
->alignment
, image
->planes
[plane
].surface
.alignment
);
1358 image
->planes
[plane
].format
= vk_format_get_plane_format(image
->vk_format
, plane
);
1361 image
->tc_compatible_cmask
= radv_image_has_cmask(image
) &&
1362 radv_use_tc_compat_cmask_for_image(device
, image
);
1364 image
->tc_compatible_htile
= radv_image_has_htile(image
) &&
1365 image
->planes
[0].surface
.flags
& RADEON_SURF_TC_COMPATIBLE_HTILE
;
1367 radv_image_alloc_values(device
, image
);
1369 assert(image
->planes
[0].surface
.surf_size
);
1374 radv_destroy_image(struct radv_device
*device
,
1375 const VkAllocationCallbacks
*pAllocator
,
1376 struct radv_image
*image
)
1378 if ((image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
) && image
->bo
)
1379 device
->ws
->buffer_destroy(image
->bo
);
1381 if (image
->owned_memory
!= VK_NULL_HANDLE
) {
1382 RADV_FROM_HANDLE(radv_device_memory
, mem
, image
->owned_memory
);
1383 radv_free_memory(device
, pAllocator
, mem
);
1386 vk_object_base_finish(&image
->base
);
1387 vk_free2(&device
->vk
.alloc
, pAllocator
, image
);
1391 radv_image_create(VkDevice _device
,
1392 const struct radv_image_create_info
*create_info
,
1393 const VkAllocationCallbacks
* alloc
,
1396 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1397 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
1398 struct radv_image
*image
= NULL
;
1399 VkFormat format
= radv_select_android_external_format(pCreateInfo
->pNext
,
1400 pCreateInfo
->format
);
1401 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
1403 const unsigned plane_count
= vk_format_get_plane_count(format
);
1404 const size_t image_struct_size
= sizeof(*image
) + sizeof(struct radv_image_plane
) * plane_count
;
1406 radv_assert(pCreateInfo
->mipLevels
> 0);
1407 radv_assert(pCreateInfo
->arrayLayers
> 0);
1408 radv_assert(pCreateInfo
->samples
> 0);
1409 radv_assert(pCreateInfo
->extent
.width
> 0);
1410 radv_assert(pCreateInfo
->extent
.height
> 0);
1411 radv_assert(pCreateInfo
->extent
.depth
> 0);
1413 image
= vk_zalloc2(&device
->vk
.alloc
, alloc
, image_struct_size
, 8,
1414 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1416 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1418 vk_object_base_init(&device
->vk
, &image
->base
, VK_OBJECT_TYPE_IMAGE
);
1420 image
->type
= pCreateInfo
->imageType
;
1421 image
->info
.width
= pCreateInfo
->extent
.width
;
1422 image
->info
.height
= pCreateInfo
->extent
.height
;
1423 image
->info
.depth
= pCreateInfo
->extent
.depth
;
1424 image
->info
.samples
= pCreateInfo
->samples
;
1425 image
->info
.storage_samples
= pCreateInfo
->samples
;
1426 image
->info
.array_size
= pCreateInfo
->arrayLayers
;
1427 image
->info
.levels
= pCreateInfo
->mipLevels
;
1428 image
->info
.num_channels
= vk_format_get_nr_components(format
);
1430 image
->vk_format
= format
;
1431 image
->tiling
= pCreateInfo
->tiling
;
1432 image
->usage
= pCreateInfo
->usage
;
1433 image
->flags
= pCreateInfo
->flags
;
1434 image
->plane_count
= plane_count
;
1436 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
1437 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
1438 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
1439 if (pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_EXTERNAL
||
1440 pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_FOREIGN_EXT
)
1441 image
->queue_family_mask
|= (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1443 image
->queue_family_mask
|= 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
1446 const VkExternalMemoryImageCreateInfo
*external_info
=
1447 vk_find_struct_const(pCreateInfo
->pNext
,
1448 EXTERNAL_MEMORY_IMAGE_CREATE_INFO
) ;
1450 image
->shareable
= external_info
;
1451 if (!vk_format_is_depth_or_stencil(format
) && !image
->shareable
) {
1452 image
->info
.surf_index
= &device
->image_mrt_offset_counter
;
1455 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1456 radv_init_surface(device
, image
, &image
->planes
[plane
].surface
, plane
, pCreateInfo
, format
);
1459 bool delay_layout
= external_info
&&
1460 (external_info
->handleTypes
& VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
);
1463 *pImage
= radv_image_to_handle(image
);
1464 assert (!(image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
));
1468 ASSERTED VkResult result
= radv_image_create_layout(device
, *create_info
, image
);
1469 assert(result
== VK_SUCCESS
);
1471 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
) {
1472 image
->alignment
= MAX2(image
->alignment
, 4096);
1473 image
->size
= align64(image
->size
, image
->alignment
);
1476 image
->bo
= device
->ws
->buffer_create(device
->ws
, image
->size
, image
->alignment
,
1477 0, RADEON_FLAG_VIRTUAL
, RADV_BO_PRIORITY_VIRTUAL
);
1479 radv_destroy_image(device
, alloc
, image
);
1480 return vk_error(device
->instance
, VK_ERROR_OUT_OF_DEVICE_MEMORY
);
1484 *pImage
= radv_image_to_handle(image
);
1490 radv_image_view_make_descriptor(struct radv_image_view
*iview
,
1491 struct radv_device
*device
,
1493 const VkComponentMapping
*components
,
1494 bool is_storage_image
, bool disable_compression
,
1495 unsigned plane_id
, unsigned descriptor_plane_id
)
1497 struct radv_image
*image
= iview
->image
;
1498 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1499 const struct vk_format_description
*format_desc
= vk_format_description(image
->vk_format
);
1500 bool is_stencil
= iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
;
1502 union radv_descriptor
*descriptor
;
1503 uint32_t hw_level
= 0;
1505 if (is_storage_image
) {
1506 descriptor
= &iview
->storage_descriptor
;
1508 descriptor
= &iview
->descriptor
;
1511 assert(vk_format_get_plane_count(vk_format
) == 1);
1512 assert(plane
->surface
.blk_w
% vk_format_get_blockwidth(plane
->format
) == 0);
1513 blk_w
= plane
->surface
.blk_w
/ vk_format_get_blockwidth(plane
->format
) * vk_format_get_blockwidth(vk_format
);
1515 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
)
1516 hw_level
= iview
->base_mip
;
1517 radv_make_texture_descriptor(device
, image
, is_storage_image
,
1521 hw_level
, hw_level
+ iview
->level_count
- 1,
1523 iview
->base_layer
+ iview
->layer_count
- 1,
1524 iview
->extent
.width
/ (plane_id
? format_desc
->width_divisor
: 1),
1525 iview
->extent
.height
/ (plane_id
? format_desc
->height_divisor
: 1),
1526 iview
->extent
.depth
,
1527 descriptor
->plane_descriptors
[descriptor_plane_id
],
1528 descriptor_plane_id
? NULL
: descriptor
->fmask_descriptor
);
1530 const struct legacy_surf_level
*base_level_info
= NULL
;
1531 if (device
->physical_device
->rad_info
.chip_class
<= GFX9
) {
1533 base_level_info
= &plane
->surface
.u
.legacy
.stencil_level
[iview
->base_mip
];
1535 base_level_info
= &plane
->surface
.u
.legacy
.level
[iview
->base_mip
];
1537 si_set_mutable_tex_desc_fields(device
, image
,
1542 blk_w
, is_stencil
, is_storage_image
,
1543 is_storage_image
|| disable_compression
,
1544 descriptor
->plane_descriptors
[descriptor_plane_id
]);
1548 radv_plane_from_aspect(VkImageAspectFlags mask
)
1551 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1553 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1561 radv_get_aspect_format(struct radv_image
*image
, VkImageAspectFlags mask
)
1564 case VK_IMAGE_ASPECT_PLANE_0_BIT
:
1565 return image
->planes
[0].format
;
1566 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1567 return image
->planes
[1].format
;
1568 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1569 return image
->planes
[2].format
;
1570 case VK_IMAGE_ASPECT_STENCIL_BIT
:
1571 return vk_format_stencil_only(image
->vk_format
);
1572 case VK_IMAGE_ASPECT_DEPTH_BIT
:
1573 return vk_format_depth_only(image
->vk_format
);
1574 case VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
:
1575 return vk_format_depth_only(image
->vk_format
);
1577 return image
->vk_format
;
1582 radv_image_view_init(struct radv_image_view
*iview
,
1583 struct radv_device
*device
,
1584 const VkImageViewCreateInfo
* pCreateInfo
,
1585 const struct radv_image_view_extra_create_info
* extra_create_info
)
1587 RADV_FROM_HANDLE(radv_image
, image
, pCreateInfo
->image
);
1588 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
1590 switch (image
->type
) {
1591 case VK_IMAGE_TYPE_1D
:
1592 case VK_IMAGE_TYPE_2D
:
1593 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1 <= image
->info
.array_size
);
1595 case VK_IMAGE_TYPE_3D
:
1596 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1
1597 <= radv_minify(image
->info
.depth
, range
->baseMipLevel
));
1600 unreachable("bad VkImageType");
1602 iview
->image
= image
;
1603 iview
->bo
= image
->bo
;
1604 iview
->type
= pCreateInfo
->viewType
;
1605 iview
->plane_id
= radv_plane_from_aspect(pCreateInfo
->subresourceRange
.aspectMask
);
1606 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
1607 iview
->multiple_planes
= vk_format_get_plane_count(image
->vk_format
) > 1 && iview
->aspect_mask
== VK_IMAGE_ASPECT_COLOR_BIT
;
1609 iview
->vk_format
= pCreateInfo
->format
;
1611 /* If the image has an Android external format, pCreateInfo->format will be
1612 * VK_FORMAT_UNDEFINED. */
1613 if (iview
->vk_format
== VK_FORMAT_UNDEFINED
)
1614 iview
->vk_format
= image
->vk_format
;
1616 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
1617 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
1618 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
1619 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
1622 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1623 iview
->extent
= (VkExtent3D
) {
1624 .width
= image
->info
.width
,
1625 .height
= image
->info
.height
,
1626 .depth
= image
->info
.depth
,
1629 iview
->extent
= (VkExtent3D
) {
1630 .width
= radv_minify(image
->info
.width
, range
->baseMipLevel
),
1631 .height
= radv_minify(image
->info
.height
, range
->baseMipLevel
),
1632 .depth
= radv_minify(image
->info
.depth
, range
->baseMipLevel
),
1636 if (iview
->vk_format
!= image
->planes
[iview
->plane_id
].format
) {
1637 unsigned view_bw
= vk_format_get_blockwidth(iview
->vk_format
);
1638 unsigned view_bh
= vk_format_get_blockheight(iview
->vk_format
);
1639 unsigned img_bw
= vk_format_get_blockwidth(image
->vk_format
);
1640 unsigned img_bh
= vk_format_get_blockheight(image
->vk_format
);
1642 iview
->extent
.width
= round_up_u32(iview
->extent
.width
* view_bw
, img_bw
);
1643 iview
->extent
.height
= round_up_u32(iview
->extent
.height
* view_bh
, img_bh
);
1645 /* Comment ported from amdvlk -
1646 * If we have the following image:
1647 * Uncompressed pixels Compressed block sizes (4x4)
1648 * mip0: 22 x 22 6 x 6
1649 * mip1: 11 x 11 3 x 3
1654 * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and the HW is
1655 * calculating the degradation of the block sizes down the mip-chain as follows (straight-up
1656 * divide-by-two integer math):
1662 * This means that mip2 will be missing texels.
1664 * Fix this by calculating the base mip's width and height, then convert that, and round it
1665 * back up to get the level 0 size.
1666 * Clamp the converted size between the original values, and next power of two, which
1667 * means we don't oversize the image.
1669 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
1670 vk_format_is_compressed(image
->vk_format
) &&
1671 !vk_format_is_compressed(iview
->vk_format
)) {
1672 unsigned lvl_width
= radv_minify(image
->info
.width
, range
->baseMipLevel
);
1673 unsigned lvl_height
= radv_minify(image
->info
.height
, range
->baseMipLevel
);
1675 lvl_width
= round_up_u32(lvl_width
* view_bw
, img_bw
);
1676 lvl_height
= round_up_u32(lvl_height
* view_bh
, img_bh
);
1678 lvl_width
<<= range
->baseMipLevel
;
1679 lvl_height
<<= range
->baseMipLevel
;
1681 iview
->extent
.width
= CLAMP(lvl_width
, iview
->extent
.width
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_pitch
);
1682 iview
->extent
.height
= CLAMP(lvl_height
, iview
->extent
.height
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_height
);
1686 iview
->base_layer
= range
->baseArrayLayer
;
1687 iview
->layer_count
= radv_get_layerCount(image
, range
);
1688 iview
->base_mip
= range
->baseMipLevel
;
1689 iview
->level_count
= radv_get_levelCount(image
, range
);
1691 bool disable_compression
= extra_create_info
? extra_create_info
->disable_compression
: false;
1692 for (unsigned i
= 0; i
< (iview
->multiple_planes
? vk_format_get_plane_count(image
->vk_format
) : 1); ++i
) {
1693 VkFormat format
= vk_format_get_plane_format(iview
->vk_format
, i
);
1694 radv_image_view_make_descriptor(iview
, device
, format
,
1695 &pCreateInfo
->components
,
1696 false, disable_compression
,
1697 iview
->plane_id
+ i
, i
);
1698 radv_image_view_make_descriptor(iview
, device
,
1699 format
, &pCreateInfo
->components
,
1700 true, disable_compression
,
1701 iview
->plane_id
+ i
, i
);
1705 bool radv_layout_is_htile_compressed(const struct radv_image
*image
,
1706 VkImageLayout layout
,
1707 bool in_render_loop
,
1708 unsigned queue_mask
)
1710 if (radv_image_is_tc_compat_htile(image
)) {
1711 if (layout
== VK_IMAGE_LAYOUT_GENERAL
&&
1713 !(image
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
)) {
1714 /* It should be safe to enable TC-compat HTILE with
1715 * VK_IMAGE_LAYOUT_GENERAL if we are not in a render
1716 * loop and if the image doesn't have the storage bit
1717 * set. This improves performance for apps that use
1718 * GENERAL for the main depth pass because this allows
1719 * compression and this reduces the number of
1720 * decompressions from/to GENERAL.
1725 return layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1728 return radv_image_has_htile(image
) &&
1729 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
1730 layout
== VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR
||
1731 layout
== VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
||
1732 (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1733 queue_mask
== (1u << RADV_QUEUE_GENERAL
)));
1736 bool radv_layout_can_fast_clear(const struct radv_image
*image
,
1737 VkImageLayout layout
,
1738 bool in_render_loop
,
1739 unsigned queue_mask
)
1741 return layout
== VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
&&
1742 queue_mask
== (1u << RADV_QUEUE_GENERAL
);
1745 bool radv_layout_dcc_compressed(const struct radv_device
*device
,
1746 const struct radv_image
*image
,
1747 VkImageLayout layout
,
1748 bool in_render_loop
,
1749 unsigned queue_mask
)
1751 /* Don't compress compute transfer dst, as image stores are not supported. */
1752 if (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1753 (queue_mask
& (1u << RADV_QUEUE_COMPUTE
)))
1756 return radv_image_has_dcc(image
) && layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1760 unsigned radv_image_queue_family_mask(const struct radv_image
*image
, uint32_t family
, uint32_t queue_family
)
1762 if (!image
->exclusive
)
1763 return image
->queue_family_mask
;
1764 if (family
== VK_QUEUE_FAMILY_EXTERNAL
||
1765 family
== VK_QUEUE_FAMILY_FOREIGN_EXT
)
1766 return (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1767 if (family
== VK_QUEUE_FAMILY_IGNORED
)
1768 return 1u << queue_family
;
1769 return 1u << family
;
1773 radv_CreateImage(VkDevice device
,
1774 const VkImageCreateInfo
*pCreateInfo
,
1775 const VkAllocationCallbacks
*pAllocator
,
1779 const VkNativeBufferANDROID
*gralloc_info
=
1780 vk_find_struct_const(pCreateInfo
->pNext
, NATIVE_BUFFER_ANDROID
);
1783 return radv_image_from_gralloc(device
, pCreateInfo
, gralloc_info
,
1784 pAllocator
, pImage
);
1787 const struct wsi_image_create_info
*wsi_info
=
1788 vk_find_struct_const(pCreateInfo
->pNext
, WSI_IMAGE_CREATE_INFO_MESA
);
1789 bool scanout
= wsi_info
&& wsi_info
->scanout
;
1791 return radv_image_create(device
,
1792 &(struct radv_image_create_info
) {
1793 .vk_info
= pCreateInfo
,
1801 radv_DestroyImage(VkDevice _device
, VkImage _image
,
1802 const VkAllocationCallbacks
*pAllocator
)
1804 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1805 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1810 radv_destroy_image(device
, pAllocator
, image
);
1813 void radv_GetImageSubresourceLayout(
1816 const VkImageSubresource
* pSubresource
,
1817 VkSubresourceLayout
* pLayout
)
1819 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1820 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1821 int level
= pSubresource
->mipLevel
;
1822 int layer
= pSubresource
->arrayLayer
;
1824 unsigned plane_id
= radv_plane_from_aspect(pSubresource
->aspectMask
);
1826 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1827 struct radeon_surf
*surface
= &plane
->surface
;
1829 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1830 uint64_t level_offset
= surface
->is_linear
? surface
->u
.gfx9
.offset
[level
] : 0;
1832 pLayout
->offset
= plane
->offset
+ level_offset
+ surface
->u
.gfx9
.surf_slice_size
* layer
;
1833 if (image
->vk_format
== VK_FORMAT_R32G32B32_UINT
||
1834 image
->vk_format
== VK_FORMAT_R32G32B32_SINT
||
1835 image
->vk_format
== VK_FORMAT_R32G32B32_SFLOAT
) {
1836 /* Adjust the number of bytes between each row because
1837 * the pitch is actually the number of components per
1840 pLayout
->rowPitch
= surface
->u
.gfx9
.surf_pitch
* surface
->bpe
/ 3;
1842 uint32_t pitch
= surface
->is_linear
? surface
->u
.gfx9
.pitch
[level
] : surface
->u
.gfx9
.surf_pitch
;
1844 assert(util_is_power_of_two_nonzero(surface
->bpe
));
1845 pLayout
->rowPitch
= pitch
* surface
->bpe
;
1848 pLayout
->arrayPitch
= surface
->u
.gfx9
.surf_slice_size
;
1849 pLayout
->depthPitch
= surface
->u
.gfx9
.surf_slice_size
;
1850 pLayout
->size
= surface
->u
.gfx9
.surf_slice_size
;
1851 if (image
->type
== VK_IMAGE_TYPE_3D
)
1852 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1854 pLayout
->offset
= plane
->offset
+ surface
->u
.legacy
.level
[level
].offset
+ (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4 * layer
;
1855 pLayout
->rowPitch
= surface
->u
.legacy
.level
[level
].nblk_x
* surface
->bpe
;
1856 pLayout
->arrayPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1857 pLayout
->depthPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1858 pLayout
->size
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1859 if (image
->type
== VK_IMAGE_TYPE_3D
)
1860 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1866 radv_CreateImageView(VkDevice _device
,
1867 const VkImageViewCreateInfo
*pCreateInfo
,
1868 const VkAllocationCallbacks
*pAllocator
,
1871 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1872 struct radv_image_view
*view
;
1874 view
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, sizeof(*view
), 8,
1875 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1877 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1879 vk_object_base_init(&device
->vk
, &view
->base
,
1880 VK_OBJECT_TYPE_IMAGE_VIEW
);
1882 radv_image_view_init(view
, device
, pCreateInfo
, NULL
);
1884 *pView
= radv_image_view_to_handle(view
);
1890 radv_DestroyImageView(VkDevice _device
, VkImageView _iview
,
1891 const VkAllocationCallbacks
*pAllocator
)
1893 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1894 RADV_FROM_HANDLE(radv_image_view
, iview
, _iview
);
1899 vk_object_base_finish(&iview
->base
);
1900 vk_free2(&device
->vk
.alloc
, pAllocator
, iview
);
1903 void radv_buffer_view_init(struct radv_buffer_view
*view
,
1904 struct radv_device
*device
,
1905 const VkBufferViewCreateInfo
* pCreateInfo
)
1907 RADV_FROM_HANDLE(radv_buffer
, buffer
, pCreateInfo
->buffer
);
1909 view
->bo
= buffer
->bo
;
1910 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
?
1911 buffer
->size
- pCreateInfo
->offset
: pCreateInfo
->range
;
1912 view
->vk_format
= pCreateInfo
->format
;
1914 radv_make_buffer_descriptor(device
, buffer
, view
->vk_format
,
1915 pCreateInfo
->offset
, view
->range
, view
->state
);
1919 radv_CreateBufferView(VkDevice _device
,
1920 const VkBufferViewCreateInfo
*pCreateInfo
,
1921 const VkAllocationCallbacks
*pAllocator
,
1922 VkBufferView
*pView
)
1924 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1925 struct radv_buffer_view
*view
;
1927 view
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, sizeof(*view
), 8,
1928 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1930 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1932 vk_object_base_init(&device
->vk
, &view
->base
,
1933 VK_OBJECT_TYPE_BUFFER_VIEW
);
1935 radv_buffer_view_init(view
, device
, pCreateInfo
);
1937 *pView
= radv_buffer_view_to_handle(view
);
1943 radv_DestroyBufferView(VkDevice _device
, VkBufferView bufferView
,
1944 const VkAllocationCallbacks
*pAllocator
)
1946 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1947 RADV_FROM_HANDLE(radv_buffer_view
, view
, bufferView
);
1952 vk_object_base_finish(&view
->base
);
1953 vk_free2(&device
->vk
.alloc
, pAllocator
, view
);