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_image
*image
)
155 if (image
->info
.samples
<= 1 &&
156 image
->info
.width
* image
->info
.height
<= 512 * 512) {
157 /* Do not enable CMASK or DCC for small surfaces where the cost
158 * of the eliminate pass can be higher than the benefit of fast
159 * clear. RadeonSI does this, but the image threshold is
165 return image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
&&
166 (image
->exclusive
|| image
->queue_family_mask
== 1);
170 radv_use_dcc_for_image(struct radv_device
*device
,
171 const struct radv_image
*image
,
172 const VkImageCreateInfo
*pCreateInfo
,
175 bool dcc_compatible_formats
;
178 /* DCC (Delta Color Compression) is only available for GFX8+. */
179 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
182 if (device
->instance
->debug_flags
& RADV_DEBUG_NO_DCC
)
185 if (image
->shareable
)
188 /* TODO: Enable DCC for storage images. */
189 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
))
192 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
)
195 if (vk_format_is_subsampled(format
) ||
196 vk_format_get_plane_count(format
) > 1)
199 if (!radv_image_use_fast_clear_for_image(image
))
202 /* TODO: Enable DCC for mipmaps on GFX9+. */
203 if ((pCreateInfo
->arrayLayers
> 1 || pCreateInfo
->mipLevels
> 1) &&
204 device
->physical_device
->rad_info
.chip_class
>= GFX9
)
207 /* Do not enable DCC for mipmapped arrays because performance is worse. */
208 if (pCreateInfo
->arrayLayers
> 1 && pCreateInfo
->mipLevels
> 1)
211 /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while
212 * 2x can be enabled with an option.
214 if (pCreateInfo
->samples
> 2 ||
215 (pCreateInfo
->samples
== 2 &&
216 !device
->physical_device
->dcc_msaa_allowed
))
219 /* Determine if the formats are DCC compatible. */
220 dcc_compatible_formats
=
221 radv_is_colorbuffer_format_supported(format
,
224 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) {
225 const struct VkImageFormatListCreateInfo
*format_list
=
226 (const struct VkImageFormatListCreateInfo
*)
227 vk_find_struct_const(pCreateInfo
->pNext
,
228 IMAGE_FORMAT_LIST_CREATE_INFO
);
230 /* We have to ignore the existence of the list if viewFormatCount = 0 */
231 if (format_list
&& format_list
->viewFormatCount
) {
232 /* compatibility is transitive, so we only need to check
233 * one format with everything else. */
234 for (unsigned i
= 0; i
< format_list
->viewFormatCount
; ++i
) {
235 if (format_list
->pViewFormats
[i
] == VK_FORMAT_UNDEFINED
)
238 if (!radv_dcc_formats_compatible(format
,
239 format_list
->pViewFormats
[i
]))
240 dcc_compatible_formats
= false;
243 dcc_compatible_formats
= false;
247 if (!dcc_compatible_formats
)
254 radv_use_fmask_for_image(const struct radv_image
*image
)
256 return image
->info
.samples
> 1 &&
257 image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
;
261 radv_use_htile_for_image(const struct radv_image
*image
)
263 return image
->info
.levels
== 1 &&
264 image
->info
.width
* image
->info
.height
>= 8 * 8;
268 radv_use_tc_compat_cmask_for_image(struct radv_device
*device
,
269 struct radv_image
*image
)
271 if (!(device
->instance
->perftest_flags
& RADV_PERFTEST_TC_COMPAT_CMASK
))
274 /* TC-compat CMASK is only available for GFX8+. */
275 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
278 if (image
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
)
281 if (radv_image_has_dcc(image
))
284 if (!radv_image_has_cmask(image
))
290 static uint32_t si_get_bo_metadata_word1(const struct radv_device
*device
)
292 return (ATI_VENDOR_ID
<< 16) | device
->physical_device
->rad_info
.pci_id
;
296 radv_is_valid_opaque_metadata(const struct radv_device
*device
,
297 const struct radeon_bo_metadata
*md
)
299 if (md
->metadata
[0] != 1 ||
300 md
->metadata
[1] != si_get_bo_metadata_word1(device
))
303 if (md
->size_metadata
< 40)
310 radv_patch_surface_from_metadata(struct radv_device
*device
,
311 struct radeon_surf
*surface
,
312 const struct radeon_bo_metadata
*md
)
314 surface
->flags
= RADEON_SURF_CLR(surface
->flags
, MODE
);
316 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
317 if (md
->u
.gfx9
.swizzle_mode
> 0)
318 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
320 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
322 surface
->u
.gfx9
.surf
.swizzle_mode
= md
->u
.gfx9
.swizzle_mode
;
324 surface
->u
.legacy
.pipe_config
= md
->u
.legacy
.pipe_config
;
325 surface
->u
.legacy
.bankw
= md
->u
.legacy
.bankw
;
326 surface
->u
.legacy
.bankh
= md
->u
.legacy
.bankh
;
327 surface
->u
.legacy
.tile_split
= md
->u
.legacy
.tile_split
;
328 surface
->u
.legacy
.mtilea
= md
->u
.legacy
.mtilea
;
329 surface
->u
.legacy
.num_banks
= md
->u
.legacy
.num_banks
;
331 if (md
->u
.legacy
.macrotile
== RADEON_LAYOUT_TILED
)
332 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
333 else if (md
->u
.legacy
.microtile
== RADEON_LAYOUT_TILED
)
334 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
336 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
342 radv_patch_image_dimensions(struct radv_device
*device
,
343 struct radv_image
*image
,
344 const struct radv_image_create_info
*create_info
,
345 struct ac_surf_info
*image_info
)
347 unsigned width
= image
->info
.width
;
348 unsigned height
= image
->info
.height
;
351 * minigbm sometimes allocates bigger images which is going to result in
352 * weird strides and other properties. Lets be lenient where possible and
353 * fail it on GFX10 (as we cannot cope there).
355 * Example hack: https://chromium-review.googlesource.com/c/chromiumos/platform/minigbm/+/1457777/
357 if (create_info
->bo_metadata
&&
358 radv_is_valid_opaque_metadata(device
, create_info
->bo_metadata
)) {
359 const struct radeon_bo_metadata
*md
= create_info
->bo_metadata
;
361 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
362 width
= G_00A004_WIDTH_LO(md
->metadata
[3]) +
363 (G_00A008_WIDTH_HI(md
->metadata
[4]) << 2) + 1;
364 height
= S_00A008_HEIGHT(md
->metadata
[4]) + 1;
366 width
= G_008F18_WIDTH(md
->metadata
[4]) + 1;
367 height
= G_008F18_HEIGHT(md
->metadata
[4]) + 1;
371 if (image
->info
.width
== width
&& image
->info
.height
== height
)
374 if (width
< image
->info
.width
|| height
< image
->info
.height
) {
376 "The imported image has smaller dimensions than the internal\n"
377 "dimensions. Using it is going to fail badly, so we reject\n"
379 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
380 image
->info
.width
, image
->info
.height
, width
, height
);
381 return VK_ERROR_INVALID_EXTERNAL_HANDLE
;
382 } else if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
384 "Tried to import an image with inconsistent width on GFX10.\n"
385 "As GFX10 has no separate stride fields we cannot cope with\n"
386 "an inconsistency in width and will fail this import.\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
;
392 "Tried to import an image with inconsistent width on pre-GFX10.\n"
393 "As GFX10 has no separate stride fields we cannot cope with\n"
394 "an inconsistency and would fail on GFX10.\n"
395 "(internal dimensions: %d x %d, external dimensions: %d x %d)\n",
396 image
->info
.width
, image
->info
.height
, width
, height
);
398 image_info
->width
= width
;
399 image_info
->height
= height
;
405 radv_patch_image_from_extra_info(struct radv_device
*device
,
406 struct radv_image
*image
,
407 const struct radv_image_create_info
*create_info
,
408 struct ac_surf_info
*image_info
)
410 VkResult result
= radv_patch_image_dimensions(device
, image
, create_info
, image_info
);
411 if (result
!= VK_SUCCESS
)
414 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
415 if (create_info
->bo_metadata
) {
416 radv_patch_surface_from_metadata(device
, &image
->planes
[plane
].surface
,
417 create_info
->bo_metadata
);
420 if (radv_surface_has_scanout(device
, create_info
)) {
421 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_SCANOUT
;
422 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_DISABLE_DCC
;
424 image
->info
.surf_index
= NULL
;
431 radv_init_surface(struct radv_device
*device
,
432 const struct radv_image
*image
,
433 struct radeon_surf
*surface
,
435 const VkImageCreateInfo
*pCreateInfo
,
436 VkFormat image_format
)
438 unsigned array_mode
= radv_choose_tiling(device
, pCreateInfo
, image_format
);
439 VkFormat format
= vk_format_get_plane_format(image_format
, plane_id
);
440 const struct vk_format_description
*desc
= vk_format_description(format
);
441 bool is_depth
, is_stencil
;
443 is_depth
= vk_format_has_depth(desc
);
444 is_stencil
= vk_format_has_stencil(desc
);
446 surface
->blk_w
= vk_format_get_blockwidth(format
);
447 surface
->blk_h
= vk_format_get_blockheight(format
);
449 surface
->bpe
= vk_format_get_blocksize(vk_format_depth_only(format
));
450 /* align byte per element on dword */
451 if (surface
->bpe
== 3) {
455 surface
->flags
= RADEON_SURF_SET(array_mode
, MODE
);
457 switch (pCreateInfo
->imageType
){
458 case VK_IMAGE_TYPE_1D
:
459 if (pCreateInfo
->arrayLayers
> 1)
460 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY
, TYPE
);
462 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D
, TYPE
);
464 case VK_IMAGE_TYPE_2D
:
465 if (pCreateInfo
->arrayLayers
> 1)
466 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY
, TYPE
);
468 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D
, TYPE
);
470 case VK_IMAGE_TYPE_3D
:
471 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_3D
, TYPE
);
474 unreachable("unhandled image type");
477 /* Required for clearing/initializing a specific layer on GFX8. */
478 surface
->flags
|= RADEON_SURF_CONTIGUOUS_DCC_LAYERS
;
481 surface
->flags
|= RADEON_SURF_ZBUFFER
;
482 if (!radv_use_htile_for_image(image
) ||
483 (device
->instance
->debug_flags
& RADV_DEBUG_NO_HIZ
))
484 surface
->flags
|= RADEON_SURF_NO_HTILE
;
485 if (radv_use_tc_compat_htile_for_image(device
, pCreateInfo
, image_format
))
486 surface
->flags
|= RADEON_SURF_TC_COMPATIBLE_HTILE
;
490 surface
->flags
|= RADEON_SURF_SBUFFER
;
492 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
493 pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
&&
494 vk_format_get_blocksizebits(image_format
) == 128 &&
495 vk_format_is_compressed(image_format
))
496 surface
->flags
|= RADEON_SURF_NO_RENDER_TARGET
;
498 if (!radv_use_dcc_for_image(device
, image
, pCreateInfo
, image_format
))
499 surface
->flags
|= RADEON_SURF_DISABLE_DCC
;
501 if (!radv_use_fmask_for_image(image
))
502 surface
->flags
|= RADEON_SURF_NO_FMASK
;
507 static inline unsigned
508 si_tile_mode_index(const struct radv_image_plane
*plane
, unsigned level
, bool stencil
)
511 return plane
->surface
.u
.legacy
.stencil_tiling_index
[level
];
513 return plane
->surface
.u
.legacy
.tiling_index
[level
];
516 static unsigned radv_map_swizzle(unsigned swizzle
)
520 return V_008F0C_SQ_SEL_Y
;
522 return V_008F0C_SQ_SEL_Z
;
524 return V_008F0C_SQ_SEL_W
;
526 return V_008F0C_SQ_SEL_0
;
528 return V_008F0C_SQ_SEL_1
;
529 default: /* VK_SWIZZLE_X */
530 return V_008F0C_SQ_SEL_X
;
535 radv_make_buffer_descriptor(struct radv_device
*device
,
536 struct radv_buffer
*buffer
,
542 const struct vk_format_description
*desc
;
544 uint64_t gpu_address
= radv_buffer_get_va(buffer
->bo
);
545 uint64_t va
= gpu_address
+ buffer
->offset
;
546 unsigned num_format
, data_format
;
548 desc
= vk_format_description(vk_format
);
549 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
550 stride
= desc
->block
.bits
/ 8;
554 state
[1] = S_008F04_BASE_ADDRESS_HI(va
>> 32) |
555 S_008F04_STRIDE(stride
);
557 if (device
->physical_device
->rad_info
.chip_class
!= GFX8
&& stride
) {
562 state
[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc
->swizzle
[0])) |
563 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc
->swizzle
[1])) |
564 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc
->swizzle
[2])) |
565 S_008F0C_DST_SEL_W(radv_map_swizzle(desc
->swizzle
[3]));
567 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
568 const struct gfx10_format
*fmt
= &gfx10_format_table
[vk_format_to_pipe_format(vk_format
)];
570 /* OOB_SELECT chooses the out-of-bounds check:
571 * - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
572 * - 1: index >= NUM_RECORDS
573 * - 2: NUM_RECORDS == 0
574 * - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
575 * else: swizzle_address >= NUM_RECORDS
577 state
[3] |= S_008F0C_FORMAT(fmt
->img_format
) |
578 S_008F0C_OOB_SELECT(V_008F0C_OOB_SELECT_STRUCTURED_WITH_OFFSET
) |
579 S_008F0C_RESOURCE_LEVEL(1);
581 num_format
= radv_translate_buffer_numformat(desc
, first_non_void
);
582 data_format
= radv_translate_buffer_dataformat(desc
, first_non_void
);
584 assert(data_format
!= V_008F0C_BUF_DATA_FORMAT_INVALID
);
585 assert(num_format
!= ~0);
587 state
[3] |= S_008F0C_NUM_FORMAT(num_format
) |
588 S_008F0C_DATA_FORMAT(data_format
);
593 si_set_mutable_tex_desc_fields(struct radv_device
*device
,
594 struct radv_image
*image
,
595 const struct legacy_surf_level
*base_level_info
,
597 unsigned base_level
, unsigned first_level
,
598 unsigned block_width
, bool is_stencil
,
599 bool is_storage_image
, bool disable_compression
,
602 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
603 uint64_t gpu_address
= image
->bo
? radv_buffer_get_va(image
->bo
) + image
->offset
: 0;
604 uint64_t va
= gpu_address
+ plane
->offset
;
605 enum chip_class chip_class
= device
->physical_device
->rad_info
.chip_class
;
606 uint64_t meta_va
= 0;
607 if (chip_class
>= GFX9
) {
609 va
+= plane
->surface
.u
.gfx9
.stencil_offset
;
611 va
+= plane
->surface
.u
.gfx9
.surf_offset
;
613 va
+= base_level_info
->offset
;
616 if (chip_class
>= GFX9
||
617 base_level_info
->mode
== RADEON_SURF_MODE_2D
)
618 state
[0] |= plane
->surface
.tile_swizzle
;
619 state
[1] &= C_008F14_BASE_ADDRESS_HI
;
620 state
[1] |= S_008F14_BASE_ADDRESS_HI(va
>> 40);
622 if (chip_class
>= GFX8
) {
623 state
[6] &= C_008F28_COMPRESSION_EN
;
625 if (!disable_compression
&& radv_dcc_enabled(image
, first_level
)) {
626 meta_va
= gpu_address
+ plane
->surface
.dcc_offset
;
627 if (chip_class
<= GFX8
)
628 meta_va
+= base_level_info
->dcc_offset
;
630 unsigned dcc_tile_swizzle
= plane
->surface
.tile_swizzle
<< 8;
631 dcc_tile_swizzle
&= plane
->surface
.dcc_alignment
- 1;
632 meta_va
|= dcc_tile_swizzle
;
633 } else if (!disable_compression
&&
634 radv_image_is_tc_compat_htile(image
)) {
635 meta_va
= gpu_address
+ plane
->surface
.htile_offset
;
639 state
[6] |= S_008F28_COMPRESSION_EN(1);
640 if (chip_class
<= GFX9
)
641 state
[7] = meta_va
>> 8;
645 if (chip_class
>= GFX10
) {
646 state
[3] &= C_00A00C_SW_MODE
;
649 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
651 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
654 state
[6] &= C_00A018_META_DATA_ADDRESS_LO
&
655 C_00A018_META_PIPE_ALIGNED
;
658 struct gfx9_surf_meta_flags meta
= {
663 if (plane
->surface
.dcc_offset
)
664 meta
= plane
->surface
.u
.gfx9
.dcc
;
666 state
[6] |= S_00A018_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
667 S_00A018_META_DATA_ADDRESS_LO(meta_va
>> 8);
670 state
[7] = meta_va
>> 16;
671 } else if (chip_class
== GFX9
) {
672 state
[3] &= C_008F1C_SW_MODE
;
673 state
[4] &= C_008F20_PITCH
;
676 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
677 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.stencil
.epitch
);
679 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
680 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.surf
.epitch
);
683 state
[5] &= C_008F24_META_DATA_ADDRESS
&
684 C_008F24_META_PIPE_ALIGNED
&
685 C_008F24_META_RB_ALIGNED
;
687 struct gfx9_surf_meta_flags meta
= {
692 if (plane
->surface
.dcc_offset
)
693 meta
= plane
->surface
.u
.gfx9
.dcc
;
695 state
[5] |= S_008F24_META_DATA_ADDRESS(meta_va
>> 40) |
696 S_008F24_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
697 S_008F24_META_RB_ALIGNED(meta
.rb_aligned
);
701 unsigned pitch
= base_level_info
->nblk_x
* block_width
;
702 unsigned index
= si_tile_mode_index(plane
, base_level
, is_stencil
);
704 state
[3] &= C_008F1C_TILING_INDEX
;
705 state
[3] |= S_008F1C_TILING_INDEX(index
);
706 state
[4] &= C_008F20_PITCH
;
707 state
[4] |= S_008F20_PITCH(pitch
- 1);
711 static unsigned radv_tex_dim(VkImageType image_type
, VkImageViewType view_type
,
712 unsigned nr_layers
, unsigned nr_samples
, bool is_storage_image
, bool gfx9
)
714 if (view_type
== VK_IMAGE_VIEW_TYPE_CUBE
|| view_type
== VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
)
715 return is_storage_image
? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_CUBE
;
717 /* GFX9 allocates 1D textures as 2D. */
718 if (gfx9
&& image_type
== VK_IMAGE_TYPE_1D
)
719 image_type
= VK_IMAGE_TYPE_2D
;
720 switch (image_type
) {
721 case VK_IMAGE_TYPE_1D
:
722 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY
: V_008F1C_SQ_RSRC_IMG_1D
;
723 case VK_IMAGE_TYPE_2D
:
725 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D_MSAA
;
727 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D
;
728 case VK_IMAGE_TYPE_3D
:
729 if (view_type
== VK_IMAGE_VIEW_TYPE_3D
)
730 return V_008F1C_SQ_RSRC_IMG_3D
;
732 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY
;
734 unreachable("illegal image type");
738 static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle
[4])
740 unsigned bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
742 if (swizzle
[3] == VK_SWIZZLE_X
) {
743 /* For the pre-defined border color values (white, opaque
744 * black, transparent black), the only thing that matters is
745 * that the alpha channel winds up in the correct place
746 * (because the RGB channels are all the same) so either of
747 * these enumerations will work.
749 if (swizzle
[2] == VK_SWIZZLE_Y
)
750 bc_swizzle
= V_008F20_BC_SWIZZLE_WZYX
;
752 bc_swizzle
= V_008F20_BC_SWIZZLE_WXYZ
;
753 } else if (swizzle
[0] == VK_SWIZZLE_X
) {
754 if (swizzle
[1] == VK_SWIZZLE_Y
)
755 bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
757 bc_swizzle
= V_008F20_BC_SWIZZLE_XWYZ
;
758 } else if (swizzle
[1] == VK_SWIZZLE_X
) {
759 bc_swizzle
= V_008F20_BC_SWIZZLE_YXWZ
;
760 } else if (swizzle
[2] == VK_SWIZZLE_X
) {
761 bc_swizzle
= V_008F20_BC_SWIZZLE_ZYXW
;
767 bool vi_alpha_is_on_msb(struct radv_device
*device
, VkFormat format
)
769 const struct vk_format_description
*desc
= vk_format_description(format
);
771 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
&& desc
->nr_channels
== 1)
772 return desc
->swizzle
[3] == VK_SWIZZLE_X
;
774 return radv_translate_colorswap(format
, false) <= 1;
777 * Build the sampler view descriptor for a texture (GFX10).
780 gfx10_make_texture_descriptor(struct radv_device
*device
,
781 struct radv_image
*image
,
782 bool is_storage_image
,
783 VkImageViewType view_type
,
785 const VkComponentMapping
*mapping
,
786 unsigned first_level
, unsigned last_level
,
787 unsigned first_layer
, unsigned last_layer
,
788 unsigned width
, unsigned height
, unsigned depth
,
790 uint32_t *fmask_state
)
792 const struct vk_format_description
*desc
;
793 enum vk_swizzle swizzle
[4];
797 desc
= vk_format_description(vk_format
);
798 img_format
= gfx10_format_table
[vk_format_to_pipe_format(vk_format
)].img_format
;
800 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
801 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
802 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
804 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
807 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
808 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
809 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
811 depth
= image
->info
.array_size
;
812 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
813 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
814 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
815 depth
= image
->info
.array_size
;
816 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
817 depth
= image
->info
.array_size
/ 6;
820 state
[1] = S_00A004_FORMAT(img_format
) |
821 S_00A004_WIDTH_LO(width
- 1);
822 state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
823 S_00A008_HEIGHT(height
- 1) |
824 S_00A008_RESOURCE_LEVEL(1);
825 state
[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
826 S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
827 S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
828 S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
829 S_00A00C_BASE_LEVEL(image
->info
.samples
> 1 ?
831 S_00A00C_LAST_LEVEL(image
->info
.samples
> 1 ?
832 util_logbase2(image
->info
.samples
) :
834 S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(swizzle
)) |
836 /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
837 * to know the total number of layers.
839 state
[4] = S_00A010_DEPTH(type
== V_008F1C_SQ_RSRC_IMG_3D
? depth
- 1 : last_layer
) |
840 S_00A010_BASE_ARRAY(first_layer
);
841 state
[5] = S_00A014_ARRAY_PITCH(0) |
842 S_00A014_MAX_MIP(image
->info
.samples
> 1 ?
843 util_logbase2(image
->info
.samples
) :
844 image
->info
.levels
- 1) |
845 S_00A014_PERF_MOD(4);
849 if (radv_dcc_enabled(image
, first_level
)) {
850 state
[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B
) |
851 S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B
) |
852 S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
855 /* Initialize the sampler view for FMASK. */
856 if (radv_image_has_fmask(image
)) {
857 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
861 assert(image
->plane_count
== 1);
863 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.fmask_offset
;
865 switch (image
->info
.samples
) {
867 format
= V_008F0C_IMG_FORMAT_FMASK8_S2_F2
;
870 format
= V_008F0C_IMG_FORMAT_FMASK8_S4_F4
;
873 format
= V_008F0C_IMG_FORMAT_FMASK32_S8_F8
;
876 unreachable("invalid nr_samples");
879 fmask_state
[0] = (va
>> 8) | image
->planes
[0].surface
.fmask_tile_swizzle
;
880 fmask_state
[1] = S_00A004_BASE_ADDRESS_HI(va
>> 40) |
881 S_00A004_FORMAT(format
) |
882 S_00A004_WIDTH_LO(width
- 1);
883 fmask_state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
884 S_00A008_HEIGHT(height
- 1) |
885 S_00A008_RESOURCE_LEVEL(1);
886 fmask_state
[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
887 S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
888 S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
889 S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
890 S_00A00C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
) |
891 S_00A00C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
892 fmask_state
[4] = S_00A010_DEPTH(last_layer
) |
893 S_00A010_BASE_ARRAY(first_layer
);
895 fmask_state
[6] = S_00A018_META_PIPE_ALIGNED(1);
897 } else if (fmask_state
)
898 memset(fmask_state
, 0, 8 * 4);
902 * Build the sampler view descriptor for a texture (SI-GFX9)
905 si_make_texture_descriptor(struct radv_device
*device
,
906 struct radv_image
*image
,
907 bool is_storage_image
,
908 VkImageViewType view_type
,
910 const VkComponentMapping
*mapping
,
911 unsigned first_level
, unsigned last_level
,
912 unsigned first_layer
, unsigned last_layer
,
913 unsigned width
, unsigned height
, unsigned depth
,
915 uint32_t *fmask_state
)
917 const struct vk_format_description
*desc
;
918 enum vk_swizzle swizzle
[4];
920 unsigned num_format
, data_format
, type
;
922 desc
= vk_format_description(vk_format
);
924 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
925 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
926 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
928 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
931 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
933 num_format
= radv_translate_tex_numformat(vk_format
, desc
, first_non_void
);
934 if (num_format
== ~0) {
938 data_format
= radv_translate_tex_dataformat(vk_format
, desc
, first_non_void
);
939 if (data_format
== ~0) {
943 /* S8 with either Z16 or Z32 HTILE need a special format. */
944 if (device
->physical_device
->rad_info
.chip_class
== GFX9
&&
945 vk_format
== VK_FORMAT_S8_UINT
&&
946 radv_image_is_tc_compat_htile(image
)) {
947 if (image
->vk_format
== VK_FORMAT_D32_SFLOAT_S8_UINT
)
948 data_format
= V_008F14_IMG_DATA_FORMAT_S8_32
;
949 else if (image
->vk_format
== VK_FORMAT_D16_UNORM_S8_UINT
)
950 data_format
= V_008F14_IMG_DATA_FORMAT_S8_16
;
952 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
953 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
954 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
956 depth
= image
->info
.array_size
;
957 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
958 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
959 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
960 depth
= image
->info
.array_size
;
961 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
962 depth
= image
->info
.array_size
/ 6;
965 state
[1] = (S_008F14_DATA_FORMAT(data_format
) |
966 S_008F14_NUM_FORMAT(num_format
));
967 state
[2] = (S_008F18_WIDTH(width
- 1) |
968 S_008F18_HEIGHT(height
- 1) |
969 S_008F18_PERF_MOD(4));
970 state
[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
971 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
972 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
973 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
974 S_008F1C_BASE_LEVEL(image
->info
.samples
> 1 ?
976 S_008F1C_LAST_LEVEL(image
->info
.samples
> 1 ?
977 util_logbase2(image
->info
.samples
) :
979 S_008F1C_TYPE(type
));
981 state
[5] = S_008F24_BASE_ARRAY(first_layer
);
985 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
986 unsigned bc_swizzle
= gfx9_border_color_swizzle(swizzle
);
988 /* Depth is the last accessible layer on Gfx9.
989 * The hw doesn't need to know the total number of layers.
991 if (type
== V_008F1C_SQ_RSRC_IMG_3D
)
992 state
[4] |= S_008F20_DEPTH(depth
- 1);
994 state
[4] |= S_008F20_DEPTH(last_layer
);
996 state
[4] |= S_008F20_BC_SWIZZLE(bc_swizzle
);
997 state
[5] |= S_008F24_MAX_MIP(image
->info
.samples
> 1 ?
998 util_logbase2(image
->info
.samples
) :
999 image
->info
.levels
- 1);
1001 state
[3] |= S_008F1C_POW2_PAD(image
->info
.levels
> 1);
1002 state
[4] |= S_008F20_DEPTH(depth
- 1);
1003 state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
1005 if (image
->planes
[0].surface
.dcc_offset
) {
1006 state
[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
1008 /* The last dword is unused by hw. The shader uses it to clear
1009 * bits in the first dword of sampler state.
1011 if (device
->physical_device
->rad_info
.chip_class
<= GFX7
&& image
->info
.samples
<= 1) {
1012 if (first_level
== last_level
)
1013 state
[7] = C_008F30_MAX_ANISO_RATIO
;
1015 state
[7] = 0xffffffff;
1019 /* Initialize the sampler view for FMASK. */
1020 if (radv_image_has_fmask(image
)) {
1021 uint32_t fmask_format
, num_format
;
1022 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
1025 assert(image
->plane_count
== 1);
1027 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.fmask_offset
;
1029 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
1030 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK
;
1031 switch (image
->info
.samples
) {
1033 num_format
= V_008F14_IMG_FMASK_8_2_2
;
1036 num_format
= V_008F14_IMG_FMASK_8_4_4
;
1039 num_format
= V_008F14_IMG_FMASK_32_8_8
;
1042 unreachable("invalid nr_samples");
1045 switch (image
->info
.samples
) {
1047 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2
;
1050 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4
;
1053 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8
;
1057 fmask_format
= V_008F14_IMG_DATA_FORMAT_INVALID
;
1059 num_format
= V_008F14_IMG_NUM_FORMAT_UINT
;
1062 fmask_state
[0] = va
>> 8;
1063 fmask_state
[0] |= image
->planes
[0].surface
.fmask_tile_swizzle
;
1064 fmask_state
[1] = S_008F14_BASE_ADDRESS_HI(va
>> 40) |
1065 S_008F14_DATA_FORMAT(fmask_format
) |
1066 S_008F14_NUM_FORMAT(num_format
);
1067 fmask_state
[2] = S_008F18_WIDTH(width
- 1) |
1068 S_008F18_HEIGHT(height
- 1);
1069 fmask_state
[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
1070 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
1071 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
1072 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
1073 S_008F1C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
1075 fmask_state
[5] = S_008F24_BASE_ARRAY(first_layer
);
1079 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
1080 fmask_state
[3] |= S_008F1C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
);
1081 fmask_state
[4] |= S_008F20_DEPTH(last_layer
) |
1082 S_008F20_PITCH(image
->planes
[0].surface
.u
.gfx9
.fmask
.epitch
);
1083 fmask_state
[5] |= S_008F24_META_PIPE_ALIGNED(1) |
1084 S_008F24_META_RB_ALIGNED(1);
1086 if (radv_image_is_tc_compat_cmask(image
)) {
1087 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.cmask_offset
;
1089 fmask_state
[5] |= S_008F24_META_DATA_ADDRESS(va
>> 40);
1090 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
1091 fmask_state
[7] |= va
>> 8;
1094 fmask_state
[3] |= S_008F1C_TILING_INDEX(image
->planes
[0].surface
.u
.legacy
.fmask
.tiling_index
);
1095 fmask_state
[4] |= S_008F20_DEPTH(depth
- 1) |
1096 S_008F20_PITCH(image
->planes
[0].surface
.u
.legacy
.fmask
.pitch_in_pixels
- 1);
1097 fmask_state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
1099 if (radv_image_is_tc_compat_cmask(image
)) {
1100 va
= gpu_address
+ image
->offset
+ image
->planes
[0].surface
.cmask_offset
;
1102 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
1103 fmask_state
[7] |= va
>> 8;
1106 } else if (fmask_state
)
1107 memset(fmask_state
, 0, 8 * 4);
1111 radv_make_texture_descriptor(struct radv_device
*device
,
1112 struct radv_image
*image
,
1113 bool is_storage_image
,
1114 VkImageViewType view_type
,
1116 const VkComponentMapping
*mapping
,
1117 unsigned first_level
, unsigned last_level
,
1118 unsigned first_layer
, unsigned last_layer
,
1119 unsigned width
, unsigned height
, unsigned depth
,
1121 uint32_t *fmask_state
)
1123 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
1124 gfx10_make_texture_descriptor(device
, image
, is_storage_image
,
1125 view_type
, vk_format
, mapping
,
1126 first_level
, last_level
,
1127 first_layer
, last_layer
,
1128 width
, height
, depth
,
1129 state
, fmask_state
);
1131 si_make_texture_descriptor(device
, image
, is_storage_image
,
1132 view_type
, vk_format
, mapping
,
1133 first_level
, last_level
,
1134 first_layer
, last_layer
,
1135 width
, height
, depth
,
1136 state
, fmask_state
);
1141 radv_query_opaque_metadata(struct radv_device
*device
,
1142 struct radv_image
*image
,
1143 struct radeon_bo_metadata
*md
)
1145 static const VkComponentMapping fixedmapping
;
1146 uint32_t desc
[8], i
;
1148 assert(image
->plane_count
== 1);
1150 /* Metadata image format format version 1:
1151 * [0] = 1 (metadata format identifier)
1152 * [1] = (VENDOR_ID << 16) | PCI_ID
1153 * [2:9] = image descriptor for the whole resource
1154 * [2] is always 0, because the base address is cleared
1155 * [9] is the DCC offset bits [39:8] from the beginning of
1157 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
1159 md
->metadata
[0] = 1; /* metadata image format version 1 */
1161 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
1162 md
->metadata
[1] = si_get_bo_metadata_word1(device
);
1165 radv_make_texture_descriptor(device
, image
, false,
1166 (VkImageViewType
)image
->type
, image
->vk_format
,
1167 &fixedmapping
, 0, image
->info
.levels
- 1, 0,
1168 image
->info
.array_size
- 1,
1169 image
->info
.width
, image
->info
.height
,
1173 si_set_mutable_tex_desc_fields(device
, image
, &image
->planes
[0].surface
.u
.legacy
.level
[0], 0, 0, 0,
1174 image
->planes
[0].surface
.blk_w
, false, false, false, desc
);
1176 /* Clear the base address and set the relative DCC offset. */
1178 desc
[1] &= C_008F14_BASE_ADDRESS_HI
;
1179 desc
[7] = image
->planes
[0].surface
.dcc_offset
>> 8;
1181 /* Dwords [2:9] contain the image descriptor. */
1182 memcpy(&md
->metadata
[2], desc
, sizeof(desc
));
1184 /* Dwords [10:..] contain the mipmap level offsets. */
1185 if (device
->physical_device
->rad_info
.chip_class
<= GFX8
) {
1186 for (i
= 0; i
<= image
->info
.levels
- 1; i
++)
1187 md
->metadata
[10+i
] = image
->planes
[0].surface
.u
.legacy
.level
[i
].offset
>> 8;
1188 md
->size_metadata
= (11 + image
->info
.levels
- 1) * 4;
1190 md
->size_metadata
= 10 * 4;
1194 radv_init_metadata(struct radv_device
*device
,
1195 struct radv_image
*image
,
1196 struct radeon_bo_metadata
*metadata
)
1198 struct radeon_surf
*surface
= &image
->planes
[0].surface
;
1200 memset(metadata
, 0, sizeof(*metadata
));
1202 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1203 metadata
->u
.gfx9
.swizzle_mode
= surface
->u
.gfx9
.surf
.swizzle_mode
;
1204 metadata
->u
.gfx9
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
1206 metadata
->u
.legacy
.microtile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_1D
?
1207 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1208 metadata
->u
.legacy
.macrotile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_2D
?
1209 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1210 metadata
->u
.legacy
.pipe_config
= surface
->u
.legacy
.pipe_config
;
1211 metadata
->u
.legacy
.bankw
= surface
->u
.legacy
.bankw
;
1212 metadata
->u
.legacy
.bankh
= surface
->u
.legacy
.bankh
;
1213 metadata
->u
.legacy
.tile_split
= surface
->u
.legacy
.tile_split
;
1214 metadata
->u
.legacy
.mtilea
= surface
->u
.legacy
.mtilea
;
1215 metadata
->u
.legacy
.num_banks
= surface
->u
.legacy
.num_banks
;
1216 metadata
->u
.legacy
.stride
= surface
->u
.legacy
.level
[0].nblk_x
* surface
->bpe
;
1217 metadata
->u
.legacy
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
1219 radv_query_opaque_metadata(device
, image
, metadata
);
1223 radv_image_override_offset_stride(struct radv_device
*device
,
1224 struct radv_image
*image
,
1225 uint64_t offset
, uint32_t stride
)
1227 ac_surface_override_offset_stride(&device
->physical_device
->rad_info
,
1228 &image
->planes
[0].surface
,
1229 image
->info
.levels
, offset
, stride
);
1233 radv_image_alloc_fmask(struct radv_device
*device
,
1234 struct radv_image
*image
)
1236 unsigned fmask_alignment
= image
->planes
[0].surface
.fmask_alignment
;
1238 image
->planes
[0].surface
.fmask_offset
= align64(image
->size
, fmask_alignment
);
1239 image
->size
= image
->planes
[0].surface
.fmask_offset
+ image
->planes
[0].surface
.fmask_size
;
1240 image
->alignment
= MAX2(image
->alignment
, fmask_alignment
);
1244 radv_image_alloc_cmask(struct radv_device
*device
,
1245 struct radv_image
*image
)
1247 unsigned cmask_alignment
= image
->planes
[0].surface
.cmask_alignment
;
1248 unsigned cmask_size
= image
->planes
[0].surface
.cmask_size
;
1253 assert(cmask_alignment
);
1255 image
->planes
[0].surface
.cmask_offset
= align64(image
->size
, cmask_alignment
);
1256 image
->size
= image
->planes
[0].surface
.cmask_offset
+ cmask_size
;
1257 image
->alignment
= MAX2(image
->alignment
, cmask_alignment
);
1261 radv_image_alloc_dcc(struct radv_image
*image
)
1263 assert(image
->plane_count
== 1);
1265 image
->planes
[0].surface
.dcc_offset
= align64(image
->size
, image
->planes
[0].surface
.dcc_alignment
);
1266 image
->size
= image
->planes
[0].surface
.dcc_offset
+ image
->planes
[0].surface
.dcc_size
;
1267 image
->alignment
= MAX2(image
->alignment
, image
->planes
[0].surface
.dcc_alignment
);
1271 radv_image_alloc_htile(struct radv_device
*device
, struct radv_image
*image
)
1273 image
->planes
[0].surface
.htile_offset
= align64(image
->size
, image
->planes
[0].surface
.htile_alignment
);
1275 image
->size
= image
->clear_value_offset
;
1276 image
->alignment
= align64(image
->alignment
, image
->planes
[0].surface
.htile_alignment
);
1280 radv_image_alloc_values(const struct radv_device
*device
, struct radv_image
*image
)
1282 if (radv_image_has_dcc(image
)) {
1283 image
->fce_pred_offset
= image
->size
;
1284 image
->size
+= 8 * image
->info
.levels
;
1286 image
->dcc_pred_offset
= image
->size
;
1287 image
->size
+= 8 * image
->info
.levels
;
1290 if (radv_image_has_dcc(image
) || radv_image_has_cmask(image
) ||
1291 radv_image_has_htile(image
)) {
1292 image
->clear_value_offset
= image
->size
;
1293 image
->size
+= 8 * image
->info
.levels
;
1296 if (radv_image_is_tc_compat_htile(image
) &&
1297 device
->physical_device
->rad_info
.has_tc_compat_zrange_bug
) {
1298 /* Metadata for the TC-compatible HTILE hardware bug which
1299 * have to be fixed by updating ZRANGE_PRECISION when doing
1300 * fast depth clears to 0.0f.
1302 image
->tc_compat_zrange_offset
= image
->size
;
1303 image
->size
+= image
->info
.levels
* 4;
1308 radv_image_can_enable_cmask(struct radv_image
*image
)
1310 if (image
->planes
[0].surface
.bpe
> 8 && image
->info
.samples
== 1) {
1311 /* Do not enable CMASK for non-MSAA images (fast color clear)
1312 * because 128 bit formats are not supported, but FMASK might
1318 return radv_image_use_fast_clear_for_image(image
) &&
1319 image
->info
.levels
== 1 &&
1320 image
->info
.depth
== 1;
1323 static void radv_image_disable_dcc(struct radv_image
*image
)
1325 for (unsigned i
= 0; i
< image
->plane_count
; ++i
)
1326 image
->planes
[i
].surface
.dcc_size
= 0;
1329 static void radv_image_disable_htile(struct radv_image
*image
)
1331 for (unsigned i
= 0; i
< image
->plane_count
; ++i
)
1332 image
->planes
[i
].surface
.htile_size
= 0;
1336 radv_image_create_layout(struct radv_device
*device
,
1337 struct radv_image_create_info create_info
,
1338 struct radv_image
*image
)
1340 /* Check that we did not initialize things earlier */
1341 assert(!image
->planes
[0].surface
.surf_size
);
1343 /* Clear the pCreateInfo pointer so we catch issues in the delayed case when we test in the
1344 * common internal case. */
1345 create_info
.vk_info
= NULL
;
1347 struct ac_surf_info image_info
= image
->info
;
1348 VkResult result
= radv_patch_image_from_extra_info(device
, image
, &create_info
, &image_info
);
1349 if (result
!= VK_SUCCESS
)
1353 image
->alignment
= 1;
1354 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1355 struct ac_surf_info info
= image_info
;
1358 const struct vk_format_description
*desc
= vk_format_description(image
->vk_format
);
1359 assert(info
.width
% desc
->width_divisor
== 0);
1360 assert(info
.height
% desc
->height_divisor
== 0);
1362 info
.width
/= desc
->width_divisor
;
1363 info
.height
/= desc
->height_divisor
;
1366 if (create_info
.no_metadata_planes
|| image
->plane_count
> 1) {
1367 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_DISABLE_DCC
|
1368 RADEON_SURF_NO_FMASK
|
1369 RADEON_SURF_NO_HTILE
;
1372 device
->ws
->surface_init(device
->ws
, &info
, &image
->planes
[plane
].surface
);
1374 image
->planes
[plane
].offset
= align(image
->size
, image
->planes
[plane
].surface
.surf_alignment
);
1375 image
->size
= image
->planes
[plane
].offset
+ image
->planes
[plane
].surface
.surf_size
;
1376 image
->alignment
= image
->planes
[plane
].surface
.surf_alignment
;
1378 image
->planes
[plane
].format
= vk_format_get_plane_format(image
->vk_format
, plane
);
1381 /* Try to enable DCC first. */
1382 if (radv_image_has_dcc(image
)) {
1383 radv_image_alloc_dcc(image
);
1384 if (image
->info
.samples
> 1) {
1385 /* CMASK should be enabled because DCC fast
1386 * clear with MSAA needs it.
1388 assert(radv_image_can_enable_cmask(image
));
1389 radv_image_alloc_cmask(device
, image
);
1392 /* When DCC cannot be enabled, try CMASK. */
1393 radv_image_disable_dcc(image
);
1394 if (radv_image_can_enable_cmask(image
)) {
1395 radv_image_alloc_cmask(device
, image
);
1399 /* Try to enable FMASK for multisampled images. */
1400 if (image
->planes
[0].surface
.fmask_size
) {
1401 radv_image_alloc_fmask(device
, image
);
1403 if (radv_use_tc_compat_cmask_for_image(device
, image
))
1404 image
->tc_compatible_cmask
= true;
1406 /* Otherwise, try to enable HTILE for depth surfaces. */
1407 if (radv_image_has_htile(image
)) {
1408 image
->tc_compatible_htile
= image
->planes
[0].surface
.flags
& RADEON_SURF_TC_COMPATIBLE_HTILE
;
1409 radv_image_alloc_htile(device
, image
);
1411 radv_image_disable_htile(image
);
1415 radv_image_alloc_values(device
, image
);
1417 assert(image
->planes
[0].surface
.surf_size
);
1422 radv_image_create(VkDevice _device
,
1423 const struct radv_image_create_info
*create_info
,
1424 const VkAllocationCallbacks
* alloc
,
1427 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1428 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
1429 struct radv_image
*image
= NULL
;
1430 VkFormat format
= radv_select_android_external_format(pCreateInfo
->pNext
,
1431 pCreateInfo
->format
);
1432 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
1434 const unsigned plane_count
= vk_format_get_plane_count(format
);
1435 const size_t image_struct_size
= sizeof(*image
) + sizeof(struct radv_image_plane
) * plane_count
;
1437 radv_assert(pCreateInfo
->mipLevels
> 0);
1438 radv_assert(pCreateInfo
->arrayLayers
> 0);
1439 radv_assert(pCreateInfo
->samples
> 0);
1440 radv_assert(pCreateInfo
->extent
.width
> 0);
1441 radv_assert(pCreateInfo
->extent
.height
> 0);
1442 radv_assert(pCreateInfo
->extent
.depth
> 0);
1444 image
= vk_zalloc2(&device
->vk
.alloc
, alloc
, image_struct_size
, 8,
1445 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1447 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1449 vk_object_base_init(&device
->vk
, &image
->base
, VK_OBJECT_TYPE_IMAGE
);
1451 image
->type
= pCreateInfo
->imageType
;
1452 image
->info
.width
= pCreateInfo
->extent
.width
;
1453 image
->info
.height
= pCreateInfo
->extent
.height
;
1454 image
->info
.depth
= pCreateInfo
->extent
.depth
;
1455 image
->info
.samples
= pCreateInfo
->samples
;
1456 image
->info
.storage_samples
= pCreateInfo
->samples
;
1457 image
->info
.array_size
= pCreateInfo
->arrayLayers
;
1458 image
->info
.levels
= pCreateInfo
->mipLevels
;
1459 image
->info
.num_channels
= vk_format_get_nr_components(format
);
1461 image
->vk_format
= format
;
1462 image
->tiling
= pCreateInfo
->tiling
;
1463 image
->usage
= pCreateInfo
->usage
;
1464 image
->flags
= pCreateInfo
->flags
;
1465 image
->plane_count
= plane_count
;
1467 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
1468 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
1469 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
1470 if (pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_EXTERNAL
||
1471 pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_FOREIGN_EXT
)
1472 image
->queue_family_mask
|= (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1474 image
->queue_family_mask
|= 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
1477 const VkExternalMemoryImageCreateInfo
*external_info
=
1478 vk_find_struct_const(pCreateInfo
->pNext
,
1479 EXTERNAL_MEMORY_IMAGE_CREATE_INFO
) ;
1481 image
->shareable
= external_info
;
1482 if (!vk_format_is_depth_or_stencil(format
) && !image
->shareable
) {
1483 image
->info
.surf_index
= &device
->image_mrt_offset_counter
;
1486 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1487 radv_init_surface(device
, image
, &image
->planes
[plane
].surface
, plane
, pCreateInfo
, format
);
1490 bool delay_layout
= external_info
&&
1491 (external_info
->handleTypes
& VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID
);
1494 *pImage
= radv_image_to_handle(image
);
1495 assert (!(image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
));
1499 ASSERTED VkResult result
= radv_image_create_layout(device
, *create_info
, image
);
1500 assert(result
== VK_SUCCESS
);
1502 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
) {
1503 image
->alignment
= MAX2(image
->alignment
, 4096);
1504 image
->size
= align64(image
->size
, image
->alignment
);
1507 image
->bo
= device
->ws
->buffer_create(device
->ws
, image
->size
, image
->alignment
,
1508 0, RADEON_FLAG_VIRTUAL
, RADV_BO_PRIORITY_VIRTUAL
);
1510 vk_free2(&device
->vk
.alloc
, alloc
, image
);
1511 return vk_error(device
->instance
, VK_ERROR_OUT_OF_DEVICE_MEMORY
);
1515 *pImage
= radv_image_to_handle(image
);
1521 radv_image_view_make_descriptor(struct radv_image_view
*iview
,
1522 struct radv_device
*device
,
1524 const VkComponentMapping
*components
,
1525 bool is_storage_image
, bool disable_compression
,
1526 unsigned plane_id
, unsigned descriptor_plane_id
)
1528 struct radv_image
*image
= iview
->image
;
1529 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1530 const struct vk_format_description
*format_desc
= vk_format_description(image
->vk_format
);
1531 bool is_stencil
= iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
;
1533 union radv_descriptor
*descriptor
;
1534 uint32_t hw_level
= 0;
1536 if (is_storage_image
) {
1537 descriptor
= &iview
->storage_descriptor
;
1539 descriptor
= &iview
->descriptor
;
1542 assert(vk_format_get_plane_count(vk_format
) == 1);
1543 assert(plane
->surface
.blk_w
% vk_format_get_blockwidth(plane
->format
) == 0);
1544 blk_w
= plane
->surface
.blk_w
/ vk_format_get_blockwidth(plane
->format
) * vk_format_get_blockwidth(vk_format
);
1546 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
)
1547 hw_level
= iview
->base_mip
;
1548 radv_make_texture_descriptor(device
, image
, is_storage_image
,
1552 hw_level
, hw_level
+ iview
->level_count
- 1,
1554 iview
->base_layer
+ iview
->layer_count
- 1,
1555 iview
->extent
.width
/ (plane_id
? format_desc
->width_divisor
: 1),
1556 iview
->extent
.height
/ (plane_id
? format_desc
->height_divisor
: 1),
1557 iview
->extent
.depth
,
1558 descriptor
->plane_descriptors
[descriptor_plane_id
],
1559 descriptor_plane_id
? NULL
: descriptor
->fmask_descriptor
);
1561 const struct legacy_surf_level
*base_level_info
= NULL
;
1562 if (device
->physical_device
->rad_info
.chip_class
<= GFX9
) {
1564 base_level_info
= &plane
->surface
.u
.legacy
.stencil_level
[iview
->base_mip
];
1566 base_level_info
= &plane
->surface
.u
.legacy
.level
[iview
->base_mip
];
1568 si_set_mutable_tex_desc_fields(device
, image
,
1573 blk_w
, is_stencil
, is_storage_image
,
1574 is_storage_image
|| disable_compression
,
1575 descriptor
->plane_descriptors
[descriptor_plane_id
]);
1579 radv_plane_from_aspect(VkImageAspectFlags mask
)
1582 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1584 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1592 radv_get_aspect_format(struct radv_image
*image
, VkImageAspectFlags mask
)
1595 case VK_IMAGE_ASPECT_PLANE_0_BIT
:
1596 return image
->planes
[0].format
;
1597 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1598 return image
->planes
[1].format
;
1599 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1600 return image
->planes
[2].format
;
1601 case VK_IMAGE_ASPECT_STENCIL_BIT
:
1602 return vk_format_stencil_only(image
->vk_format
);
1603 case VK_IMAGE_ASPECT_DEPTH_BIT
:
1604 return vk_format_depth_only(image
->vk_format
);
1605 case VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
:
1606 return vk_format_depth_only(image
->vk_format
);
1608 return image
->vk_format
;
1613 radv_image_view_init(struct radv_image_view
*iview
,
1614 struct radv_device
*device
,
1615 const VkImageViewCreateInfo
* pCreateInfo
,
1616 const struct radv_image_view_extra_create_info
* extra_create_info
)
1618 RADV_FROM_HANDLE(radv_image
, image
, pCreateInfo
->image
);
1619 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
1621 switch (image
->type
) {
1622 case VK_IMAGE_TYPE_1D
:
1623 case VK_IMAGE_TYPE_2D
:
1624 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1 <= image
->info
.array_size
);
1626 case VK_IMAGE_TYPE_3D
:
1627 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1
1628 <= radv_minify(image
->info
.depth
, range
->baseMipLevel
));
1631 unreachable("bad VkImageType");
1633 iview
->image
= image
;
1634 iview
->bo
= image
->bo
;
1635 iview
->type
= pCreateInfo
->viewType
;
1636 iview
->plane_id
= radv_plane_from_aspect(pCreateInfo
->subresourceRange
.aspectMask
);
1637 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
1638 iview
->multiple_planes
= vk_format_get_plane_count(image
->vk_format
) > 1 && iview
->aspect_mask
== VK_IMAGE_ASPECT_COLOR_BIT
;
1640 iview
->vk_format
= pCreateInfo
->format
;
1642 /* If the image has an Android external format, pCreateInfo->format will be
1643 * VK_FORMAT_UNDEFINED. */
1644 if (iview
->vk_format
== VK_FORMAT_UNDEFINED
)
1645 iview
->vk_format
= image
->vk_format
;
1647 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
1648 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
1649 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
1650 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
1653 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1654 iview
->extent
= (VkExtent3D
) {
1655 .width
= image
->info
.width
,
1656 .height
= image
->info
.height
,
1657 .depth
= image
->info
.depth
,
1660 iview
->extent
= (VkExtent3D
) {
1661 .width
= radv_minify(image
->info
.width
, range
->baseMipLevel
),
1662 .height
= radv_minify(image
->info
.height
, range
->baseMipLevel
),
1663 .depth
= radv_minify(image
->info
.depth
, range
->baseMipLevel
),
1667 if (iview
->vk_format
!= image
->planes
[iview
->plane_id
].format
) {
1668 unsigned view_bw
= vk_format_get_blockwidth(iview
->vk_format
);
1669 unsigned view_bh
= vk_format_get_blockheight(iview
->vk_format
);
1670 unsigned img_bw
= vk_format_get_blockwidth(image
->vk_format
);
1671 unsigned img_bh
= vk_format_get_blockheight(image
->vk_format
);
1673 iview
->extent
.width
= round_up_u32(iview
->extent
.width
* view_bw
, img_bw
);
1674 iview
->extent
.height
= round_up_u32(iview
->extent
.height
* view_bh
, img_bh
);
1676 /* Comment ported from amdvlk -
1677 * If we have the following image:
1678 * Uncompressed pixels Compressed block sizes (4x4)
1679 * mip0: 22 x 22 6 x 6
1680 * mip1: 11 x 11 3 x 3
1685 * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and the HW is
1686 * calculating the degradation of the block sizes down the mip-chain as follows (straight-up
1687 * divide-by-two integer math):
1693 * This means that mip2 will be missing texels.
1695 * Fix this by calculating the base mip's width and height, then convert that, and round it
1696 * back up to get the level 0 size.
1697 * Clamp the converted size between the original values, and next power of two, which
1698 * means we don't oversize the image.
1700 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
1701 vk_format_is_compressed(image
->vk_format
) &&
1702 !vk_format_is_compressed(iview
->vk_format
)) {
1703 unsigned lvl_width
= radv_minify(image
->info
.width
, range
->baseMipLevel
);
1704 unsigned lvl_height
= radv_minify(image
->info
.height
, range
->baseMipLevel
);
1706 lvl_width
= round_up_u32(lvl_width
* view_bw
, img_bw
);
1707 lvl_height
= round_up_u32(lvl_height
* view_bh
, img_bh
);
1709 lvl_width
<<= range
->baseMipLevel
;
1710 lvl_height
<<= range
->baseMipLevel
;
1712 iview
->extent
.width
= CLAMP(lvl_width
, iview
->extent
.width
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_pitch
);
1713 iview
->extent
.height
= CLAMP(lvl_height
, iview
->extent
.height
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_height
);
1717 iview
->base_layer
= range
->baseArrayLayer
;
1718 iview
->layer_count
= radv_get_layerCount(image
, range
);
1719 iview
->base_mip
= range
->baseMipLevel
;
1720 iview
->level_count
= radv_get_levelCount(image
, range
);
1722 bool disable_compression
= extra_create_info
? extra_create_info
->disable_compression
: false;
1723 for (unsigned i
= 0; i
< (iview
->multiple_planes
? vk_format_get_plane_count(image
->vk_format
) : 1); ++i
) {
1724 VkFormat format
= vk_format_get_plane_format(iview
->vk_format
, i
);
1725 radv_image_view_make_descriptor(iview
, device
, format
,
1726 &pCreateInfo
->components
,
1727 false, disable_compression
,
1728 iview
->plane_id
+ i
, i
);
1729 radv_image_view_make_descriptor(iview
, device
,
1730 format
, &pCreateInfo
->components
,
1731 true, disable_compression
,
1732 iview
->plane_id
+ i
, i
);
1736 bool radv_layout_is_htile_compressed(const struct radv_image
*image
,
1737 VkImageLayout layout
,
1738 bool in_render_loop
,
1739 unsigned queue_mask
)
1741 if (radv_image_is_tc_compat_htile(image
)) {
1742 if (layout
== VK_IMAGE_LAYOUT_GENERAL
&&
1744 !(image
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
)) {
1745 /* It should be safe to enable TC-compat HTILE with
1746 * VK_IMAGE_LAYOUT_GENERAL if we are not in a render
1747 * loop and if the image doesn't have the storage bit
1748 * set. This improves performance for apps that use
1749 * GENERAL for the main depth pass because this allows
1750 * compression and this reduces the number of
1751 * decompressions from/to GENERAL.
1756 return layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1759 return radv_image_has_htile(image
) &&
1760 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
1761 layout
== VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL_KHR
||
1762 layout
== VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL_KHR
||
1763 (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1764 queue_mask
== (1u << RADV_QUEUE_GENERAL
)));
1767 bool radv_layout_can_fast_clear(const struct radv_image
*image
,
1768 VkImageLayout layout
,
1769 bool in_render_loop
,
1770 unsigned queue_mask
)
1772 return layout
== VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
;
1775 bool radv_layout_dcc_compressed(const struct radv_device
*device
,
1776 const struct radv_image
*image
,
1777 VkImageLayout layout
,
1778 bool in_render_loop
,
1779 unsigned queue_mask
)
1781 /* Don't compress compute transfer dst, as image stores are not supported. */
1782 if (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1783 (queue_mask
& (1u << RADV_QUEUE_COMPUTE
)))
1786 return radv_image_has_dcc(image
) && layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1790 unsigned radv_image_queue_family_mask(const struct radv_image
*image
, uint32_t family
, uint32_t queue_family
)
1792 if (!image
->exclusive
)
1793 return image
->queue_family_mask
;
1794 if (family
== VK_QUEUE_FAMILY_EXTERNAL
||
1795 family
== VK_QUEUE_FAMILY_FOREIGN_EXT
)
1796 return (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1797 if (family
== VK_QUEUE_FAMILY_IGNORED
)
1798 return 1u << queue_family
;
1799 return 1u << family
;
1803 radv_CreateImage(VkDevice device
,
1804 const VkImageCreateInfo
*pCreateInfo
,
1805 const VkAllocationCallbacks
*pAllocator
,
1809 const VkNativeBufferANDROID
*gralloc_info
=
1810 vk_find_struct_const(pCreateInfo
->pNext
, NATIVE_BUFFER_ANDROID
);
1813 return radv_image_from_gralloc(device
, pCreateInfo
, gralloc_info
,
1814 pAllocator
, pImage
);
1817 const struct wsi_image_create_info
*wsi_info
=
1818 vk_find_struct_const(pCreateInfo
->pNext
, WSI_IMAGE_CREATE_INFO_MESA
);
1819 bool scanout
= wsi_info
&& wsi_info
->scanout
;
1821 return radv_image_create(device
,
1822 &(struct radv_image_create_info
) {
1823 .vk_info
= pCreateInfo
,
1831 radv_DestroyImage(VkDevice _device
, VkImage _image
,
1832 const VkAllocationCallbacks
*pAllocator
)
1834 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1835 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1840 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
)
1841 device
->ws
->buffer_destroy(image
->bo
);
1843 if (image
->owned_memory
!= VK_NULL_HANDLE
)
1844 radv_FreeMemory(_device
, image
->owned_memory
, pAllocator
);
1846 vk_object_base_finish(&image
->base
);
1847 vk_free2(&device
->vk
.alloc
, pAllocator
, image
);
1850 void radv_GetImageSubresourceLayout(
1853 const VkImageSubresource
* pSubresource
,
1854 VkSubresourceLayout
* pLayout
)
1856 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1857 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1858 int level
= pSubresource
->mipLevel
;
1859 int layer
= pSubresource
->arrayLayer
;
1861 unsigned plane_id
= radv_plane_from_aspect(pSubresource
->aspectMask
);
1863 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1864 struct radeon_surf
*surface
= &plane
->surface
;
1866 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1867 uint64_t level_offset
= surface
->is_linear
? surface
->u
.gfx9
.offset
[level
] : 0;
1869 pLayout
->offset
= plane
->offset
+ level_offset
+ surface
->u
.gfx9
.surf_slice_size
* layer
;
1870 if (image
->vk_format
== VK_FORMAT_R32G32B32_UINT
||
1871 image
->vk_format
== VK_FORMAT_R32G32B32_SINT
||
1872 image
->vk_format
== VK_FORMAT_R32G32B32_SFLOAT
) {
1873 /* Adjust the number of bytes between each row because
1874 * the pitch is actually the number of components per
1877 pLayout
->rowPitch
= surface
->u
.gfx9
.surf_pitch
* surface
->bpe
/ 3;
1879 uint32_t pitch
= surface
->is_linear
? surface
->u
.gfx9
.pitch
[level
] : surface
->u
.gfx9
.surf_pitch
;
1881 assert(util_is_power_of_two_nonzero(surface
->bpe
));
1882 pLayout
->rowPitch
= pitch
* surface
->bpe
;
1885 pLayout
->arrayPitch
= surface
->u
.gfx9
.surf_slice_size
;
1886 pLayout
->depthPitch
= surface
->u
.gfx9
.surf_slice_size
;
1887 pLayout
->size
= surface
->u
.gfx9
.surf_slice_size
;
1888 if (image
->type
== VK_IMAGE_TYPE_3D
)
1889 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1891 pLayout
->offset
= plane
->offset
+ surface
->u
.legacy
.level
[level
].offset
+ (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4 * layer
;
1892 pLayout
->rowPitch
= surface
->u
.legacy
.level
[level
].nblk_x
* surface
->bpe
;
1893 pLayout
->arrayPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1894 pLayout
->depthPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1895 pLayout
->size
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1896 if (image
->type
== VK_IMAGE_TYPE_3D
)
1897 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1903 radv_CreateImageView(VkDevice _device
,
1904 const VkImageViewCreateInfo
*pCreateInfo
,
1905 const VkAllocationCallbacks
*pAllocator
,
1908 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1909 struct radv_image_view
*view
;
1911 view
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, sizeof(*view
), 8,
1912 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1914 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1916 vk_object_base_init(&device
->vk
, &view
->base
,
1917 VK_OBJECT_TYPE_IMAGE_VIEW
);
1919 radv_image_view_init(view
, device
, pCreateInfo
, NULL
);
1921 *pView
= radv_image_view_to_handle(view
);
1927 radv_DestroyImageView(VkDevice _device
, VkImageView _iview
,
1928 const VkAllocationCallbacks
*pAllocator
)
1930 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1931 RADV_FROM_HANDLE(radv_image_view
, iview
, _iview
);
1936 vk_object_base_finish(&iview
->base
);
1937 vk_free2(&device
->vk
.alloc
, pAllocator
, iview
);
1940 void radv_buffer_view_init(struct radv_buffer_view
*view
,
1941 struct radv_device
*device
,
1942 const VkBufferViewCreateInfo
* pCreateInfo
)
1944 RADV_FROM_HANDLE(radv_buffer
, buffer
, pCreateInfo
->buffer
);
1946 view
->bo
= buffer
->bo
;
1947 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
?
1948 buffer
->size
- pCreateInfo
->offset
: pCreateInfo
->range
;
1949 view
->vk_format
= pCreateInfo
->format
;
1951 radv_make_buffer_descriptor(device
, buffer
, view
->vk_format
,
1952 pCreateInfo
->offset
, view
->range
, view
->state
);
1956 radv_CreateBufferView(VkDevice _device
,
1957 const VkBufferViewCreateInfo
*pCreateInfo
,
1958 const VkAllocationCallbacks
*pAllocator
,
1959 VkBufferView
*pView
)
1961 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1962 struct radv_buffer_view
*view
;
1964 view
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, sizeof(*view
), 8,
1965 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1967 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1969 vk_object_base_init(&device
->vk
, &view
->base
,
1970 VK_OBJECT_TYPE_BUFFER_VIEW
);
1972 radv_buffer_view_init(view
, device
, pCreateInfo
);
1974 *pView
= radv_buffer_view_to_handle(view
);
1980 radv_DestroyBufferView(VkDevice _device
, VkBufferView bufferView
,
1981 const VkAllocationCallbacks
*pAllocator
)
1983 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1984 RADV_FROM_HANDLE(radv_buffer_view
, view
, bufferView
);
1989 vk_object_base_finish(&view
->base
);
1990 vk_free2(&device
->vk
.alloc
, pAllocator
, view
);