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"
35 #include "util/debug.h"
36 #include "util/u_atomic.h"
38 radv_choose_tiling(struct radv_device
*device
,
39 const struct radv_image_create_info
*create_info
)
41 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
43 if (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
) {
44 assert(pCreateInfo
->samples
<= 1);
45 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
48 if (!vk_format_is_compressed(pCreateInfo
->format
) &&
49 !vk_format_is_depth_or_stencil(pCreateInfo
->format
)
50 && device
->physical_device
->rad_info
.chip_class
<= VI
) {
51 /* this causes hangs in some VK CTS tests on GFX9. */
52 /* Textures with a very small height are recommended to be linear. */
53 if (pCreateInfo
->imageType
== VK_IMAGE_TYPE_1D
||
54 /* Only very thin and long 2D textures should benefit from
56 (pCreateInfo
->extent
.width
> 8 && pCreateInfo
->extent
.height
<= 2))
57 return RADEON_SURF_MODE_LINEAR_ALIGNED
;
60 /* MSAA resources must be 2D tiled. */
61 if (pCreateInfo
->samples
> 1)
62 return RADEON_SURF_MODE_2D
;
64 return RADEON_SURF_MODE_2D
;
67 radv_init_surface(struct radv_device
*device
,
68 struct radeon_surf
*surface
,
69 const struct radv_image_create_info
*create_info
)
71 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
72 unsigned array_mode
= radv_choose_tiling(device
, create_info
);
73 const struct vk_format_description
*desc
=
74 vk_format_description(pCreateInfo
->format
);
75 bool is_depth
, is_stencil
, blendable
;
77 is_depth
= vk_format_has_depth(desc
);
78 is_stencil
= vk_format_has_stencil(desc
);
80 surface
->blk_w
= vk_format_get_blockwidth(pCreateInfo
->format
);
81 surface
->blk_h
= vk_format_get_blockheight(pCreateInfo
->format
);
83 surface
->bpe
= vk_format_get_blocksize(vk_format_depth_only(pCreateInfo
->format
));
84 /* align byte per element on dword */
85 if (surface
->bpe
== 3) {
88 surface
->flags
= RADEON_SURF_SET(array_mode
, MODE
);
90 switch (pCreateInfo
->imageType
){
91 case VK_IMAGE_TYPE_1D
:
92 if (pCreateInfo
->arrayLayers
> 1)
93 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY
, TYPE
);
95 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_1D
, TYPE
);
97 case VK_IMAGE_TYPE_2D
:
98 if (pCreateInfo
->arrayLayers
> 1)
99 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY
, TYPE
);
101 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_2D
, TYPE
);
103 case VK_IMAGE_TYPE_3D
:
104 surface
->flags
|= RADEON_SURF_SET(RADEON_SURF_TYPE_3D
, TYPE
);
107 unreachable("unhandled image type");
111 surface
->flags
|= RADEON_SURF_ZBUFFER
;
115 surface
->flags
|= RADEON_SURF_SBUFFER
;
117 surface
->flags
|= RADEON_SURF_OPTIMIZE_FOR_SPACE
;
119 if ((pCreateInfo
->usage
& (VK_IMAGE_USAGE_TRANSFER_SRC_BIT
|
120 VK_IMAGE_USAGE_STORAGE_BIT
)) ||
121 (pCreateInfo
->flags
& VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT
) ||
122 (pCreateInfo
->tiling
== VK_IMAGE_TILING_LINEAR
) ||
123 device
->physical_device
->rad_info
.chip_class
< VI
||
124 create_info
->scanout
|| (device
->debug_flags
& RADV_DEBUG_NO_DCC
) ||
125 !radv_is_colorbuffer_format_supported(pCreateInfo
->format
, &blendable
))
126 surface
->flags
|= RADEON_SURF_DISABLE_DCC
;
127 if (create_info
->scanout
)
128 surface
->flags
|= RADEON_SURF_SCANOUT
;
131 #define ATI_VENDOR_ID 0x1002
132 static uint32_t si_get_bo_metadata_word1(struct radv_device
*device
)
134 return (ATI_VENDOR_ID
<< 16) | device
->physical_device
->rad_info
.pci_id
;
137 static inline unsigned
138 si_tile_mode_index(const struct radv_image
*image
, unsigned level
, bool stencil
)
141 return image
->surface
.u
.legacy
.stencil_tiling_index
[level
];
143 return image
->surface
.u
.legacy
.tiling_index
[level
];
146 static unsigned radv_map_swizzle(unsigned swizzle
)
150 return V_008F0C_SQ_SEL_Y
;
152 return V_008F0C_SQ_SEL_Z
;
154 return V_008F0C_SQ_SEL_W
;
156 return V_008F0C_SQ_SEL_0
;
158 return V_008F0C_SQ_SEL_1
;
159 default: /* VK_SWIZZLE_X */
160 return V_008F0C_SQ_SEL_X
;
165 radv_make_buffer_descriptor(struct radv_device
*device
,
166 struct radv_buffer
*buffer
,
172 const struct vk_format_description
*desc
;
174 uint64_t gpu_address
= device
->ws
->buffer_get_va(buffer
->bo
);
175 uint64_t va
= gpu_address
+ buffer
->offset
;
176 unsigned num_format
, data_format
;
178 desc
= vk_format_description(vk_format
);
179 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
180 stride
= desc
->block
.bits
/ 8;
182 num_format
= radv_translate_buffer_numformat(desc
, first_non_void
);
183 data_format
= radv_translate_buffer_dataformat(desc
, first_non_void
);
187 state
[1] = S_008F04_BASE_ADDRESS_HI(va
>> 32) |
188 S_008F04_STRIDE(stride
);
190 if (device
->physical_device
->rad_info
.chip_class
!= VI
&& stride
) {
195 state
[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc
->swizzle
[0])) |
196 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc
->swizzle
[1])) |
197 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc
->swizzle
[2])) |
198 S_008F0C_DST_SEL_W(radv_map_swizzle(desc
->swizzle
[3])) |
199 S_008F0C_NUM_FORMAT(num_format
) |
200 S_008F0C_DATA_FORMAT(data_format
);
204 si_set_mutable_tex_desc_fields(struct radv_device
*device
,
205 struct radv_image
*image
,
206 const struct legacy_surf_level
*base_level_info
,
207 unsigned base_level
, unsigned first_level
,
208 unsigned block_width
, bool is_stencil
,
211 uint64_t gpu_address
= image
->bo
? device
->ws
->buffer_get_va(image
->bo
) + image
->offset
: 0;
212 uint64_t va
= gpu_address
;
213 enum chip_class chip_class
= device
->physical_device
->rad_info
.chip_class
;
214 uint64_t meta_va
= 0;
215 if (chip_class
>= GFX9
) {
217 va
+= image
->surface
.u
.gfx9
.stencil_offset
;
219 va
+= image
->surface
.u
.gfx9
.surf_offset
;
221 va
+= base_level_info
->offset
;
224 if (chip_class
>= GFX9
||
225 base_level_info
->mode
== RADEON_SURF_MODE_2D
)
226 state
[0] |= image
->surface
.tile_swizzle
;
227 state
[1] &= C_008F14_BASE_ADDRESS_HI
;
228 state
[1] |= S_008F14_BASE_ADDRESS_HI(va
>> 40);
230 if (chip_class
>= VI
) {
231 state
[6] &= C_008F28_COMPRESSION_EN
;
233 if (image
->surface
.dcc_size
&& first_level
< image
->surface
.num_dcc_levels
) {
234 meta_va
= gpu_address
+ image
->dcc_offset
;
235 if (chip_class
<= VI
)
236 meta_va
+= base_level_info
->dcc_offset
;
237 state
[6] |= S_008F28_COMPRESSION_EN(1);
238 state
[7] = meta_va
>> 8;
239 state
[7] |= image
->surface
.tile_swizzle
;
243 if (chip_class
>= GFX9
) {
244 state
[3] &= C_008F1C_SW_MODE
;
245 state
[4] &= C_008F20_PITCH_GFX9
;
248 state
[3] |= S_008F1C_SW_MODE(image
->surface
.u
.gfx9
.stencil
.swizzle_mode
);
249 state
[4] |= S_008F20_PITCH_GFX9(image
->surface
.u
.gfx9
.stencil
.epitch
);
251 state
[3] |= S_008F1C_SW_MODE(image
->surface
.u
.gfx9
.surf
.swizzle_mode
);
252 state
[4] |= S_008F20_PITCH_GFX9(image
->surface
.u
.gfx9
.surf
.epitch
);
255 state
[5] &= C_008F24_META_DATA_ADDRESS
&
256 C_008F24_META_PIPE_ALIGNED
&
257 C_008F24_META_RB_ALIGNED
;
259 struct gfx9_surf_meta_flags meta
;
261 if (image
->dcc_offset
)
262 meta
= image
->surface
.u
.gfx9
.dcc
;
264 meta
= image
->surface
.u
.gfx9
.htile
;
266 state
[5] |= S_008F24_META_DATA_ADDRESS(meta_va
>> 40) |
267 S_008F24_META_PIPE_ALIGNED(meta
.pipe_aligned
) |
268 S_008F24_META_RB_ALIGNED(meta
.rb_aligned
);
272 unsigned pitch
= base_level_info
->nblk_x
* block_width
;
273 unsigned index
= si_tile_mode_index(image
, base_level
, is_stencil
);
275 state
[3] &= C_008F1C_TILING_INDEX
;
276 state
[3] |= S_008F1C_TILING_INDEX(index
);
277 state
[4] &= C_008F20_PITCH_GFX6
;
278 state
[4] |= S_008F20_PITCH_GFX6(pitch
- 1);
282 static unsigned radv_tex_dim(VkImageType image_type
, VkImageViewType view_type
,
283 unsigned nr_layers
, unsigned nr_samples
, bool is_storage_image
)
285 if (view_type
== VK_IMAGE_VIEW_TYPE_CUBE
|| view_type
== VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
)
286 return is_storage_image
? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_CUBE
;
287 switch (image_type
) {
288 case VK_IMAGE_TYPE_1D
:
289 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY
: V_008F1C_SQ_RSRC_IMG_1D
;
290 case VK_IMAGE_TYPE_2D
:
292 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D_MSAA
;
294 return nr_layers
> 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY
: V_008F1C_SQ_RSRC_IMG_2D
;
295 case VK_IMAGE_TYPE_3D
:
296 if (view_type
== VK_IMAGE_VIEW_TYPE_3D
)
297 return V_008F1C_SQ_RSRC_IMG_3D
;
299 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY
;
301 unreachable("illegale image type");
305 static unsigned gfx9_border_color_swizzle(const unsigned char swizzle
[4])
307 unsigned bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
309 if (swizzle
[3] == VK_SWIZZLE_X
) {
310 /* For the pre-defined border color values (white, opaque
311 * black, transparent black), the only thing that matters is
312 * that the alpha channel winds up in the correct place
313 * (because the RGB channels are all the same) so either of
314 * these enumerations will work.
316 if (swizzle
[2] == VK_SWIZZLE_Y
)
317 bc_swizzle
= V_008F20_BC_SWIZZLE_WZYX
;
319 bc_swizzle
= V_008F20_BC_SWIZZLE_WXYZ
;
320 } else if (swizzle
[0] == VK_SWIZZLE_X
) {
321 if (swizzle
[1] == VK_SWIZZLE_Y
)
322 bc_swizzle
= V_008F20_BC_SWIZZLE_XYZW
;
324 bc_swizzle
= V_008F20_BC_SWIZZLE_XWYZ
;
325 } else if (swizzle
[1] == VK_SWIZZLE_X
) {
326 bc_swizzle
= V_008F20_BC_SWIZZLE_YXWZ
;
327 } else if (swizzle
[2] == VK_SWIZZLE_X
) {
328 bc_swizzle
= V_008F20_BC_SWIZZLE_ZYXW
;
335 * Build the sampler view descriptor for a texture.
338 si_make_texture_descriptor(struct radv_device
*device
,
339 struct radv_image
*image
,
340 bool is_storage_image
,
341 VkImageViewType view_type
,
343 const VkComponentMapping
*mapping
,
344 unsigned first_level
, unsigned last_level
,
345 unsigned first_layer
, unsigned last_layer
,
346 unsigned width
, unsigned height
, unsigned depth
,
348 uint32_t *fmask_state
)
350 const struct vk_format_description
*desc
;
351 enum vk_swizzle swizzle
[4];
353 unsigned num_format
, data_format
, type
;
355 desc
= vk_format_description(vk_format
);
357 if (desc
->colorspace
== VK_FORMAT_COLORSPACE_ZS
) {
358 const unsigned char swizzle_xxxx
[4] = {0, 0, 0, 0};
359 vk_format_compose_swizzles(mapping
, swizzle_xxxx
, swizzle
);
361 vk_format_compose_swizzles(mapping
, desc
->swizzle
, swizzle
);
364 first_non_void
= vk_format_get_first_non_void_channel(vk_format
);
366 num_format
= radv_translate_tex_numformat(vk_format
, desc
, first_non_void
);
367 if (num_format
== ~0) {
371 data_format
= radv_translate_tex_dataformat(vk_format
, desc
, first_non_void
);
372 if (data_format
== ~0) {
376 type
= radv_tex_dim(image
->type
, view_type
, image
->info
.array_size
, image
->info
.samples
,
378 if (type
== V_008F1C_SQ_RSRC_IMG_1D_ARRAY
) {
380 depth
= image
->info
.array_size
;
381 } else if (type
== V_008F1C_SQ_RSRC_IMG_2D_ARRAY
||
382 type
== V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY
) {
383 if (view_type
!= VK_IMAGE_VIEW_TYPE_3D
)
384 depth
= image
->info
.array_size
;
385 } else if (type
== V_008F1C_SQ_RSRC_IMG_CUBE
)
386 depth
= image
->info
.array_size
/ 6;
389 state
[1] = (S_008F14_DATA_FORMAT_GFX6(data_format
) |
390 S_008F14_NUM_FORMAT_GFX6(num_format
));
391 state
[2] = (S_008F18_WIDTH(width
- 1) |
392 S_008F18_HEIGHT(height
- 1) |
393 S_008F18_PERF_MOD(4));
394 state
[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle
[0])) |
395 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle
[1])) |
396 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle
[2])) |
397 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle
[3])) |
398 S_008F1C_BASE_LEVEL(image
->info
.samples
> 1 ?
400 S_008F1C_LAST_LEVEL(image
->info
.samples
> 1 ?
401 util_logbase2(image
->info
.samples
) :
403 S_008F1C_TYPE(type
));
405 state
[5] = S_008F24_BASE_ARRAY(first_layer
);
409 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
410 unsigned bc_swizzle
= gfx9_border_color_swizzle(desc
->swizzle
);
412 /* Depth is the the last accessible layer on Gfx9.
413 * The hw doesn't need to know the total number of layers.
415 if (type
== V_008F1C_SQ_RSRC_IMG_3D
)
416 state
[4] |= S_008F20_DEPTH(depth
- 1);
418 state
[4] |= S_008F20_DEPTH(last_layer
);
420 state
[4] |= S_008F20_BC_SWIZZLE(bc_swizzle
);
421 state
[5] |= S_008F24_MAX_MIP(image
->info
.samples
> 1 ?
422 util_logbase2(image
->info
.samples
) :
423 image
->info
.levels
- 1);
425 state
[3] |= S_008F1C_POW2_PAD(image
->info
.levels
> 1);
426 state
[4] |= S_008F20_DEPTH(depth
- 1);
427 state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
429 if (image
->dcc_offset
) {
430 unsigned swap
= radv_translate_colorswap(vk_format
, FALSE
);
432 state
[6] = S_008F28_ALPHA_IS_ON_MSB(swap
<= 1);
434 /* The last dword is unused by hw. The shader uses it to clear
435 * bits in the first dword of sampler state.
437 if (device
->physical_device
->rad_info
.chip_class
<= CIK
&& image
->info
.samples
<= 1) {
438 if (first_level
== last_level
)
439 state
[7] = C_008F30_MAX_ANISO_RATIO
;
441 state
[7] = 0xffffffff;
445 /* Initialize the sampler view for FMASK. */
446 if (image
->fmask
.size
) {
447 uint32_t fmask_format
, num_format
;
448 uint64_t gpu_address
= device
->ws
->buffer_get_va(image
->bo
);
451 va
= gpu_address
+ image
->offset
+ image
->fmask
.offset
;
453 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
454 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK
;
455 switch (image
->info
.samples
) {
457 num_format
= V_008F14_IMG_FMASK_8_2_2
;
460 num_format
= V_008F14_IMG_FMASK_8_4_4
;
463 num_format
= V_008F14_IMG_FMASK_32_8_8
;
466 unreachable("invalid nr_samples");
469 switch (image
->info
.samples
) {
471 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2
;
474 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4
;
477 fmask_format
= V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8
;
481 fmask_format
= V_008F14_IMG_DATA_FORMAT_INVALID
;
483 num_format
= V_008F14_IMG_NUM_FORMAT_UINT
;
486 fmask_state
[0] = va
>> 8;
487 fmask_state
[0] |= image
->fmask
.tile_swizzle
;
488 fmask_state
[1] = S_008F14_BASE_ADDRESS_HI(va
>> 40) |
489 S_008F14_DATA_FORMAT_GFX6(fmask_format
) |
490 S_008F14_NUM_FORMAT_GFX6(num_format
);
491 fmask_state
[2] = S_008F18_WIDTH(width
- 1) |
492 S_008F18_HEIGHT(height
- 1);
493 fmask_state
[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X
) |
494 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X
) |
495 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X
) |
496 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X
) |
497 S_008F1C_TYPE(radv_tex_dim(image
->type
, view_type
, 1, 0, false));
499 fmask_state
[5] = S_008F24_BASE_ARRAY(first_layer
);
503 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
504 fmask_state
[3] |= S_008F1C_SW_MODE(image
->surface
.u
.gfx9
.fmask
.swizzle_mode
);
505 fmask_state
[4] |= S_008F20_DEPTH(last_layer
) |
506 S_008F20_PITCH_GFX9(image
->surface
.u
.gfx9
.fmask
.epitch
);
507 fmask_state
[5] |= S_008F24_META_PIPE_ALIGNED(image
->surface
.u
.gfx9
.cmask
.pipe_aligned
) |
508 S_008F24_META_RB_ALIGNED(image
->surface
.u
.gfx9
.cmask
.rb_aligned
);
510 fmask_state
[3] |= S_008F1C_TILING_INDEX(image
->fmask
.tile_mode_index
);
511 fmask_state
[4] |= S_008F20_DEPTH(depth
- 1) |
512 S_008F20_PITCH_GFX6(image
->fmask
.pitch_in_pixels
- 1);
513 fmask_state
[5] |= S_008F24_LAST_ARRAY(last_layer
);
515 } else if (fmask_state
)
516 memset(fmask_state
, 0, 8 * 4);
520 radv_query_opaque_metadata(struct radv_device
*device
,
521 struct radv_image
*image
,
522 struct radeon_bo_metadata
*md
)
524 static const VkComponentMapping fixedmapping
;
527 /* Metadata image format format version 1:
528 * [0] = 1 (metadata format identifier)
529 * [1] = (VENDOR_ID << 16) | PCI_ID
530 * [2:9] = image descriptor for the whole resource
531 * [2] is always 0, because the base address is cleared
532 * [9] is the DCC offset bits [39:8] from the beginning of
534 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
536 md
->metadata
[0] = 1; /* metadata image format version 1 */
538 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
539 md
->metadata
[1] = si_get_bo_metadata_word1(device
);
542 si_make_texture_descriptor(device
, image
, false,
543 (VkImageViewType
)image
->type
, image
->vk_format
,
544 &fixedmapping
, 0, image
->info
.levels
- 1, 0,
545 image
->info
.array_size
,
546 image
->info
.width
, image
->info
.height
,
550 si_set_mutable_tex_desc_fields(device
, image
, &image
->surface
.u
.legacy
.level
[0], 0, 0,
551 image
->surface
.blk_w
, false, desc
);
553 /* Clear the base address and set the relative DCC offset. */
555 desc
[1] &= C_008F14_BASE_ADDRESS_HI
;
556 desc
[7] = image
->dcc_offset
>> 8;
558 /* Dwords [2:9] contain the image descriptor. */
559 memcpy(&md
->metadata
[2], desc
, sizeof(desc
));
561 /* Dwords [10:..] contain the mipmap level offsets. */
562 if (device
->physical_device
->rad_info
.chip_class
<= VI
) {
563 for (i
= 0; i
<= image
->info
.levels
- 1; i
++)
564 md
->metadata
[10+i
] = image
->surface
.u
.legacy
.level
[i
].offset
>> 8;
565 md
->size_metadata
= (11 + image
->info
.levels
- 1) * 4;
570 radv_init_metadata(struct radv_device
*device
,
571 struct radv_image
*image
,
572 struct radeon_bo_metadata
*metadata
)
574 struct radeon_surf
*surface
= &image
->surface
;
576 memset(metadata
, 0, sizeof(*metadata
));
578 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
579 metadata
->u
.gfx9
.swizzle_mode
= surface
->u
.gfx9
.surf
.swizzle_mode
;
581 metadata
->u
.legacy
.microtile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_1D
?
582 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
583 metadata
->u
.legacy
.macrotile
= surface
->u
.legacy
.level
[0].mode
>= RADEON_SURF_MODE_2D
?
584 RADEON_LAYOUT_TILED
: RADEON_LAYOUT_LINEAR
;
585 metadata
->u
.legacy
.pipe_config
= surface
->u
.legacy
.pipe_config
;
586 metadata
->u
.legacy
.bankw
= surface
->u
.legacy
.bankw
;
587 metadata
->u
.legacy
.bankh
= surface
->u
.legacy
.bankh
;
588 metadata
->u
.legacy
.tile_split
= surface
->u
.legacy
.tile_split
;
589 metadata
->u
.legacy
.mtilea
= surface
->u
.legacy
.mtilea
;
590 metadata
->u
.legacy
.num_banks
= surface
->u
.legacy
.num_banks
;
591 metadata
->u
.legacy
.stride
= surface
->u
.legacy
.level
[0].nblk_x
* surface
->bpe
;
592 metadata
->u
.legacy
.scanout
= (surface
->flags
& RADEON_SURF_SCANOUT
) != 0;
594 radv_query_opaque_metadata(device
, image
, metadata
);
597 /* The number of samples can be specified independently of the texture. */
599 radv_image_get_fmask_info(struct radv_device
*device
,
600 struct radv_image
*image
,
602 struct radv_fmask_info
*out
)
604 /* FMASK is allocated like an ordinary texture. */
605 struct radeon_surf fmask
= {};
606 struct ac_surf_info info
= image
->info
;
607 memset(out
, 0, sizeof(*out
));
609 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
610 out
->alignment
= image
->surface
.u
.gfx9
.fmask_alignment
;
611 out
->size
= image
->surface
.u
.gfx9
.fmask_size
;
615 fmask
.blk_w
= image
->surface
.blk_w
;
616 fmask
.blk_h
= image
->surface
.blk_h
;
618 fmask
.flags
= image
->surface
.flags
| RADEON_SURF_FMASK
;
620 if (!image
->shareable
)
621 info
.surf_index
= &device
->fmask_mrt_offset_counter
;
623 /* Force 2D tiling if it wasn't set. This may occur when creating
624 * FMASK for MSAA resolve on R6xx. On R6xx, the single-sample
625 * destination buffer must have an FMASK too. */
626 fmask
.flags
= RADEON_SURF_CLR(fmask
.flags
, MODE
);
627 fmask
.flags
|= RADEON_SURF_SET(RADEON_SURF_MODE_2D
, MODE
);
629 switch (nr_samples
) {
641 device
->ws
->surface_init(device
->ws
, &info
, &fmask
);
642 assert(fmask
.u
.legacy
.level
[0].mode
== RADEON_SURF_MODE_2D
);
644 out
->slice_tile_max
= (fmask
.u
.legacy
.level
[0].nblk_x
* fmask
.u
.legacy
.level
[0].nblk_y
) / 64;
645 if (out
->slice_tile_max
)
646 out
->slice_tile_max
-= 1;
648 out
->tile_mode_index
= fmask
.u
.legacy
.tiling_index
[0];
649 out
->pitch_in_pixels
= fmask
.u
.legacy
.level
[0].nblk_x
;
650 out
->bank_height
= fmask
.u
.legacy
.bankh
;
651 out
->tile_swizzle
= fmask
.tile_swizzle
;
652 out
->alignment
= MAX2(256, fmask
.surf_alignment
);
653 out
->size
= fmask
.surf_size
;
655 assert(!out
->tile_swizzle
|| !image
->shareable
);
659 radv_image_alloc_fmask(struct radv_device
*device
,
660 struct radv_image
*image
)
662 radv_image_get_fmask_info(device
, image
, image
->info
.samples
, &image
->fmask
);
664 image
->fmask
.offset
= align64(image
->size
, image
->fmask
.alignment
);
665 image
->size
= image
->fmask
.offset
+ image
->fmask
.size
;
666 image
->alignment
= MAX2(image
->alignment
, image
->fmask
.alignment
);
670 radv_image_get_cmask_info(struct radv_device
*device
,
671 struct radv_image
*image
,
672 struct radv_cmask_info
*out
)
674 unsigned pipe_interleave_bytes
= device
->physical_device
->rad_info
.pipe_interleave_bytes
;
675 unsigned num_pipes
= device
->physical_device
->rad_info
.num_tile_pipes
;
676 unsigned cl_width
, cl_height
;
678 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
679 out
->alignment
= image
->surface
.u
.gfx9
.cmask_alignment
;
680 out
->size
= image
->surface
.u
.gfx9
.cmask_size
;
697 case 16: /* Hawaii */
706 unsigned base_align
= num_pipes
* pipe_interleave_bytes
;
708 unsigned width
= align(image
->info
.width
, cl_width
*8);
709 unsigned height
= align(image
->info
.height
, cl_height
*8);
710 unsigned slice_elements
= (width
* height
) / (8*8);
712 /* Each element of CMASK is a nibble. */
713 unsigned slice_bytes
= slice_elements
/ 2;
715 out
->slice_tile_max
= (width
* height
) / (128*128);
716 if (out
->slice_tile_max
)
717 out
->slice_tile_max
-= 1;
719 out
->alignment
= MAX2(256, base_align
);
720 out
->size
= (image
->type
== VK_IMAGE_TYPE_3D
? image
->info
.depth
: image
->info
.array_size
) *
721 align(slice_bytes
, base_align
);
725 radv_image_alloc_cmask(struct radv_device
*device
,
726 struct radv_image
*image
)
728 uint32_t clear_value_size
= 0;
729 radv_image_get_cmask_info(device
, image
, &image
->cmask
);
731 image
->cmask
.offset
= align64(image
->size
, image
->cmask
.alignment
);
732 /* + 8 for storing the clear values */
733 if (!image
->clear_value_offset
) {
734 image
->clear_value_offset
= image
->cmask
.offset
+ image
->cmask
.size
;
735 clear_value_size
= 8;
737 image
->size
= image
->cmask
.offset
+ image
->cmask
.size
+ clear_value_size
;
738 image
->alignment
= MAX2(image
->alignment
, image
->cmask
.alignment
);
742 radv_image_alloc_dcc(struct radv_device
*device
,
743 struct radv_image
*image
)
745 image
->dcc_offset
= align64(image
->size
, image
->surface
.dcc_alignment
);
746 /* + 16 for storing the clear values + dcc pred */
747 image
->clear_value_offset
= image
->dcc_offset
+ image
->surface
.dcc_size
;
748 image
->dcc_pred_offset
= image
->clear_value_offset
+ 8;
749 image
->size
= image
->dcc_offset
+ image
->surface
.dcc_size
+ 16;
750 image
->alignment
= MAX2(image
->alignment
, image
->surface
.dcc_alignment
);
754 radv_image_alloc_htile(struct radv_device
*device
,
755 struct radv_image
*image
)
757 if ((device
->debug_flags
& RADV_DEBUG_NO_HIZ
) || image
->info
.levels
> 1) {
758 image
->surface
.htile_size
= 0;
762 image
->htile_offset
= align64(image
->size
, image
->surface
.htile_alignment
);
764 /* + 8 for storing the clear values */
765 image
->clear_value_offset
= image
->htile_offset
+ image
->surface
.htile_size
;
766 image
->size
= image
->clear_value_offset
+ 8;
767 image
->alignment
= align64(image
->alignment
, image
->surface
.htile_alignment
);
771 radv_image_create(VkDevice _device
,
772 const struct radv_image_create_info
*create_info
,
773 const VkAllocationCallbacks
* alloc
,
776 RADV_FROM_HANDLE(radv_device
, device
, _device
);
777 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
778 struct radv_image
*image
= NULL
;
779 bool can_cmask_dcc
= false;
780 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
782 radv_assert(pCreateInfo
->mipLevels
> 0);
783 radv_assert(pCreateInfo
->arrayLayers
> 0);
784 radv_assert(pCreateInfo
->samples
> 0);
785 radv_assert(pCreateInfo
->extent
.width
> 0);
786 radv_assert(pCreateInfo
->extent
.height
> 0);
787 radv_assert(pCreateInfo
->extent
.depth
> 0);
789 image
= vk_alloc2(&device
->alloc
, alloc
, sizeof(*image
), 8,
790 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
792 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
794 memset(image
, 0, sizeof(*image
));
795 image
->type
= pCreateInfo
->imageType
;
796 image
->info
.width
= pCreateInfo
->extent
.width
;
797 image
->info
.height
= pCreateInfo
->extent
.height
;
798 image
->info
.depth
= pCreateInfo
->extent
.depth
;
799 image
->info
.samples
= pCreateInfo
->samples
;
800 image
->info
.array_size
= pCreateInfo
->arrayLayers
;
801 image
->info
.levels
= pCreateInfo
->mipLevels
;
803 image
->vk_format
= pCreateInfo
->format
;
804 image
->tiling
= pCreateInfo
->tiling
;
805 image
->usage
= pCreateInfo
->usage
;
806 image
->flags
= pCreateInfo
->flags
;
808 image
->exclusive
= pCreateInfo
->sharingMode
== VK_SHARING_MODE_EXCLUSIVE
;
809 if (pCreateInfo
->sharingMode
== VK_SHARING_MODE_CONCURRENT
) {
810 for (uint32_t i
= 0; i
< pCreateInfo
->queueFamilyIndexCount
; ++i
)
811 if (pCreateInfo
->pQueueFamilyIndices
[i
] == VK_QUEUE_FAMILY_EXTERNAL_KHR
)
812 image
->queue_family_mask
|= (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
814 image
->queue_family_mask
|= 1u << pCreateInfo
->pQueueFamilyIndices
[i
];
817 image
->shareable
= vk_find_struct_const(pCreateInfo
->pNext
,
818 EXTERNAL_MEMORY_IMAGE_CREATE_INFO_KHR
) != NULL
;
819 if (!vk_format_is_depth(pCreateInfo
->format
) && !create_info
->scanout
&& !image
->shareable
) {
820 image
->info
.surf_index
= &device
->image_mrt_offset_counter
;
823 radv_init_surface(device
, &image
->surface
, create_info
);
825 device
->ws
->surface_init(device
->ws
, &image
->info
, &image
->surface
);
827 image
->size
= image
->surface
.surf_size
;
828 image
->alignment
= image
->surface
.surf_alignment
;
830 if (image
->exclusive
|| image
->queue_family_mask
== 1)
831 can_cmask_dcc
= true;
833 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) &&
834 image
->surface
.dcc_size
&& can_cmask_dcc
)
835 radv_image_alloc_dcc(device
, image
);
837 image
->surface
.dcc_size
= 0;
839 if ((pCreateInfo
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) &&
840 pCreateInfo
->mipLevels
== 1 &&
841 !image
->surface
.dcc_size
&& image
->info
.depth
== 1 && can_cmask_dcc
)
842 radv_image_alloc_cmask(device
, image
);
843 if (image
->info
.samples
> 1 && vk_format_is_color(pCreateInfo
->format
)) {
844 radv_image_alloc_fmask(device
, image
);
845 } else if (vk_format_is_depth(pCreateInfo
->format
)) {
847 radv_image_alloc_htile(device
, image
);
850 if (pCreateInfo
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
) {
851 image
->alignment
= MAX2(image
->alignment
, 4096);
852 image
->size
= align64(image
->size
, image
->alignment
);
855 image
->bo
= device
->ws
->buffer_create(device
->ws
, image
->size
, image
->alignment
,
856 0, RADEON_FLAG_VIRTUAL
);
858 vk_free2(&device
->alloc
, alloc
, image
);
859 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
863 *pImage
= radv_image_to_handle(image
);
869 radv_image_view_make_descriptor(struct radv_image_view
*iview
,
870 struct radv_device
*device
,
871 const VkComponentMapping
*components
,
872 bool is_storage_image
)
874 struct radv_image
*image
= iview
->image
;
875 bool is_stencil
= iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
;
877 uint32_t *descriptor
;
878 uint32_t *fmask_descriptor
;
879 uint32_t hw_level
= 0;
881 if (is_storage_image
) {
882 descriptor
= iview
->storage_descriptor
;
883 fmask_descriptor
= iview
->storage_fmask_descriptor
;
885 descriptor
= iview
->descriptor
;
886 fmask_descriptor
= iview
->fmask_descriptor
;
889 assert(image
->surface
.blk_w
% vk_format_get_blockwidth(image
->vk_format
) == 0);
890 blk_w
= image
->surface
.blk_w
/ vk_format_get_blockwidth(image
->vk_format
) * vk_format_get_blockwidth(iview
->vk_format
);
892 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
)
893 hw_level
= iview
->base_mip
;
894 si_make_texture_descriptor(device
, image
, is_storage_image
,
898 hw_level
, hw_level
+ iview
->level_count
- 1,
900 iview
->base_layer
+ iview
->layer_count
- 1,
902 iview
->extent
.height
,
907 const struct legacy_surf_level
*base_level_info
= NULL
;
908 if (device
->physical_device
->rad_info
.chip_class
<= GFX9
) {
910 base_level_info
= &image
->surface
.u
.legacy
.stencil_level
[iview
->base_mip
];
912 base_level_info
= &image
->surface
.u
.legacy
.level
[iview
->base_mip
];
914 si_set_mutable_tex_desc_fields(device
, image
,
918 blk_w
, is_stencil
, descriptor
);
922 radv_image_view_init(struct radv_image_view
*iview
,
923 struct radv_device
*device
,
924 const VkImageViewCreateInfo
* pCreateInfo
)
926 RADV_FROM_HANDLE(radv_image
, image
, pCreateInfo
->image
);
927 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
929 switch (image
->type
) {
930 case VK_IMAGE_TYPE_1D
:
931 case VK_IMAGE_TYPE_2D
:
932 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1 <= image
->info
.array_size
);
934 case VK_IMAGE_TYPE_3D
:
935 assert(range
->baseArrayLayer
+ radv_get_layerCount(image
, range
) - 1
936 <= radv_minify(image
->info
.depth
, range
->baseMipLevel
));
939 unreachable("bad VkImageType");
941 iview
->image
= image
;
942 iview
->bo
= image
->bo
;
943 iview
->type
= pCreateInfo
->viewType
;
944 iview
->vk_format
= pCreateInfo
->format
;
945 iview
->aspect_mask
= pCreateInfo
->subresourceRange
.aspectMask
;
947 if (iview
->aspect_mask
== VK_IMAGE_ASPECT_STENCIL_BIT
) {
948 iview
->vk_format
= vk_format_stencil_only(iview
->vk_format
);
949 } else if (iview
->aspect_mask
== VK_IMAGE_ASPECT_DEPTH_BIT
) {
950 iview
->vk_format
= vk_format_depth_only(iview
->vk_format
);
953 if (device
->physical_device
->rad_info
.chip_class
>= GFX9
) {
954 iview
->extent
= (VkExtent3D
) {
955 .width
= image
->info
.width
,
956 .height
= image
->info
.height
,
957 .depth
= image
->info
.depth
,
960 iview
->extent
= (VkExtent3D
) {
961 .width
= radv_minify(image
->info
.width
, range
->baseMipLevel
),
962 .height
= radv_minify(image
->info
.height
, range
->baseMipLevel
),
963 .depth
= radv_minify(image
->info
.depth
, range
->baseMipLevel
),
967 if (iview
->vk_format
!= image
->vk_format
) {
968 iview
->extent
.width
= round_up_u32(iview
->extent
.width
* vk_format_get_blockwidth(iview
->vk_format
),
969 vk_format_get_blockwidth(image
->vk_format
));
970 iview
->extent
.height
= round_up_u32(iview
->extent
.height
* vk_format_get_blockheight(iview
->vk_format
),
971 vk_format_get_blockheight(image
->vk_format
));
974 iview
->base_layer
= range
->baseArrayLayer
;
975 iview
->layer_count
= radv_get_layerCount(image
, range
);
976 iview
->base_mip
= range
->baseMipLevel
;
977 iview
->level_count
= radv_get_levelCount(image
, range
);
979 radv_image_view_make_descriptor(iview
, device
, &pCreateInfo
->components
, false);
980 radv_image_view_make_descriptor(iview
, device
, &pCreateInfo
->components
, true);
983 bool radv_layout_has_htile(const struct radv_image
*image
,
984 VkImageLayout layout
,
987 return image
->surface
.htile_size
&&
988 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
989 layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
) &&
990 queue_mask
== (1u << RADV_QUEUE_GENERAL
);
993 bool radv_layout_is_htile_compressed(const struct radv_image
*image
,
994 VkImageLayout layout
,
997 return image
->surface
.htile_size
&&
998 (layout
== VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL
||
999 layout
== VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL
) &&
1000 queue_mask
== (1u << RADV_QUEUE_GENERAL
);
1003 bool radv_layout_can_fast_clear(const struct radv_image
*image
,
1004 VkImageLayout layout
,
1005 unsigned queue_mask
)
1007 return layout
== VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL
&&
1008 queue_mask
== (1u << RADV_QUEUE_GENERAL
);
1012 unsigned radv_image_queue_family_mask(const struct radv_image
*image
, uint32_t family
, uint32_t queue_family
)
1014 if (!image
->exclusive
)
1015 return image
->queue_family_mask
;
1016 if (family
== VK_QUEUE_FAMILY_EXTERNAL_KHR
)
1017 return (1u << RADV_MAX_QUEUE_FAMILIES
) - 1u;
1018 if (family
== VK_QUEUE_FAMILY_IGNORED
)
1019 return 1u << queue_family
;
1020 return 1u << family
;
1024 radv_CreateImage(VkDevice device
,
1025 const VkImageCreateInfo
*pCreateInfo
,
1026 const VkAllocationCallbacks
*pAllocator
,
1029 return radv_image_create(device
,
1030 &(struct radv_image_create_info
) {
1031 .vk_info
= pCreateInfo
,
1039 radv_DestroyImage(VkDevice _device
, VkImage _image
,
1040 const VkAllocationCallbacks
*pAllocator
)
1042 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1043 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1048 if (image
->flags
& VK_IMAGE_CREATE_SPARSE_BINDING_BIT
)
1049 device
->ws
->buffer_destroy(image
->bo
);
1051 vk_free2(&device
->alloc
, pAllocator
, image
);
1054 void radv_GetImageSubresourceLayout(
1057 const VkImageSubresource
* pSubresource
,
1058 VkSubresourceLayout
* pLayout
)
1060 RADV_FROM_HANDLE(radv_image
, image
, _image
);
1061 int level
= pSubresource
->mipLevel
;
1062 int layer
= pSubresource
->arrayLayer
;
1063 struct radeon_surf
*surface
= &image
->surface
;
1065 pLayout
->offset
= surface
->u
.legacy
.level
[level
].offset
+ surface
->u
.legacy
.level
[level
].slice_size
* layer
;
1066 pLayout
->rowPitch
= surface
->u
.legacy
.level
[level
].nblk_x
* surface
->bpe
;
1067 pLayout
->arrayPitch
= surface
->u
.legacy
.level
[level
].slice_size
;
1068 pLayout
->depthPitch
= surface
->u
.legacy
.level
[level
].slice_size
;
1069 pLayout
->size
= surface
->u
.legacy
.level
[level
].slice_size
;
1070 if (image
->type
== VK_IMAGE_TYPE_3D
)
1071 pLayout
->size
*= u_minify(image
->info
.depth
, level
);
1076 radv_CreateImageView(VkDevice _device
,
1077 const VkImageViewCreateInfo
*pCreateInfo
,
1078 const VkAllocationCallbacks
*pAllocator
,
1081 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1082 struct radv_image_view
*view
;
1084 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
1085 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1087 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1089 radv_image_view_init(view
, device
, pCreateInfo
);
1091 *pView
= radv_image_view_to_handle(view
);
1097 radv_DestroyImageView(VkDevice _device
, VkImageView _iview
,
1098 const VkAllocationCallbacks
*pAllocator
)
1100 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1101 RADV_FROM_HANDLE(radv_image_view
, iview
, _iview
);
1105 vk_free2(&device
->alloc
, pAllocator
, iview
);
1108 void radv_buffer_view_init(struct radv_buffer_view
*view
,
1109 struct radv_device
*device
,
1110 const VkBufferViewCreateInfo
* pCreateInfo
,
1111 struct radv_cmd_buffer
*cmd_buffer
)
1113 RADV_FROM_HANDLE(radv_buffer
, buffer
, pCreateInfo
->buffer
);
1115 view
->bo
= buffer
->bo
;
1116 view
->range
= pCreateInfo
->range
== VK_WHOLE_SIZE
?
1117 buffer
->size
- pCreateInfo
->offset
: pCreateInfo
->range
;
1118 view
->vk_format
= pCreateInfo
->format
;
1120 radv_make_buffer_descriptor(device
, buffer
, view
->vk_format
,
1121 pCreateInfo
->offset
, view
->range
, view
->state
);
1125 radv_CreateBufferView(VkDevice _device
,
1126 const VkBufferViewCreateInfo
*pCreateInfo
,
1127 const VkAllocationCallbacks
*pAllocator
,
1128 VkBufferView
*pView
)
1130 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1131 struct radv_buffer_view
*view
;
1133 view
= vk_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
1134 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
1136 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
1138 radv_buffer_view_init(view
, device
, pCreateInfo
, NULL
);
1140 *pView
= radv_buffer_view_to_handle(view
);
1146 radv_DestroyBufferView(VkDevice _device
, VkBufferView bufferView
,
1147 const VkAllocationCallbacks
*pAllocator
)
1149 RADV_FROM_HANDLE(radv_device
, device
, _device
);
1150 RADV_FROM_HANDLE(radv_buffer_view
, view
, bufferView
);
1155 vk_free2(&device
->alloc
, pAllocator
, view
);