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"
38 radv_choose_tiling(struct radv_device
*device
,
39 const VkImageCreateInfo
*pCreateInfo
)
41 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
) {
42 assert(pCreateInfo
->samples
<= 1);
43 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
46 if (!vk_format_is_compressed(pCreateInfo
->format
) &&
47 !vk_format_is_depth_or_stencil(pCreateInfo
->format
)
48 && device
->physical_device
->rad_info
.chip_class
<= GFX8
) {
49 /* this causes hangs in some VK CTS tests on GFX9. */
50 /* Textures with a very small height are recommended to be linear. */
51 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_1D
||
52 /* Only very thin and long 2D textures should benefit from
54 (pCreateInfo
->extent
.width
> 8 && pCreateInfo
->extent
.height
<= 2))
55 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
58 /* MSAA resources must be 2D tiled. */
59 if (pCreateInfo
->samples
> 1)
60 return RADEON_SURF_MODE_2D
;
62 return RADEON_SURF_MODE_2D
;
66 radv_use_tc_compat_htile_for_image(struct radv_device
*device
,
67 const VkImageCreateInfo
*pCreateInfo
)
69 /* TC-compat HTILE is only available for GFX8+. */
70 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
73 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
) ||
74 (pCreateInfo
->flags
& VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
))
77 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
)
80 if (pCreateInfo
->mipLevels
> 1)
83 /* FIXME: for some reason TC compat with 2/4/8 samples breaks some cts
84 * tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
86 if (pCreateInfo
->samples
>= 2 &&
87 (pCreateInfo
->format
== VK_FORMAT_D32_SFLOAT_S8_UINT
||
88 (pCreateInfo
->format
== VK_FORMAT_D32_SFLOAT
&&
89 device
->physical_device
->rad_info
.chip_class
== GFX10
)))
92 /* GFX9 supports both 32-bit and 16-bit depth surfaces, while GFX8 only
93 * supports 32-bit. Though, it's possible to enable TC-compat for
94 * 16-bit depth surfaces if no Z planes are compressed.
96 if (pCreateInfo
->format
!= VK_FORMAT_D32_SFLOAT_S8_UINT
&&
97 pCreateInfo
->format
!= VK_FORMAT_D32_SFLOAT
&&
98 pCreateInfo
->format
!= VK_FORMAT_D16_UNORM
)
101 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) {
102 const struct VkImageFormatListCreateInfoKHR
*format_list
=
103 (const struct VkImageFormatListCreateInfoKHR
*)
104 vk_find_struct_const(pCreateInfo
->pNext
,
105 IMAGE_FORMAT_LIST_CREATE_INFO_KHR
);
107 /* We have to ignore the existence of the list if viewFormatCount = 0 */
108 if (format_list
&& format_list
->viewFormatCount
) {
109 /* compatibility is transitive, so we only need to check
110 * one format with everything else.
112 for (unsigned i
= 0; i
< format_list
->viewFormatCount
; ++i
) {
113 if (format_list
->pViewFormats
[i
] == VK_FORMAT_UNDEFINED
)
116 if (pCreateInfo
->format
!= format_list
->pViewFormats
[i
])
128 radv_surface_has_scanout(struct radv_device
*device
, const struct radv_image_create_info
*info
)
133 if (!info
->bo_metadata
)
136 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
137 return info
->bo_metadata
->u
.gfx9
.swizzle_mode
== 0 || info
->bo_metadata
->u
.gfx9
.swizzle_mode
% 4 == 2;
139 return info
->bo_metadata
->u
.legacy
.scanout
;
144 radv_use_dcc_for_image(struct radv_device
*device
,
145 const struct radv_image
*image
,
146 const VkImageCreateInfo
*pCreateInfo
)
148 bool dcc_compatible_formats
;
151 /* DCC (Delta Color Compression) is only available for GFX8+. */
152 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
155 if (device
->instance
->debug_flags
& RADV_DEBUG_NO_DCC
)
158 if (image
->shareable
)
161 /* TODO: Enable DCC for storage images. */
162 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
) ||
163 (pCreateInfo
->flags
& VK_IMAGE_CREATE_EXTENDED_USAGE_BIT
))
166 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
)
169 if (vk_format_is_subsampled(pCreateInfo
->format
) ||
170 vk_format_get_plane_count(pCreateInfo
->format
) > 1)
173 /* TODO: Enable DCC for mipmaps on GFX9+. */
174 if ((pCreateInfo
->arrayLayers
> 1 || pCreateInfo
->mipLevels
> 1) &&
175 device
->physical_device
->rad_info
.chip_class
>= GFX9
)
178 /* Do not enable DCC for mipmapped arrays because performance is worse. */
179 if (pCreateInfo
->arrayLayers
> 1 && pCreateInfo
->mipLevels
> 1)
182 /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while
183 * 2x can be enabled with an option.
185 if (pCreateInfo
->samples
> 2 ||
186 (pCreateInfo
->samples
== 2 &&
187 !device
->physical_device
->dcc_msaa_allowed
))
190 /* Determine if the formats are DCC compatible. */
191 dcc_compatible_formats
=
192 radv_is_colorbuffer_format_supported(pCreateInfo
->format
,
195 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) {
196 const struct VkImageFormatListCreateInfoKHR
*format_list
=
197 (const struct VkImageFormatListCreateInfoKHR
*)
198 vk_find_struct_const(pCreateInfo
->pNext
,
199 IMAGE_FORMAT_LIST_CREATE_INFO_KHR
);
201 /* We have to ignore the existence of the list if viewFormatCount = 0 */
202 if (format_list
&& format_list
->viewFormatCount
) {
203 /* compatibility is transitive, so we only need to check
204 * one format with everything else. */
205 for (unsigned i
= 0; i
< format_list
->viewFormatCount
; ++i
) {
206 if (format_list
->pViewFormats
[i
] == VK_FORMAT_UNDEFINED
)
209 if (!radv_dcc_formats_compatible(pCreateInfo
->format
,
210 format_list
->pViewFormats
[i
]))
211 dcc_compatible_formats
= false;
214 dcc_compatible_formats
= false;
218 if (!dcc_compatible_formats
)
225 radv_use_tc_compat_cmask_for_image(struct radv_device
*device
,
226 struct radv_image
*image
)
228 if (!(device
->instance
->perftest_flags
& RADV_PERFTEST_TC_COMPAT_CMASK
))
231 /* TC-compat CMASK is only available for GFX8+. */
232 if (device
->physical_device
->rad_info
.chip_class
< GFX8
)
235 if (image
->usage
& VK_IMAGE_USAGE_STORAGE_BIT
)
238 if (radv_image_has_dcc(image
))
241 if (!radv_image_has_cmask(image
))
248 radv_patch_surface_from_metadata(struct radv_device
*device
,
249 struct radeon_surf
*surface
,
250 const struct radeon_bo_metadata
*md
)
252 surface
->flags
= RADEON_SURF_CLR(surface
->flags
, MODE
);
254 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
255 if (md
->u
.gfx9
.swizzle_mode
> 0)
256 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
258 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
260 surface
->u
.gfx9
.surf
.swizzle_mode
= md
->u
.gfx9
.swizzle_mode
;
262 surface
->u
.legacy
.pipe_config
= md
->u
.legacy
.pipe_config
;
263 surface
->u
.legacy
.bankw
= md
->u
.legacy
.bankw
;
264 surface
->u
.legacy
.bankh
= md
->u
.legacy
.bankh
;
265 surface
->u
.legacy
.tile_split
= md
->u
.legacy
.tile_split
;
266 surface
->u
.legacy
.mtilea
= md
->u
.legacy
.mtilea
;
267 surface
->u
.legacy
.num_banks
= md
->u
.legacy
.num_banks
;
269 if (md
->u
.legacy
.macrotile
== RADEON_LAYOUT_TILED
)
270 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
271 else if (md
->u
.legacy
.microtile
== RADEON_LAYOUT_TILED
)
272 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_1D
, MODE
);
274 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED
, MODE
);
280 radv_patch_image_from_extra_info(struct radv_device
*device
,
281 struct radv_image
*image
,
282 const struct radv_image_create_info
*create_info
)
284 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
285 if (create_info
->bo_metadata
) {
286 radv_patch_surface_from_metadata(device
, &image
->planes
[plane
].surface
,
287 create_info
->bo_metadata
);
290 if (radv_surface_has_scanout(device
, create_info
)) {
291 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_SCANOUT
;
292 image
->planes
[plane
].surface
.flags
|= RADEON_SURF_DISABLE_DCC
;
294 image
->info
.surf_index
= NULL
;
300 radv_init_surface(struct radv_device
*device
,
301 const struct radv_image
*image
,
302 struct radeon_surf
*surface
,
304 const VkImageCreateInfo
*pCreateInfo
)
306 unsigned array_mode
= radv_choose_tiling(device
, pCreateInfo
);
307 VkFormat format
= vk_format_get_plane_format(pCreateInfo
->format
, plane_id
);
308 const struct vk_format_description
*desc
= vk_format_description(format
);
309 bool is_depth
, is_stencil
;
311 is_depth
= vk_format_has_depth(desc
);
312 is_stencil
= vk_format_has_stencil(desc
);
314 surface
->blk_w
= vk_format_get_blockwidth(format
);
315 surface
->blk_h
= vk_format_get_blockheight(format
);
317 surface
->bpe
= vk_format_get_blocksize(vk_format_depth_only(format
));
318 /* align byte per element on dword */
319 if (surface
->bpe
== 3) {
323 surface
->flags
= RADEON_SURF_SET(array_mode
, MODE
);
325 switch (pCreateInfo
->imageType
){
326 case VK_IMAGE_TYPE_1D
:
327 if (pCreateInfo
->arrayLayers
> 1)
328 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY
, TYPE
);
330 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D
, TYPE
);
332 case VK_IMAGE_TYPE_2D
:
333 if (pCreateInfo
->arrayLayers
> 1)
334 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY
, TYPE
);
336 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D
, TYPE
);
338 case VK_IMAGE_TYPE_3D
:
339 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_3D
, TYPE
);
342 unreachable("unhandled image type");
346 surface
->flags
|= RADEON_SURF_ZBUFFER
;
347 if (radv_use_tc_compat_htile_for_image(device
, pCreateInfo
))
348 surface
->flags
|= RADEON_SURF_TC_COMPATIBLE_HTILE
;
352 surface
->flags
|= RADEON_SURF_SBUFFER
;
354 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
355 pCreateInfo
->imageType
== VK_IMAGE_TYPE_3D
&&
356 vk_format_get_blocksizebits(pCreateInfo
->format
) == 128 &&
357 vk_format_is_compressed(pCreateInfo
->format
))
358 surface
->flags
|= RADEON_SURF_NO_RENDER_TARGET
;
360 surface
->flags
|= RADEON_SURF_OPTIMIZE_FOR_SPACE
;
362 if (!radv_use_dcc_for_image(device
, image
, pCreateInfo
))
363 surface
->flags
|= RADEON_SURF_DISABLE_DCC
;
368 static uint32_t si_get_bo_metadata_word1(struct radv_device
*device
)
370 return (ATI_VENDOR_ID
<< 16) | device
->physical_device
->rad_info
.pci_id
;
373 static inline unsigned
374 si_tile_mode_index(const struct radv_image_plane
*plane
, unsigned level
, bool stencil
)
377 return plane
->surface
.u
.legacy
.stencil_tiling_index
[level
];
379 return plane
->surface
.u
.legacy
.tiling_index
[level
];
382 static unsigned radv_map_swizzle(unsigned swizzle
)
386 return V_008F0C_SQ_SEL_Y
;
388 return V_008F0C_SQ_SEL_Z
;
390 return V_008F0C_SQ_SEL_W
;
392 return V_008F0C_SQ_SEL_0
;
394 return V_008F0C_SQ_SEL_1
;
395 default: /* VK_SWIZZLE_X */
396 return V_008F0C_SQ_SEL_X
;
401 radv_make_buffer_descriptor(struct radv_device
*device
,
402 struct radv_buffer
*buffer
,
408 const struct vk_format_description
*desc
;
410 uint64_t gpu_address
= radv_buffer_get_va(buffer
->bo
);
411 uint64_t va
= gpu_address
+ buffer
->offset
;
412 unsigned num_format
, data_format
;
414 desc
= vk_format_description(vk_format
);
415 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
416 stride
= desc
->block
.bits
/ 8;
420 state
[1] = S_008F04_BASE_ADDRESS_HI(va
>> 32) |
421 S_008F04_STRIDE(stride
);
423 if (device
->physical_device
->rad_info
.chip_class
!= GFX8
&& stride
) {
428 state
[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc
->swizzle
[0])) |
429 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc
->swizzle
[1])) |
430 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc
->swizzle
[2])) |
431 S_008F0C_DST_SEL_W(radv_map_swizzle(desc
->swizzle
[3]));
433 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
434 const struct gfx10_format
*fmt
= &gfx10_format_table
[vk_format
];
436 /* OOB_SELECT chooses the out-of-bounds check:
437 * - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
438 * - 1: index >= NUM_RECORDS
439 * - 2: NUM_RECORDS == 0
440 * - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
441 * else: swizzle_address >= NUM_RECORDS
443 state
[3] |= S_008F0C_FORMAT(fmt
->img_format
) |
444 S_008F0C_OOB_SELECT(0) |
445 S_008F0C_RESOURCE_LEVEL(1);
447 num_format
= radv_translate_buffer_numformat(desc
, first_non_void
);
448 data_format
= radv_translate_buffer_dataformat(desc
, first_non_void
);
450 assert(data_format
!= V_008F0C_BUF_DATA_FORMAT_INVALID
);
451 assert(num_format
!= ~0);
453 state
[3] |= S_008F0C_NUM_FORMAT(num_format
) |
454 S_008F0C_DATA_FORMAT(data_format
);
459 si_set_mutable_tex_desc_fields(struct radv_device
*device
,
460 struct radv_image
*image
,
461 const struct legacy_surf_level
*base_level_info
,
463 unsigned base_level
, unsigned first_level
,
464 unsigned block_width
, bool is_stencil
,
465 bool is_storage_image
, bool disable_compression
,
468 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
469 uint64_t gpu_address
= image
->bo
? radv_buffer_get_va(image
->bo
) + image
->offset
: 0;
470 uint64_t va
= gpu_address
+ plane
->offset
;
471 enum chip_class chip_class
= device
->physical_device
->rad_info
.chip_class
;
472 uint64_t meta_va
= 0;
473 if (chip_class
>= GFX9
) {
475 va
+= plane
->surface
.u
.gfx9
.stencil_offset
;
477 va
+= plane
->surface
.u
.gfx9
.surf_offset
;
479 va
+= base_level_info
->offset
;
482 if (chip_class
>= GFX9
||
483 base_level_info
->mode
== RADEON_SURF_MODE_2D
)
484 state
[0] |= plane
->surface
.tile_swizzle
;
485 state
[1] &= C_008F14_BASE_ADDRESS_HI
;
486 state
[1] |= S_008F14_BASE_ADDRESS_HI(va
>> 40);
488 if (chip_class
>= GFX8
) {
489 state
[6] &= C_008F28_COMPRESSION_EN
;
491 if (!disable_compression
&& radv_dcc_enabled(image
, first_level
)) {
492 meta_va
= gpu_address
+ image
->dcc_offset
;
493 if (chip_class
<= GFX8
)
494 meta_va
+= base_level_info
->dcc_offset
;
496 unsigned dcc_tile_swizzle
= plane
->surface
.tile_swizzle
<< 8;
497 dcc_tile_swizzle
&= plane
->surface
.dcc_alignment
- 1;
498 meta_va
|= dcc_tile_swizzle
;
499 } else if (!disable_compression
&&
500 radv_image_is_tc_compat_htile(image
)) {
501 meta_va
= gpu_address
+ image
->htile_offset
;
505 state
[6] |= S_008F28_COMPRESSION_EN(1);
506 if (chip_class
<= GFX9
)
507 state
[7] = meta_va
>> 8;
511 if (chip_class
>= GFX10
) {
512 state
[3] &= C_00A00C_SW_MODE
;
515 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
517 state
[3] |= S_00A00C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
520 state
[6] &= C_00A018_META_DATA_ADDRESS_LO
&
521 C_00A018_META_PIPE_ALIGNED
;
524 struct gfx9_surf_meta_flags meta
;
526 if (image
->dcc_offset
)
527 meta
= plane
->surface
.u
.gfx9
.dcc
;
529 meta
= plane
->surface
.u
.gfx9
.htile
;
531 state
[6] |= S_00A018_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
532 S_00A018_META_DATA_ADDRESS_LO(meta_va
>> 8);
535 state
[7] = meta_va
>> 16;
536 } else if (chip_class
== GFX9
) {
537 state
[3] &= C_008F1C_SW_MODE
;
538 state
[4] &= C_008F20_PITCH
;
541 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
542 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.stencil
.epitch
);
544 state
[3] |= S_008F1C_SW_MODE(plane
->surface
.u
.gfx9
.surf
.swizzle_mode
);
545 state
[4] |= S_008F20_PITCH(plane
->surface
.u
.gfx9
.surf
.epitch
);
548 state
[5] &= C_008F24_META_DATA_ADDRESS
&
549 C_008F24_META_PIPE_ALIGNED
&
550 C_008F24_META_RB_ALIGNED
;
552 struct gfx9_surf_meta_flags meta
;
554 if (image
->dcc_offset
)
555 meta
= plane
->surface
.u
.gfx9
.dcc
;
557 meta
= plane
->surface
.u
.gfx9
.htile
;
559 state
[5] |= S_008F24_META_DATA_ADDRESS(meta_va
>> 40) |
560 S_008F24_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
561 S_008F24_META_RB_ALIGNED(meta
.rb_aligned
);
565 unsigned pitch
= base_level_info
->nblk_x
* block_width
;
566 unsigned index
= si_tile_mode_index(plane
, base_level
, is_stencil
);
568 state
[3] &= C_008F1C_TILING_INDEX
;
569 state
[3] |= S_008F1C_TILING_INDEX(index
);
570 state
[4] &= C_008F20_PITCH
;
571 state
[4] |= S_008F20_PITCH(pitch
- 1);
575 static unsigned radv_tex_dim(VkImageType image_type
, VkImageViewType view_type
,
576 unsigned nr_layers
, unsigned nr_samples
, bool is_storage_image
, bool gfx9
)
578 if (view_type
== VK_IMAGE_VIEW_TYPE_CUBE
|| view_type
== VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
)
579 return is_storage_image
? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_CUBE
;
581 /* GFX9 allocates 1D textures as 2D. */
582 if (gfx9
&& image_type
== VK_IMAGE_TYPE_1D
)
583 image_type
= VK_IMAGE_TYPE_2D
;
584 switch (image_type
) {
585 case VK_IMAGE_TYPE_1D
:
586 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY
: V_008F1C_SQ_RSRC_IMG_1D
;
587 case VK_IMAGE_TYPE_2D
:
589 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D_MSAA
;
591 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D
;
592 case VK_IMAGE_TYPE_3D
:
593 if (view_type
== VK_IMAGE_VIEW_TYPE_3D
)
594 return V_008F1C_SQ_RSRC_IMG_3D
;
596 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY
;
598 unreachable("illegal image type");
602 static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle
[4])
604 unsigned bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
606 if (swizzle
[3] == VK_SWIZZLE_X
) {
607 /* For the pre-defined border color values (white, opaque
608 * black, transparent black), the only thing that matters is
609 * that the alpha channel winds up in the correct place
610 * (because the RGB channels are all the same) so either of
611 * these enumerations will work.
613 if (swizzle
[2] == VK_SWIZZLE_Y
)
614 bc_swizzle
= V_008F20_BC_SWIZZLE_WZYX
;
616 bc_swizzle
= V_008F20_BC_SWIZZLE_WXYZ
;
617 } else if (swizzle
[0] == VK_SWIZZLE_X
) {
618 if (swizzle
[1] == VK_SWIZZLE_Y
)
619 bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
621 bc_swizzle
= V_008F20_BC_SWIZZLE_XWYZ
;
622 } else if (swizzle
[1] == VK_SWIZZLE_X
) {
623 bc_swizzle
= V_008F20_BC_SWIZZLE_YXWZ
;
624 } else if (swizzle
[2] == VK_SWIZZLE_X
) {
625 bc_swizzle
= V_008F20_BC_SWIZZLE_ZYXW
;
631 static bool vi_alpha_is_on_msb(struct radv_device
*device
, VkFormat format
)
633 const struct vk_format_description
*desc
= vk_format_description(format
);
635 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
&& desc
->nr_channels
== 1)
636 return desc
->swizzle
[3] == VK_SWIZZLE_X
;
638 return radv_translate_colorswap(format
, false) <= 1;
641 * Build the sampler view descriptor for a texture (GFX10).
644 gfx10_make_texture_descriptor(struct radv_device
*device
,
645 struct radv_image
*image
,
646 bool is_storage_image
,
647 VkImageViewType view_type
,
649 const VkComponentMapping
*mapping
,
650 unsigned first_level
, unsigned last_level
,
651 unsigned first_layer
, unsigned last_layer
,
652 unsigned width
, unsigned height
, unsigned depth
,
654 uint32_t *fmask_state
)
656 const struct vk_format_description
*desc
;
657 enum vk_swizzle swizzle
[4];
661 desc
= vk_format_description(vk_format
);
662 img_format
= gfx10_format_table
[vk_format
].img_format
;
664 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
665 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
666 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
668 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
671 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
672 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
673 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
675 depth
= image
->info
.array_size
;
676 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
677 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
678 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
679 depth
= image
->info
.array_size
;
680 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
681 depth
= image
->info
.array_size
/ 6;
684 state
[1] = S_00A004_FORMAT(img_format
) |
685 S_00A004_WIDTH_LO(width
- 1);
686 state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
687 S_00A008_HEIGHT(height
- 1) |
688 S_00A008_RESOURCE_LEVEL(1);
689 state
[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
690 S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
691 S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
692 S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
693 S_00A00C_BASE_LEVEL(image
->info
.samples
> 1 ?
695 S_00A00C_LAST_LEVEL(image
->info
.samples
> 1 ?
696 util_logbase2(image
->info
.samples
) :
698 S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(swizzle
)) |
700 /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
701 * to know the total number of layers.
703 state
[4] = S_00A010_DEPTH(type
== V_008F1C_SQ_RSRC_IMG_3D
? depth
- 1 : last_layer
) |
704 S_00A010_BASE_ARRAY(first_layer
);
705 state
[5] = S_00A014_ARRAY_PITCH(!!(type
== V_008F1C_SQ_RSRC_IMG_3D
)) |
706 S_00A014_MAX_MIP(image
->info
.samples
> 1 ?
707 util_logbase2(image
->info
.samples
) :
708 image
->info
.levels
- 1) |
709 S_00A014_PERF_MOD(4);
713 if (radv_dcc_enabled(image
, first_level
)) {
714 state
[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B
) |
715 S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B
) |
716 S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
719 /* Initialize the sampler view for FMASK. */
720 if (radv_image_has_fmask(image
)) {
721 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
725 assert(image
->plane_count
== 1);
727 va
= gpu_address
+ image
->offset
+ image
->fmask_offset
;
729 switch (image
->info
.samples
) {
731 format
= V_008F0C_IMG_FORMAT_FMASK8_S2_F2
;
734 format
= V_008F0C_IMG_FORMAT_FMASK8_S4_F4
;
737 format
= V_008F0C_IMG_FORMAT_FMASK32_S8_F8
;
740 unreachable("invalid nr_samples");
743 fmask_state
[0] = (va
>> 8) | image
->planes
[0].surface
.fmask_tile_swizzle
;
744 fmask_state
[1] = S_00A004_BASE_ADDRESS_HI(va
>> 40) |
745 S_00A004_FORMAT(format
) |
746 S_00A004_WIDTH_LO(width
- 1);
747 fmask_state
[2] = S_00A008_WIDTH_HI((width
- 1) >> 2) |
748 S_00A008_HEIGHT(height
- 1) |
749 S_00A008_RESOURCE_LEVEL(1);
750 fmask_state
[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
751 S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
752 S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
753 S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
754 S_00A00C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
) |
755 S_00A00C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
756 fmask_state
[4] = S_00A010_DEPTH(last_layer
) |
757 S_00A010_BASE_ARRAY(first_layer
);
759 fmask_state
[6] = S_00A018_META_PIPE_ALIGNED(image
->planes
[0].surface
.u
.gfx9
.cmask
.pipe_aligned
);
761 } else if (fmask_state
)
762 memset(fmask_state
, 0, 8 * 4);
766 * Build the sampler view descriptor for a texture (SI-GFX9)
769 si_make_texture_descriptor(struct radv_device
*device
,
770 struct radv_image
*image
,
771 bool is_storage_image
,
772 VkImageViewType view_type
,
774 const VkComponentMapping
*mapping
,
775 unsigned first_level
, unsigned last_level
,
776 unsigned first_layer
, unsigned last_layer
,
777 unsigned width
, unsigned height
, unsigned depth
,
779 uint32_t *fmask_state
)
781 const struct vk_format_description
*desc
;
782 enum vk_swizzle swizzle
[4];
784 unsigned num_format
, data_format
, type
;
786 desc
= vk_format_description(vk_format
);
788 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
789 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
790 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
792 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
795 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
797 num_format
= radv_translate_tex_numformat(vk_format
, desc
, first_non_void
);
798 if (num_format
== ~0) {
802 data_format
= radv_translate_tex_dataformat(vk_format
, desc
, first_non_void
);
803 if (data_format
== ~0) {
807 /* S8 with either Z16 or Z32 HTILE need a special format. */
808 if (device
->physical_device
->rad_info
.chip_class
== GFX9
&&
809 vk_format
== VK_FORMAT_S8_UINT
&&
810 radv_image_is_tc_compat_htile(image
)) {
811 if (image
->vk_format
== VK_FORMAT_D32_SFLOAT_S8_UINT
)
812 data_format
= V_008F14_IMG_DATA_FORMAT_S8_32
;
813 else if (image
->vk_format
== VK_FORMAT_D16_UNORM_S8_UINT
)
814 data_format
= V_008F14_IMG_DATA_FORMAT_S8_16
;
816 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
817 is_storage_image
, device
->physical_device
->rad_info
.chip_class
== GFX9
);
818 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
820 depth
= image
->info
.array_size
;
821 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
822 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
823 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
824 depth
= image
->info
.array_size
;
825 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
826 depth
= image
->info
.array_size
/ 6;
829 state
[1] = (S_008F14_DATA_FORMAT(data_format
) |
830 S_008F14_NUM_FORMAT(num_format
));
831 state
[2] = (S_008F18_WIDTH(width
- 1) |
832 S_008F18_HEIGHT(height
- 1) |
833 S_008F18_PERF_MOD(4));
834 state
[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
835 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
836 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
837 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
838 S_008F1C_BASE_LEVEL(image
->info
.samples
> 1 ?
840 S_008F1C_LAST_LEVEL(image
->info
.samples
> 1 ?
841 util_logbase2(image
->info
.samples
) :
843 S_008F1C_TYPE(type
));
845 state
[5] = S_008F24_BASE_ARRAY(first_layer
);
849 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
850 unsigned bc_swizzle
= gfx9_border_color_swizzle(swizzle
);
852 /* Depth is the last accessible layer on Gfx9.
853 * The hw doesn't need to know the total number of layers.
855 if (type
== V_008F1C_SQ_RSRC_IMG_3D
)
856 state
[4] |= S_008F20_DEPTH(depth
- 1);
858 state
[4] |= S_008F20_DEPTH(last_layer
);
860 state
[4] |= S_008F20_BC_SWIZZLE(bc_swizzle
);
861 state
[5] |= S_008F24_MAX_MIP(image
->info
.samples
> 1 ?
862 util_logbase2(image
->info
.samples
) :
863 image
->info
.levels
- 1);
865 state
[3] |= S_008F1C_POW2_PAD(image
->info
.levels
> 1);
866 state
[4] |= S_008F20_DEPTH(depth
- 1);
867 state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
869 if (image
->dcc_offset
) {
870 state
[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device
, vk_format
));
872 /* The last dword is unused by hw. The shader uses it to clear
873 * bits in the first dword of sampler state.
875 if (device
->physical_device
->rad_info
.chip_class
<= GFX7
&& image
->info
.samples
<= 1) {
876 if (first_level
== last_level
)
877 state
[7] = C_008F30_MAX_ANISO_RATIO
;
879 state
[7] = 0xffffffff;
883 /* Initialize the sampler view for FMASK. */
884 if (radv_image_has_fmask(image
)) {
885 uint32_t fmask_format
, num_format
;
886 uint64_t gpu_address
= radv_buffer_get_va(image
->bo
);
889 assert(image
->plane_count
== 1);
891 va
= gpu_address
+ image
->offset
+ image
->fmask_offset
;
893 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
894 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK
;
895 switch (image
->info
.samples
) {
897 num_format
= V_008F14_IMG_FMASK_8_2_2
;
900 num_format
= V_008F14_IMG_FMASK_8_4_4
;
903 num_format
= V_008F14_IMG_FMASK_32_8_8
;
906 unreachable("invalid nr_samples");
909 switch (image
->info
.samples
) {
911 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2
;
914 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4
;
917 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8
;
921 fmask_format
= V_008F14_IMG_DATA_FORMAT_INVALID
;
923 num_format
= V_008F14_IMG_NUM_FORMAT_UINT
;
926 fmask_state
[0] = va
>> 8;
927 fmask_state
[0] |= image
->planes
[0].surface
.fmask_tile_swizzle
;
928 fmask_state
[1] = S_008F14_BASE_ADDRESS_HI(va
>> 40) |
929 S_008F14_DATA_FORMAT(fmask_format
) |
930 S_008F14_NUM_FORMAT(num_format
);
931 fmask_state
[2] = S_008F18_WIDTH(width
- 1) |
932 S_008F18_HEIGHT(height
- 1);
933 fmask_state
[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
934 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
935 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
936 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
937 S_008F1C_TYPE(radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, 0, false, false));
939 fmask_state
[5] = S_008F24_BASE_ARRAY(first_layer
);
943 if (device
->physical_device
->rad_info
.chip_class
== GFX9
) {
944 fmask_state
[3] |= S_008F1C_SW_MODE(image
->planes
[0].surface
.u
.gfx9
.fmask
.swizzle_mode
);
945 fmask_state
[4] |= S_008F20_DEPTH(last_layer
) |
946 S_008F20_PITCH(image
->planes
[0].surface
.u
.gfx9
.fmask
.epitch
);
947 fmask_state
[5] |= S_008F24_META_PIPE_ALIGNED(image
->planes
[0].surface
.u
.gfx9
.cmask
.pipe_aligned
) |
948 S_008F24_META_RB_ALIGNED(image
->planes
[0].surface
.u
.gfx9
.cmask
.rb_aligned
);
950 if (radv_image_is_tc_compat_cmask(image
)) {
951 va
= gpu_address
+ image
->offset
+ image
->cmask_offset
;
953 fmask_state
[5] |= S_008F24_META_DATA_ADDRESS(va
>> 40);
954 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
955 fmask_state
[7] |= va
>> 8;
958 fmask_state
[3] |= S_008F1C_TILING_INDEX(image
->planes
[0].surface
.u
.legacy
.fmask
.tiling_index
);
959 fmask_state
[4] |= S_008F20_DEPTH(depth
- 1) |
960 S_008F20_PITCH(image
->planes
[0].surface
.u
.legacy
.fmask
.pitch_in_pixels
- 1);
961 fmask_state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
963 if (radv_image_is_tc_compat_cmask(image
)) {
964 va
= gpu_address
+ image
->offset
+ image
->cmask_offset
;
966 fmask_state
[6] |= S_008F28_COMPRESSION_EN(1);
967 fmask_state
[7] |= va
>> 8;
970 } else if (fmask_state
)
971 memset(fmask_state
, 0, 8 * 4);
975 radv_make_texture_descriptor(struct radv_device
*device
,
976 struct radv_image
*image
,
977 bool is_storage_image
,
978 VkImageViewType view_type
,
980 const VkComponentMapping
*mapping
,
981 unsigned first_level
, unsigned last_level
,
982 unsigned first_layer
, unsigned last_layer
,
983 unsigned width
, unsigned height
, unsigned depth
,
985 uint32_t *fmask_state
)
987 if (device
->physical_device
->rad_info
.chip_class
>= GFX10
) {
988 gfx10_make_texture_descriptor(device
, image
, is_storage_image
,
989 view_type
, vk_format
, mapping
,
990 first_level
, last_level
,
991 first_layer
, last_layer
,
992 width
, height
, depth
,
995 si_make_texture_descriptor(device
, image
, is_storage_image
,
996 view_type
, vk_format
, mapping
,
997 first_level
, last_level
,
998 first_layer
, last_layer
,
999 width
, height
, depth
,
1000 state
, fmask_state
);
1005 radv_query_opaque_metadata(struct radv_device
*device
,
1006 struct radv_image
*image
,
1007 struct radeon_bo_metadata
*md
)
1009 static const VkComponentMapping fixedmapping
;
1010 uint32_t desc
[8], i
;
1012 assert(image
->plane_count
== 1);
1014 /* Metadata image format format version 1:
1015 * [0] = 1 (metadata format identifier)
1016 * [1] = (VENDOR_ID << 16) | PCI_ID
1017 * [2:9] = image descriptor for the whole resource
1018 * [2] is always 0, because the base address is cleared
1019 * [9] is the DCC offset bits [39:8] from the beginning of
1021 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
1023 md
->metadata
[0] = 1; /* metadata image format version 1 */
1025 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
1026 md
->metadata
[1] = si_get_bo_metadata_word1(device
);
1029 radv_make_texture_descriptor(device
, image
, false,
1030 (VkImageViewType
)image
->type
, image
->vk_format
,
1031 &fixedmapping
, 0, image
->info
.levels
- 1, 0,
1032 image
->info
.array_size
- 1,
1033 image
->info
.width
, image
->info
.height
,
1037 si_set_mutable_tex_desc_fields(device
, image
, &image
->planes
[0].surface
.u
.legacy
.level
[0], 0, 0, 0,
1038 image
->planes
[0].surface
.blk_w
, false, false, false, desc
);
1040 /* Clear the base address and set the relative DCC offset. */
1042 desc
[1] &= C_008F14_BASE_ADDRESS_HI
;
1043 desc
[7] = image
->dcc_offset
>> 8;
1045 /* Dwords [2:9] contain the image descriptor. */
1046 memcpy(&md
->metadata
[2], desc
, sizeof(desc
));
1048 /* Dwords [10:..] contain the mipmap level offsets. */
1049 if (device
->physical_device
->rad_info
.chip_class
<= GFX8
) {
1050 for (i
= 0; i
<= image
->info
.levels
- 1; i
++)
1051 md
->metadata
[10+i
] = image
->planes
[0].surface
.u
.legacy
.level
[i
].offset
>> 8;
1052 md
->size_metadata
= (11 + image
->info
.levels
- 1) * 4;
1054 md
->size_metadata
= 10 * 4;
1058 radv_init_metadata(struct radv_device
*device
,
1059 struct radv_image
*image
,
1060 struct radeon_bo_metadata
*metadata
)
1062 struct radeon_surf
*surface
= &image
->planes
[0].surface
;
1064 memset(metadata
, 0, sizeof(*metadata
));
1066 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1067 metadata
->u
.gfx9
.swizzle_mode
= surface
->u
.gfx9
.surf
.swizzle_mode
;
1069 metadata
->u
.legacy
.microtile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_1D
?
1070 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1071 metadata
->u
.legacy
.macrotile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_2D
?
1072 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
1073 metadata
->u
.legacy
.pipe_config
= surface
->u
.legacy
.pipe_config
;
1074 metadata
->u
.legacy
.bankw
= surface
->u
.legacy
.bankw
;
1075 metadata
->u
.legacy
.bankh
= surface
->u
.legacy
.bankh
;
1076 metadata
->u
.legacy
.tile_split
= surface
->u
.legacy
.tile_split
;
1077 metadata
->u
.legacy
.mtilea
= surface
->u
.legacy
.mtilea
;
1078 metadata
->u
.legacy
.num_banks
= surface
->u
.legacy
.num_banks
;
1079 metadata
->u
.legacy
.stride
= surface
->u
.legacy
.level
[0].nblk_x
* surface
->bpe
;
1080 metadata
->u
.legacy
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
1082 radv_query_opaque_metadata(device
, image
, metadata
);
1086 radv_image_override_offset_stride(struct radv_device
*device
,
1087 struct radv_image
*image
,
1088 uint64_t offset
, uint32_t stride
)
1090 struct radeon_surf
*surface
= &image
->planes
[0].surface
;
1091 unsigned bpe
= vk_format_get_blocksizebits(image
->vk_format
) / 8;
1093 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1095 surface
->u
.gfx9
.surf_pitch
= stride
;
1096 surface
->u
.gfx9
.surf_slice_size
=
1097 (uint64_t)stride
* surface
->u
.gfx9
.surf_height
* bpe
;
1099 surface
->u
.gfx9
.surf_offset
= offset
;
1101 surface
->u
.legacy
.level
[0].nblk_x
= stride
;
1102 surface
->u
.legacy
.level
[0].slice_size_dw
=
1103 ((uint64_t)stride
* surface
->u
.legacy
.level
[0].nblk_y
* bpe
) / 4;
1106 for (unsigned i
= 0; i
< ARRAY_SIZE(surface
->u
.legacy
.level
); ++i
)
1107 surface
->u
.legacy
.level
[i
].offset
+= offset
;
1114 radv_image_alloc_fmask(struct radv_device
*device
,
1115 struct radv_image
*image
)
1117 unsigned fmask_alignment
= image
->planes
[0].surface
.fmask_alignment
;
1119 image
->fmask_offset
= align64(image
->size
, fmask_alignment
);
1120 image
->size
= image
->fmask_offset
+ image
->planes
[0].surface
.fmask_size
;
1121 image
->alignment
= MAX2(image
->alignment
, fmask_alignment
);
1125 radv_image_alloc_cmask(struct radv_device
*device
,
1126 struct radv_image
*image
)
1128 unsigned cmask_alignment
= image
->planes
[0].surface
.cmask_alignment
;
1129 unsigned cmask_size
= image
->planes
[0].surface
.cmask_size
;
1130 uint32_t clear_value_size
= 0;
1135 assert(cmask_alignment
);
1137 image
->cmask_offset
= align64(image
->size
, cmask_alignment
);
1138 /* + 8 for storing the clear values */
1139 if (!image
->clear_value_offset
) {
1140 image
->clear_value_offset
= image
->cmask_offset
+ cmask_size
;
1141 clear_value_size
= 8;
1143 image
->size
= image
->cmask_offset
+ cmask_size
+ clear_value_size
;
1144 image
->alignment
= MAX2(image
->alignment
, cmask_alignment
);
1148 radv_image_alloc_dcc(struct radv_image
*image
)
1150 assert(image
->plane_count
== 1);
1152 image
->dcc_offset
= align64(image
->size
, image
->planes
[0].surface
.dcc_alignment
);
1153 /* + 24 for storing the clear values + fce pred + dcc pred for each mip */
1154 image
->clear_value_offset
= image
->dcc_offset
+ image
->planes
[0].surface
.dcc_size
;
1155 image
->fce_pred_offset
= image
->clear_value_offset
+ 8 * image
->info
.levels
;
1156 image
->dcc_pred_offset
= image
->clear_value_offset
+ 16 * image
->info
.levels
;
1157 image
->size
= image
->dcc_offset
+ image
->planes
[0].surface
.dcc_size
+ 24 * image
->info
.levels
;
1158 image
->alignment
= MAX2(image
->alignment
, image
->planes
[0].surface
.dcc_alignment
);
1162 radv_image_alloc_htile(struct radv_device
*device
, struct radv_image
*image
)
1164 image
->htile_offset
= align64(image
->size
, image
->planes
[0].surface
.htile_alignment
);
1166 /* + 8 for storing the clear values */
1167 image
->clear_value_offset
= image
->htile_offset
+ image
->planes
[0].surface
.htile_size
;
1168 image
->size
= image
->clear_value_offset
+ image
->info
.levels
* 8;
1169 if (radv_image_is_tc_compat_htile(image
) &&
1170 device
->physical_device
->rad_info
.has_tc_compat_zrange_bug
) {
1171 /* Metadata for the TC-compatible HTILE hardware bug which
1172 * have to be fixed by updating ZRANGE_PRECISION when doing
1173 * fast depth clears to 0.0f.
1175 image
->tc_compat_zrange_offset
= image
->size
;
1176 image
->size
= image
->tc_compat_zrange_offset
+ image
->info
.levels
* 4;
1178 image
->alignment
= align64(image
->alignment
, image
->planes
[0].surface
.htile_alignment
);
1182 radv_image_can_enable_dcc_or_cmask(struct radv_image
*image
)
1184 if (image
->info
.samples
<= 1 &&
1185 image
->info
.width
* image
->info
.height
<= 512 * 512) {
1186 /* Do not enable CMASK or DCC for small surfaces where the cost
1187 * of the eliminate pass can be higher than the benefit of fast
1188 * clear. RadeonSI does this, but the image threshold is
1194 return image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
&&
1195 (image
->exclusive
|| image
->queue_family_mask
== 1);
1199 radv_image_can_enable_dcc(struct radv_device
*device
, struct radv_image
*image
)
1201 if (!radv_image_can_enable_dcc_or_cmask(image
) ||
1202 !radv_image_has_dcc(image
))
1205 /* On GFX8, DCC layers can be interleaved and it's currently only
1206 * enabled if slice size is equal to the per slice fast clear size
1207 * because the driver assumes that portions of multiple layers are
1208 * contiguous during fast clears.
1210 if (image
->info
.array_size
> 1) {
1211 const struct legacy_surf_level
*surf_level
=
1212 &image
->planes
[0].surface
.u
.legacy
.level
[0];
1214 assert(device
->physical_device
->rad_info
.chip_class
== GFX8
);
1216 if (image
->planes
[0].surface
.dcc_slice_size
!= surf_level
->dcc_fast_clear_size
)
1224 radv_image_can_enable_cmask(struct radv_image
*image
)
1226 if (image
->planes
[0].surface
.bpe
> 8 && image
->info
.samples
== 1) {
1227 /* Do not enable CMASK for non-MSAA images (fast color clear)
1228 * because 128 bit formats are not supported, but FMASK might
1234 return radv_image_can_enable_dcc_or_cmask(image
) &&
1235 image
->info
.levels
== 1 &&
1236 image
->info
.depth
== 1 &&
1237 !image
->planes
[0].surface
.is_linear
;
1241 radv_image_can_enable_fmask(struct radv_image
*image
)
1243 return image
->info
.samples
> 1 && vk_format_is_color(image
->vk_format
);
1247 radv_image_can_enable_htile(struct radv_image
*image
)
1249 return radv_image_has_htile(image
) &&
1250 image
->info
.levels
== 1 &&
1251 image
->info
.width
* image
->info
.height
>= 8 * 8;
1254 static void radv_image_disable_dcc(struct radv_image
*image
)
1256 for (unsigned i
= 0; i
< image
->plane_count
; ++i
)
1257 image
->planes
[i
].surface
.dcc_size
= 0;
1260 static void radv_image_disable_htile(struct radv_image
*image
)
1262 for (unsigned i
= 0; i
< image
->plane_count
; ++i
)
1263 image
->planes
[i
].surface
.htile_size
= 0;
1267 radv_image_create_layout(struct radv_device
*device
,
1268 const struct radv_image_create_info
*create_info
,
1269 struct radv_image
*image
)
1271 /* Check that we did not initialize things earlier */
1272 assert(!image
->planes
[0].surface
.surf_size
);
1274 radv_patch_image_from_extra_info(device
, image
, create_info
);
1277 image
->alignment
= 1;
1278 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1279 struct ac_surf_info info
= image
->info
;
1282 const struct vk_format_description
*desc
= vk_format_description(image
->vk_format
);
1283 assert(info
.width
% desc
->width_divisor
== 0);
1284 assert(info
.height
% desc
->height_divisor
== 0);
1286 info
.width
/= desc
->width_divisor
;
1287 info
.height
/= desc
->height_divisor
;
1290 device
->ws
->surface_init(device
->ws
, &info
, &image
->planes
[plane
].surface
);
1292 image
->planes
[plane
].offset
= align(image
->size
, image
->planes
[plane
].surface
.surf_alignment
);
1293 image
->size
= image
->planes
[plane
].offset
+ image
->planes
[plane
].surface
.surf_size
;
1294 image
->alignment
= image
->planes
[plane
].surface
.surf_alignment
;
1296 image
->planes
[plane
].format
= vk_format_get_plane_format(image
->vk_format
, plane
);
1299 if (!create_info
->no_metadata_planes
) {
1300 /* Try to enable DCC first. */
1301 if (radv_image_can_enable_dcc(device
, image
)) {
1302 radv_image_alloc_dcc(image
);
1303 if (image
->info
.samples
> 1) {
1304 /* CMASK should be enabled because DCC fast
1305 * clear with MSAA needs it.
1307 assert(radv_image_can_enable_cmask(image
));
1308 radv_image_alloc_cmask(device
, image
);
1311 /* When DCC cannot be enabled, try CMASK. */
1312 radv_image_disable_dcc(image
);
1313 if (radv_image_can_enable_cmask(image
)) {
1314 radv_image_alloc_cmask(device
, image
);
1318 /* Try to enable FMASK for multisampled images. */
1319 if (radv_image_can_enable_fmask(image
)) {
1320 radv_image_alloc_fmask(device
, image
);
1322 if (radv_use_tc_compat_cmask_for_image(device
, image
))
1323 image
->tc_compatible_cmask
= true;
1325 /* Otherwise, try to enable HTILE for depth surfaces. */
1326 if (radv_image_can_enable_htile(image
) &&
1327 !(device
->instance
->debug_flags
& RADV_DEBUG_NO_HIZ
)) {
1328 image
->tc_compatible_htile
= image
->planes
[0].surface
.flags
& RADEON_SURF_TC_COMPATIBLE_HTILE
;
1329 radv_image_alloc_htile(device
, image
);
1331 radv_image_disable_htile(image
);
1335 radv_image_disable_dcc(image
);
1336 radv_image_disable_htile(image
);
1339 assert(image
->planes
[0].surface
.surf_size
);
1343 radv_image_create(VkDevice _device
,
1344 const struct radv_image_create_info
*create_info
,
1345 const VkAllocationCallbacks
* alloc
,
1348 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1349 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
1350 struct radv_image
*image
= NULL
;
1351 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
1353 const unsigned plane_count
= vk_format_get_plane_count(pCreateInfo
->format
);
1354 const size_t image_struct_size
= sizeof(*image
) + sizeof(struct radv_image_plane
) * plane_count
;
1356 radv_assert(pCreateInfo
->mipLevels
> 0);
1357 radv_assert(pCreateInfo
->arrayLayers
> 0);
1358 radv_assert(pCreateInfo
->samples
> 0);
1359 radv_assert(pCreateInfo
->extent
.width
> 0);
1360 radv_assert(pCreateInfo
->extent
.height
> 0);
1361 radv_assert(pCreateInfo
->extent
.depth
> 0);
1363 image
= vk_zalloc2(&device
->alloc
, alloc
, image_struct_size
, 8,
1364 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1366 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1368 image
->type
= pCreateInfo
->imageType
;
1369 image
->info
.width
= pCreateInfo
->extent
.width
;
1370 image
->info
.height
= pCreateInfo
->extent
.height
;
1371 image
->info
.depth
= pCreateInfo
->extent
.depth
;
1372 image
->info
.samples
= pCreateInfo
->samples
;
1373 image
->info
.storage_samples
= pCreateInfo
->samples
;
1374 image
->info
.array_size
= pCreateInfo
->arrayLayers
;
1375 image
->info
.levels
= pCreateInfo
->mipLevels
;
1376 image
->info
.num_channels
= vk_format_get_nr_components(pCreateInfo
->format
);
1378 image
->vk_format
= pCreateInfo
->format
;
1379 image
->tiling
= pCreateInfo
->tiling
;
1380 image
->usage
= pCreateInfo
->usage
;
1381 image
->flags
= pCreateInfo
->flags
;
1382 image
->plane_count
= plane_count
;
1384 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
1385 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
1386 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
1387 if (pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_EXTERNAL
||
1388 pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_FOREIGN_EXT
)
1389 image
->queue_family_mask
|= (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1391 image
->queue_family_mask
|= 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
1394 image
->shareable
= vk_find_struct_const(pCreateInfo
->pNext
,
1395 EXTERNAL_MEMORY_IMAGE_CREATE_INFO
) != NULL
;
1396 if (!vk_format_is_depth_or_stencil(pCreateInfo
->format
) && !image
->shareable
) {
1397 image
->info
.surf_index
= &device
->image_mrt_offset_counter
;
1400 for (unsigned plane
= 0; plane
< image
->plane_count
; ++plane
) {
1401 radv_init_surface(device
, image
, &image
->planes
[plane
].surface
, plane
, pCreateInfo
);
1404 radv_image_create_layout(device
, create_info
, image
);
1406 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
) {
1407 image
->alignment
= MAX2(image
->alignment
, 4096);
1408 image
->size
= align64(image
->size
, image
->alignment
);
1411 image
->bo
= device
->ws
->buffer_create(device
->ws
, image
->size
, image
->alignment
,
1412 0, RADEON_FLAG_VIRTUAL
, RADV_BO_PRIORITY_VIRTUAL
);
1414 vk_free2(&device
->alloc
, alloc
, image
);
1415 return vk_error(device
->instance
, VK_ERROR_OUT_OF_DEVICE_MEMORY
);
1419 *pImage
= radv_image_to_handle(image
);
1425 radv_image_view_make_descriptor(struct radv_image_view
*iview
,
1426 struct radv_device
*device
,
1428 const VkComponentMapping
*components
,
1429 bool is_storage_image
, bool disable_compression
,
1430 unsigned plane_id
, unsigned descriptor_plane_id
)
1432 struct radv_image
*image
= iview
->image
;
1433 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1434 const struct vk_format_description
*format_desc
= vk_format_description(image
->vk_format
);
1435 bool is_stencil
= iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
;
1437 union radv_descriptor
*descriptor
;
1438 uint32_t hw_level
= 0;
1440 if (is_storage_image
) {
1441 descriptor
= &iview
->storage_descriptor
;
1443 descriptor
= &iview
->descriptor
;
1446 assert(vk_format_get_plane_count(vk_format
) == 1);
1447 assert(plane
->surface
.blk_w
% vk_format_get_blockwidth(plane
->format
) == 0);
1448 blk_w
= plane
->surface
.blk_w
/ vk_format_get_blockwidth(plane
->format
) * vk_format_get_blockwidth(vk_format
);
1450 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
)
1451 hw_level
= iview
->base_mip
;
1452 radv_make_texture_descriptor(device
, image
, is_storage_image
,
1456 hw_level
, hw_level
+ iview
->level_count
- 1,
1458 iview
->base_layer
+ iview
->layer_count
- 1,
1459 iview
->extent
.width
/ (plane_id
? format_desc
->width_divisor
: 1),
1460 iview
->extent
.height
/ (plane_id
? format_desc
->height_divisor
: 1),
1461 iview
->extent
.depth
,
1462 descriptor
->plane_descriptors
[descriptor_plane_id
],
1463 descriptor_plane_id
? NULL
: descriptor
->fmask_descriptor
);
1465 const struct legacy_surf_level
*base_level_info
= NULL
;
1466 if (device
->physical_device
->rad_info
.chip_class
<= GFX9
) {
1468 base_level_info
= &plane
->surface
.u
.legacy
.stencil_level
[iview
->base_mip
];
1470 base_level_info
= &plane
->surface
.u
.legacy
.level
[iview
->base_mip
];
1472 si_set_mutable_tex_desc_fields(device
, image
,
1477 blk_w
, is_stencil
, is_storage_image
,
1478 is_storage_image
|| disable_compression
,
1479 descriptor
->plane_descriptors
[descriptor_plane_id
]);
1483 radv_plane_from_aspect(VkImageAspectFlags mask
)
1486 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1488 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1496 radv_get_aspect_format(struct radv_image
*image
, VkImageAspectFlags mask
)
1499 case VK_IMAGE_ASPECT_PLANE_0_BIT
:
1500 return image
->planes
[0].format
;
1501 case VK_IMAGE_ASPECT_PLANE_1_BIT
:
1502 return image
->planes
[1].format
;
1503 case VK_IMAGE_ASPECT_PLANE_2_BIT
:
1504 return image
->planes
[2].format
;
1505 case VK_IMAGE_ASPECT_STENCIL_BIT
:
1506 return vk_format_stencil_only(image
->vk_format
);
1507 case VK_IMAGE_ASPECT_DEPTH_BIT
:
1508 return vk_format_depth_only(image
->vk_format
);
1509 case VK_IMAGE_ASPECT_DEPTH_BIT
| VK_IMAGE_ASPECT_STENCIL_BIT
:
1510 return vk_format_depth_only(image
->vk_format
);
1512 return image
->vk_format
;
1517 radv_image_view_init(struct radv_image_view
*iview
,
1518 struct radv_device
*device
,
1519 const VkImageViewCreateInfo
* pCreateInfo
,
1520 const struct radv_image_view_extra_create_info
* extra_create_info
)
1522 RADV_FROM_HANDLE(radv_image
, image
, pCreateInfo
->image
);
1523 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
1525 switch (image
->type
) {
1526 case VK_IMAGE_TYPE_1D
:
1527 case VK_IMAGE_TYPE_2D
:
1528 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1 <= image
->info
.array_size
);
1530 case VK_IMAGE_TYPE_3D
:
1531 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1
1532 <= radv_minify(image
->info
.depth
, range
->baseMipLevel
));
1535 unreachable("bad VkImageType");
1537 iview
->image
= image
;
1538 iview
->bo
= image
->bo
;
1539 iview
->type
= pCreateInfo
->viewType
;
1540 iview
->plane_id
= radv_plane_from_aspect(pCreateInfo
->subresourceRange
.aspectMask
);
1541 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
1542 iview
->multiple_planes
= vk_format_get_plane_count(image
->vk_format
) > 1 && iview
->aspect_mask
== VK_IMAGE_ASPECT_COLOR_BIT
;
1543 iview
->vk_format
= pCreateInfo
->format
;
1545 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
1546 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
1547 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
1548 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
1551 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1552 iview
->extent
= (VkExtent3D
) {
1553 .width
= image
->info
.width
,
1554 .height
= image
->info
.height
,
1555 .depth
= image
->info
.depth
,
1558 iview
->extent
= (VkExtent3D
) {
1559 .width
= radv_minify(image
->info
.width
, range
->baseMipLevel
),
1560 .height
= radv_minify(image
->info
.height
, range
->baseMipLevel
),
1561 .depth
= radv_minify(image
->info
.depth
, range
->baseMipLevel
),
1565 if (iview
->vk_format
!= image
->planes
[iview
->plane_id
].format
) {
1566 unsigned view_bw
= vk_format_get_blockwidth(iview
->vk_format
);
1567 unsigned view_bh
= vk_format_get_blockheight(iview
->vk_format
);
1568 unsigned img_bw
= vk_format_get_blockwidth(image
->vk_format
);
1569 unsigned img_bh
= vk_format_get_blockheight(image
->vk_format
);
1571 iview
->extent
.width
= round_up_u32(iview
->extent
.width
* view_bw
, img_bw
);
1572 iview
->extent
.height
= round_up_u32(iview
->extent
.height
* view_bh
, img_bh
);
1574 /* Comment ported from amdvlk -
1575 * If we have the following image:
1576 * Uncompressed pixels Compressed block sizes (4x4)
1577 * mip0: 22 x 22 6 x 6
1578 * mip1: 11 x 11 3 x 3
1583 * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and the HW is
1584 * calculating the degradation of the block sizes down the mip-chain as follows (straight-up
1585 * divide-by-two integer math):
1591 * This means that mip2 will be missing texels.
1593 * Fix this by calculating the base mip's width and height, then convert that, and round it
1594 * back up to get the level 0 size.
1595 * Clamp the converted size between the original values, and next power of two, which
1596 * means we don't oversize the image.
1598 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
&&
1599 vk_format_is_compressed(image
->vk_format
) &&
1600 !vk_format_is_compressed(iview
->vk_format
)) {
1601 unsigned lvl_width
= radv_minify(image
->info
.width
, range
->baseMipLevel
);
1602 unsigned lvl_height
= radv_minify(image
->info
.height
, range
->baseMipLevel
);
1604 lvl_width
= round_up_u32(lvl_width
* view_bw
, img_bw
);
1605 lvl_height
= round_up_u32(lvl_height
* view_bh
, img_bh
);
1607 lvl_width
<<= range
->baseMipLevel
;
1608 lvl_height
<<= range
->baseMipLevel
;
1610 iview
->extent
.width
= CLAMP(lvl_width
, iview
->extent
.width
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_pitch
);
1611 iview
->extent
.height
= CLAMP(lvl_height
, iview
->extent
.height
, iview
->image
->planes
[0].surface
.u
.gfx9
.surf_height
);
1615 iview
->base_layer
= range
->baseArrayLayer
;
1616 iview
->layer_count
= radv_get_layerCount(image
, range
);
1617 iview
->base_mip
= range
->baseMipLevel
;
1618 iview
->level_count
= radv_get_levelCount(image
, range
);
1620 bool disable_compression
= extra_create_info
? extra_create_info
->disable_compression
: false;
1621 for (unsigned i
= 0; i
< (iview
->multiple_planes
? vk_format_get_plane_count(image
->vk_format
) : 1); ++i
) {
1622 VkFormat format
= vk_format_get_plane_format(iview
->vk_format
, i
);
1623 radv_image_view_make_descriptor(iview
, device
, format
,
1624 &pCreateInfo
->components
,
1625 false, disable_compression
,
1626 iview
->plane_id
+ i
, i
);
1627 radv_image_view_make_descriptor(iview
, device
,
1628 format
, &pCreateInfo
->components
,
1629 true, disable_compression
,
1630 iview
->plane_id
+ i
, i
);
1634 bool radv_layout_has_htile(const struct radv_image
*image
,
1635 VkImageLayout layout
,
1636 bool in_render_loop
,
1637 unsigned queue_mask
)
1639 if (radv_image_is_tc_compat_htile(image
))
1640 return layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1642 return radv_image_has_htile(image
) &&
1643 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
1644 (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1645 queue_mask
== (1u << RADV_QUEUE_GENERAL
)));
1648 bool radv_layout_is_htile_compressed(const struct radv_image
*image
,
1649 VkImageLayout layout
,
1650 bool in_render_loop
,
1651 unsigned queue_mask
)
1653 if (radv_image_is_tc_compat_htile(image
))
1654 return layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1656 return radv_image_has_htile(image
) &&
1657 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
1658 (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1659 queue_mask
== (1u << RADV_QUEUE_GENERAL
)));
1662 bool radv_layout_can_fast_clear(const struct radv_image
*image
,
1663 VkImageLayout layout
,
1664 bool in_render_loop
,
1665 unsigned queue_mask
)
1667 return layout
== VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
;
1670 bool radv_layout_dcc_compressed(const struct radv_device
*device
,
1671 const struct radv_image
*image
,
1672 VkImageLayout layout
,
1673 bool in_render_loop
,
1674 unsigned queue_mask
)
1676 /* Don't compress compute transfer dst, as image stores are not supported. */
1677 if (layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
&&
1678 (queue_mask
& (1u << RADV_QUEUE_COMPUTE
)))
1681 return radv_image_has_dcc(image
) && layout
!= VK_IMAGE_LAYOUT_GENERAL
;
1685 unsigned radv_image_queue_family_mask(const struct radv_image
*image
, uint32_t family
, uint32_t queue_family
)
1687 if (!image
->exclusive
)
1688 return image
->queue_family_mask
;
1689 if (family
== VK_QUEUE_FAMILY_EXTERNAL
||
1690 family
== VK_QUEUE_FAMILY_FOREIGN_EXT
)
1691 return (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1692 if (family
== VK_QUEUE_FAMILY_IGNORED
)
1693 return 1u << queue_family
;
1694 return 1u << family
;
1698 radv_CreateImage(VkDevice device
,
1699 const VkImageCreateInfo
*pCreateInfo
,
1700 const VkAllocationCallbacks
*pAllocator
,
1704 const VkNativeBufferANDROID
*gralloc_info
=
1705 vk_find_struct_const(pCreateInfo
->pNext
, NATIVE_BUFFER_ANDROID
);
1708 return radv_image_from_gralloc(device
, pCreateInfo
, gralloc_info
,
1709 pAllocator
, pImage
);
1712 const struct wsi_image_create_info
*wsi_info
=
1713 vk_find_struct_const(pCreateInfo
->pNext
, WSI_IMAGE_CREATE_INFO_MESA
);
1714 bool scanout
= wsi_info
&& wsi_info
->scanout
;
1716 return radv_image_create(device
,
1717 &(struct radv_image_create_info
) {
1718 .vk_info
= pCreateInfo
,
1726 radv_DestroyImage(VkDevice _device
, VkImage _image
,
1727 const VkAllocationCallbacks
*pAllocator
)
1729 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1730 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1735 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
)
1736 device
->ws
->buffer_destroy(image
->bo
);
1738 if (image
->owned_memory
!= VK_NULL_HANDLE
)
1739 radv_FreeMemory(_device
, image
->owned_memory
, pAllocator
);
1741 vk_free2(&device
->alloc
, pAllocator
, image
);
1744 void radv_GetImageSubresourceLayout(
1747 const VkImageSubresource
* pSubresource
,
1748 VkSubresourceLayout
* pLayout
)
1750 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1751 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1752 int level
= pSubresource
->mipLevel
;
1753 int layer
= pSubresource
->arrayLayer
;
1755 unsigned plane_id
= radv_plane_from_aspect(pSubresource
->aspectMask
);
1757 struct radv_image_plane
*plane
= &image
->planes
[plane_id
];
1758 struct radeon_surf
*surface
= &plane
->surface
;
1760 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
1761 pLayout
->offset
= plane
->offset
+ surface
->u
.gfx9
.offset
[level
] + surface
->u
.gfx9
.surf_slice_size
* layer
;
1762 if (image
->vk_format
== VK_FORMAT_R32G32B32_UINT
||
1763 image
->vk_format
== VK_FORMAT_R32G32B32_SINT
||
1764 image
->vk_format
== VK_FORMAT_R32G32B32_SFLOAT
) {
1765 /* Adjust the number of bytes between each row because
1766 * the pitch is actually the number of components per
1769 pLayout
->rowPitch
= surface
->u
.gfx9
.surf_pitch
* surface
->bpe
/ 3;
1771 assert(util_is_power_of_two_nonzero(surface
->bpe
));
1772 pLayout
->rowPitch
= surface
->u
.gfx9
.surf_pitch
* surface
->bpe
;
1775 pLayout
->arrayPitch
= surface
->u
.gfx9
.surf_slice_size
;
1776 pLayout
->depthPitch
= surface
->u
.gfx9
.surf_slice_size
;
1777 pLayout
->size
= surface
->u
.gfx9
.surf_slice_size
;
1778 if (image
->type
== VK_IMAGE_TYPE_3D
)
1779 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1781 pLayout
->offset
= plane
->offset
+ surface
->u
.legacy
.level
[level
].offset
+ (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4 * layer
;
1782 pLayout
->rowPitch
= surface
->u
.legacy
.level
[level
].nblk_x
* surface
->bpe
;
1783 pLayout
->arrayPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1784 pLayout
->depthPitch
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1785 pLayout
->size
= (uint64_t)surface
->u
.legacy
.level
[level
].slice_size_dw
* 4;
1786 if (image
->type
== VK_IMAGE_TYPE_3D
)
1787 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1793 radv_CreateImageView(VkDevice _device
,
1794 const VkImageViewCreateInfo
*pCreateInfo
,
1795 const VkAllocationCallbacks
*pAllocator
,
1798 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1799 struct radv_image_view
*view
;
1801 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
1802 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1804 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1806 radv_image_view_init(view
, device
, pCreateInfo
, NULL
);
1808 *pView
= radv_image_view_to_handle(view
);
1814 radv_DestroyImageView(VkDevice _device
, VkImageView _iview
,
1815 const VkAllocationCallbacks
*pAllocator
)
1817 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1818 RADV_FROM_HANDLE(radv_image_view
, iview
, _iview
);
1822 vk_free2(&device
->alloc
, pAllocator
, iview
);
1825 void radv_buffer_view_init(struct radv_buffer_view
*view
,
1826 struct radv_device
*device
,
1827 const VkBufferViewCreateInfo
* pCreateInfo
)
1829 RADV_FROM_HANDLE(radv_buffer
, buffer
, pCreateInfo
->buffer
);
1831 view
->bo
= buffer
->bo
;
1832 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
?
1833 buffer
->size
- pCreateInfo
->offset
: pCreateInfo
->range
;
1834 view
->vk_format
= pCreateInfo
->format
;
1836 radv_make_buffer_descriptor(device
, buffer
, view
->vk_format
,
1837 pCreateInfo
->offset
, view
->range
, view
->state
);
1841 radv_CreateBufferView(VkDevice _device
,
1842 const VkBufferViewCreateInfo
*pCreateInfo
,
1843 const VkAllocationCallbacks
*pAllocator
,
1844 VkBufferView
*pView
)
1846 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1847 struct radv_buffer_view
*view
;
1849 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
1850 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1852 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
1854 radv_buffer_view_init(view
, device
, pCreateInfo
);
1856 *pView
= radv_buffer_view_to_handle(view
);
1862 radv_DestroyBufferView(VkDevice _device
, VkBufferView bufferView
,
1863 const VkAllocationCallbacks
*pAllocator
)
1865 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1866 RADV_FROM_HANDLE(radv_buffer_view
, view
, bufferView
);
1871 vk_free2(&device
->alloc
, pAllocator
, view
);