Revert "radv: Do not decompress on LAYOUT_GENERAL."
[mesa.git] / src / amd / vulkan / radv_image.c
1 /*
2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
4 *
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
7 *
8 * 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:
14 *
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
17 * Software.
18 *
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
25 * IN THE SOFTWARE.
26 */
27
28 #include "radv_debug.h"
29 #include "radv_private.h"
30 #include "vk_format.h"
31 #include "vk_util.h"
32 #include "radv_radeon_winsys.h"
33 #include "sid.h"
34 #include "util/debug.h"
35 #include "util/u_atomic.h"
36
37 static unsigned
38 radv_choose_tiling(struct radv_device *device,
39 const struct radv_image_create_info *create_info)
40 {
41 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
42
43 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
44 assert(pCreateInfo->samples <= 1);
45 return RADEON_SURF_MODE_LINEAR_ALIGNED;
46 }
47
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 <= GFX8) {
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
55 * linear_aligned. */
56 (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
57 return RADEON_SURF_MODE_LINEAR_ALIGNED;
58 }
59
60 /* MSAA resources must be 2D tiled. */
61 if (pCreateInfo->samples > 1)
62 return RADEON_SURF_MODE_2D;
63
64 return RADEON_SURF_MODE_2D;
65 }
66
67 static bool
68 radv_use_tc_compat_htile_for_image(struct radv_device *device,
69 const VkImageCreateInfo *pCreateInfo)
70 {
71 /* TC-compat HTILE is only available for GFX8+. */
72 if (device->physical_device->rad_info.chip_class < GFX8)
73 return false;
74
75 if ((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) ||
76 (pCreateInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT))
77 return false;
78
79 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
80 return false;
81
82 if (pCreateInfo->mipLevels > 1)
83 return false;
84
85 /* FIXME: for some reason TC compat with 2/4/8 samples breaks some cts
86 * tests - disable for now. On GFX10 D32_SFLOAT is affected as well.
87 */
88 if (pCreateInfo->samples >= 2 &&
89 (pCreateInfo->format == VK_FORMAT_D32_SFLOAT_S8_UINT ||
90 (pCreateInfo->format == VK_FORMAT_D32_SFLOAT &&
91 device->physical_device->rad_info.chip_class == GFX10)))
92 return false;
93
94 /* GFX9 supports both 32-bit and 16-bit depth surfaces, while GFX8 only
95 * supports 32-bit. Though, it's possible to enable TC-compat for
96 * 16-bit depth surfaces if no Z planes are compressed.
97 */
98 if (pCreateInfo->format != VK_FORMAT_D32_SFLOAT_S8_UINT &&
99 pCreateInfo->format != VK_FORMAT_D32_SFLOAT &&
100 pCreateInfo->format != VK_FORMAT_D16_UNORM)
101 return false;
102
103 if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
104 const struct VkImageFormatListCreateInfoKHR *format_list =
105 (const struct VkImageFormatListCreateInfoKHR *)
106 vk_find_struct_const(pCreateInfo->pNext,
107 IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
108
109 /* We have to ignore the existence of the list if viewFormatCount = 0 */
110 if (format_list && format_list->viewFormatCount) {
111 /* compatibility is transitive, so we only need to check
112 * one format with everything else.
113 */
114 for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
115 if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
116 continue;
117
118 if (pCreateInfo->format != format_list->pViewFormats[i])
119 return false;
120 }
121 } else {
122 return false;
123 }
124 }
125
126 return true;
127 }
128
129 static bool
130 radv_surface_has_scanout(struct radv_device *device, const struct radv_image_create_info *info)
131 {
132 if (info->scanout)
133 return true;
134
135 if (!info->bo_metadata)
136 return false;
137
138 if (device->physical_device->rad_info.chip_class >= GFX9) {
139 return info->bo_metadata->u.gfx9.swizzle_mode == 0 || info->bo_metadata->u.gfx9.swizzle_mode % 4 == 2;
140 } else {
141 return info->bo_metadata->u.legacy.scanout;
142 }
143 }
144
145 static bool
146 radv_support_storage_dcc(const struct radv_physical_device *pdevice)
147 {
148 return pdevice->rad_info.chip_class >= GFX10 &&
149 (pdevice->instance->perftest_flags & RADV_PERFTEST_STORAGE_DCC);
150 }
151
152 static bool
153 radv_use_dcc_for_image(struct radv_device *device,
154 const struct radv_image *image,
155 const struct radv_image_create_info *create_info,
156 const VkImageCreateInfo *pCreateInfo)
157 {
158 bool dcc_compatible_formats;
159 bool blendable;
160
161 /* DCC (Delta Color Compression) is only available for GFX8+. */
162 if (device->physical_device->rad_info.chip_class < GFX8)
163 return false;
164
165 if (device->instance->debug_flags & RADV_DEBUG_NO_DCC)
166 return false;
167
168 if (image->shareable)
169 return false;
170
171 if (((pCreateInfo->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
172 !radv_support_storage_dcc(device->physical_device))||
173 (pCreateInfo->flags & VK_IMAGE_CREATE_EXTENDED_USAGE_BIT))
174 return false;
175
176 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR)
177 return false;
178
179 if (vk_format_is_subsampled(pCreateInfo->format) ||
180 vk_format_get_plane_count(pCreateInfo->format) > 1)
181 return false;
182
183 /* TODO: Enable DCC for mipmaps on GFX9+. */
184 if ((pCreateInfo->arrayLayers > 1 || pCreateInfo->mipLevels > 1) &&
185 device->physical_device->rad_info.chip_class >= GFX9)
186 return false;
187
188 /* Do not enable DCC for mipmapped arrays because performance is worse. */
189 if (pCreateInfo->arrayLayers > 1 && pCreateInfo->mipLevels > 1)
190 return false;
191
192 if (radv_surface_has_scanout(device, create_info))
193 return false;
194
195 /* FIXME: DCC for MSAA with 4x and 8x samples doesn't work yet, while
196 * 2x can be enabled with an option.
197 */
198 if (pCreateInfo->samples > 2 ||
199 (pCreateInfo->samples == 2 &&
200 !device->physical_device->dcc_msaa_allowed))
201 return false;
202
203 /* Determine if the formats are DCC compatible. */
204 dcc_compatible_formats =
205 radv_is_colorbuffer_format_supported(pCreateInfo->format,
206 &blendable);
207
208 if (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) {
209 const struct VkImageFormatListCreateInfoKHR *format_list =
210 (const struct VkImageFormatListCreateInfoKHR *)
211 vk_find_struct_const(pCreateInfo->pNext,
212 IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
213
214 /* We have to ignore the existence of the list if viewFormatCount = 0 */
215 if (format_list && format_list->viewFormatCount) {
216 /* compatibility is transitive, so we only need to check
217 * one format with everything else. */
218 for (unsigned i = 0; i < format_list->viewFormatCount; ++i) {
219 if (format_list->pViewFormats[i] == VK_FORMAT_UNDEFINED)
220 continue;
221
222 if (!radv_dcc_formats_compatible(pCreateInfo->format,
223 format_list->pViewFormats[i]))
224 dcc_compatible_formats = false;
225 }
226 } else {
227 dcc_compatible_formats = false;
228 }
229 }
230
231 if (!dcc_compatible_formats)
232 return false;
233
234 return true;
235 }
236
237 static bool
238 radv_use_tc_compat_cmask_for_image(struct radv_device *device,
239 struct radv_image *image)
240 {
241 if (!(device->instance->perftest_flags & RADV_PERFTEST_TC_COMPAT_CMASK))
242 return false;
243
244 /* TC-compat CMASK is only available for GFX8+. */
245 if (device->physical_device->rad_info.chip_class < GFX8)
246 return false;
247
248 if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT)
249 return false;
250
251 if (radv_image_has_dcc(image))
252 return false;
253
254 if (!radv_image_has_cmask(image))
255 return false;
256
257 return true;
258 }
259
260 static void
261 radv_prefill_surface_from_metadata(struct radv_device *device,
262 struct radeon_surf *surface,
263 const struct radv_image_create_info *create_info)
264 {
265 const struct radeon_bo_metadata *md = create_info->bo_metadata;
266 if (device->physical_device->rad_info.chip_class >= GFX9) {
267 if (md->u.gfx9.swizzle_mode > 0)
268 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
269 else
270 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
271
272 surface->u.gfx9.surf.swizzle_mode = md->u.gfx9.swizzle_mode;
273 } else {
274 surface->u.legacy.pipe_config = md->u.legacy.pipe_config;
275 surface->u.legacy.bankw = md->u.legacy.bankw;
276 surface->u.legacy.bankh = md->u.legacy.bankh;
277 surface->u.legacy.tile_split = md->u.legacy.tile_split;
278 surface->u.legacy.mtilea = md->u.legacy.mtilea;
279 surface->u.legacy.num_banks = md->u.legacy.num_banks;
280
281 if (md->u.legacy.macrotile == RADEON_LAYOUT_TILED)
282 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
283 else if (md->u.legacy.microtile == RADEON_LAYOUT_TILED)
284 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
285 else
286 surface->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_LINEAR_ALIGNED, MODE);
287
288 }
289 }
290
291 static int
292 radv_init_surface(struct radv_device *device,
293 const struct radv_image *image,
294 struct radeon_surf *surface,
295 unsigned plane_id,
296 const struct radv_image_create_info *create_info)
297 {
298 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
299 unsigned array_mode = radv_choose_tiling(device, create_info);
300 VkFormat format = vk_format_get_plane_format(pCreateInfo->format, plane_id);
301 const struct vk_format_description *desc = vk_format_description(format);
302 bool is_depth, is_stencil;
303
304 is_depth = vk_format_has_depth(desc);
305 is_stencil = vk_format_has_stencil(desc);
306
307 surface->blk_w = vk_format_get_blockwidth(format);
308 surface->blk_h = vk_format_get_blockheight(format);
309
310 surface->bpe = vk_format_get_blocksize(vk_format_depth_only(format));
311 /* align byte per element on dword */
312 if (surface->bpe == 3) {
313 surface->bpe = 4;
314 }
315 if (create_info->bo_metadata) {
316 radv_prefill_surface_from_metadata(device, surface, create_info);
317 } else {
318 surface->flags = RADEON_SURF_SET(array_mode, MODE);
319 }
320
321 switch (pCreateInfo->imageType){
322 case VK_IMAGE_TYPE_1D:
323 if (pCreateInfo->arrayLayers > 1)
324 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
325 else
326 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
327 break;
328 case VK_IMAGE_TYPE_2D:
329 if (pCreateInfo->arrayLayers > 1)
330 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
331 else
332 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
333 break;
334 case VK_IMAGE_TYPE_3D:
335 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
336 break;
337 default:
338 unreachable("unhandled image type");
339 }
340
341 if (is_depth) {
342 surface->flags |= RADEON_SURF_ZBUFFER;
343 if (radv_use_tc_compat_htile_for_image(device, pCreateInfo))
344 surface->flags |= RADEON_SURF_TC_COMPATIBLE_HTILE;
345 }
346
347 if (is_stencil)
348 surface->flags |= RADEON_SURF_SBUFFER;
349
350 if (device->physical_device->rad_info.chip_class >= GFX9 &&
351 pCreateInfo->imageType == VK_IMAGE_TYPE_3D &&
352 vk_format_get_blocksizebits(pCreateInfo->format) == 128 &&
353 vk_format_is_compressed(pCreateInfo->format))
354 surface->flags |= RADEON_SURF_NO_RENDER_TARGET;
355
356 surface->flags |= RADEON_SURF_OPTIMIZE_FOR_SPACE;
357
358 if (!radv_use_dcc_for_image(device, image, create_info, pCreateInfo))
359 surface->flags |= RADEON_SURF_DISABLE_DCC;
360
361 if (radv_surface_has_scanout(device, create_info))
362 surface->flags |= RADEON_SURF_SCANOUT;
363
364 return 0;
365 }
366
367 static uint32_t si_get_bo_metadata_word1(struct radv_device *device)
368 {
369 return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id;
370 }
371
372 static inline unsigned
373 si_tile_mode_index(const struct radv_image_plane *plane, unsigned level, bool stencil)
374 {
375 if (stencil)
376 return plane->surface.u.legacy.stencil_tiling_index[level];
377 else
378 return plane->surface.u.legacy.tiling_index[level];
379 }
380
381 static unsigned radv_map_swizzle(unsigned swizzle)
382 {
383 switch (swizzle) {
384 case VK_SWIZZLE_Y:
385 return V_008F0C_SQ_SEL_Y;
386 case VK_SWIZZLE_Z:
387 return V_008F0C_SQ_SEL_Z;
388 case VK_SWIZZLE_W:
389 return V_008F0C_SQ_SEL_W;
390 case VK_SWIZZLE_0:
391 return V_008F0C_SQ_SEL_0;
392 case VK_SWIZZLE_1:
393 return V_008F0C_SQ_SEL_1;
394 default: /* VK_SWIZZLE_X */
395 return V_008F0C_SQ_SEL_X;
396 }
397 }
398
399 static void
400 radv_make_buffer_descriptor(struct radv_device *device,
401 struct radv_buffer *buffer,
402 VkFormat vk_format,
403 unsigned offset,
404 unsigned range,
405 uint32_t *state)
406 {
407 const struct vk_format_description *desc;
408 unsigned stride;
409 uint64_t gpu_address = radv_buffer_get_va(buffer->bo);
410 uint64_t va = gpu_address + buffer->offset;
411 unsigned num_format, data_format;
412 int first_non_void;
413 desc = vk_format_description(vk_format);
414 first_non_void = vk_format_get_first_non_void_channel(vk_format);
415 stride = desc->block.bits / 8;
416
417 va += offset;
418 state[0] = va;
419 state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
420 S_008F04_STRIDE(stride);
421
422 if (device->physical_device->rad_info.chip_class != GFX8 && stride) {
423 range /= stride;
424 }
425
426 state[2] = range;
427 state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc->swizzle[0])) |
428 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc->swizzle[1])) |
429 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc->swizzle[2])) |
430 S_008F0C_DST_SEL_W(radv_map_swizzle(desc->swizzle[3]));
431
432 if (device->physical_device->rad_info.chip_class >= GFX10) {
433 const struct gfx10_format *fmt = &gfx10_format_table[vk_format];
434
435 /* OOB_SELECT chooses the out-of-bounds check:
436 * - 0: (index >= NUM_RECORDS) || (offset >= STRIDE)
437 * - 1: index >= NUM_RECORDS
438 * - 2: NUM_RECORDS == 0
439 * - 3: if SWIZZLE_ENABLE == 0: offset >= NUM_RECORDS
440 * else: swizzle_address >= NUM_RECORDS
441 */
442 state[3] |= S_008F0C_FORMAT(fmt->img_format) |
443 S_008F0C_OOB_SELECT(0) |
444 S_008F0C_RESOURCE_LEVEL(1);
445 } else {
446 num_format = radv_translate_buffer_numformat(desc, first_non_void);
447 data_format = radv_translate_buffer_dataformat(desc, first_non_void);
448
449 assert(data_format != V_008F0C_BUF_DATA_FORMAT_INVALID);
450 assert(num_format != ~0);
451
452 state[3] |= S_008F0C_NUM_FORMAT(num_format) |
453 S_008F0C_DATA_FORMAT(data_format);
454 }
455 }
456
457 static void
458 si_set_mutable_tex_desc_fields(struct radv_device *device,
459 struct radv_image *image,
460 const struct legacy_surf_level *base_level_info,
461 unsigned plane_id,
462 unsigned base_level, unsigned first_level,
463 unsigned block_width, bool is_stencil,
464 bool is_storage_image, bool disable_compression,
465 uint32_t *state)
466 {
467 struct radv_image_plane *plane = &image->planes[plane_id];
468 uint64_t gpu_address = image->bo ? radv_buffer_get_va(image->bo) + image->offset : 0;
469 uint64_t va = gpu_address + plane->offset;
470 enum chip_class chip_class = device->physical_device->rad_info.chip_class;
471 uint64_t meta_va = 0;
472 if (chip_class >= GFX9) {
473 if (is_stencil)
474 va += plane->surface.u.gfx9.stencil_offset;
475 else
476 va += plane->surface.u.gfx9.surf_offset;
477 } else
478 va += base_level_info->offset;
479
480 state[0] = va >> 8;
481 if (chip_class >= GFX9 ||
482 base_level_info->mode == RADEON_SURF_MODE_2D)
483 state[0] |= plane->surface.tile_swizzle;
484 state[1] &= C_008F14_BASE_ADDRESS_HI;
485 state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
486
487 if (chip_class >= GFX8) {
488 state[6] &= C_008F28_COMPRESSION_EN;
489 state[7] = 0;
490 if (!disable_compression && radv_dcc_enabled(image, first_level)) {
491 meta_va = gpu_address + image->dcc_offset;
492 if (chip_class <= GFX8)
493 meta_va += base_level_info->dcc_offset;
494
495 unsigned dcc_tile_swizzle = plane->surface.tile_swizzle << 8;
496 dcc_tile_swizzle &= plane->surface.dcc_alignment - 1;
497 meta_va |= dcc_tile_swizzle;
498 } else if (!disable_compression &&
499 radv_image_is_tc_compat_htile(image)) {
500 meta_va = gpu_address + image->htile_offset;
501 }
502
503 if (meta_va) {
504 state[6] |= S_008F28_COMPRESSION_EN(1);
505 if (chip_class <= GFX9)
506 state[7] = meta_va >> 8;
507 }
508 }
509
510 if (chip_class >= GFX10) {
511 state[3] &= C_00A00C_SW_MODE;
512
513 if (is_stencil) {
514 state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.stencil.swizzle_mode);
515 } else {
516 state[3] |= S_00A00C_SW_MODE(plane->surface.u.gfx9.surf.swizzle_mode);
517 }
518
519 state[6] &= C_00A018_META_DATA_ADDRESS_LO &
520 C_00A018_META_PIPE_ALIGNED;
521
522 if (meta_va) {
523 struct gfx9_surf_meta_flags meta;
524
525 if (image->dcc_offset)
526 meta = plane->surface.u.gfx9.dcc;
527 else
528 meta = plane->surface.u.gfx9.htile;
529
530 state[6] |= S_00A018_META_PIPE_ALIGNED(meta.pipe_aligned) |
531 S_00A018_META_DATA_ADDRESS_LO(meta_va >> 8);
532 }
533
534 state[7] = meta_va >> 16;
535 } else if (chip_class == GFX9) {
536 state[3] &= C_008F1C_SW_MODE;
537 state[4] &= C_008F20_PITCH;
538
539 if (is_stencil) {
540 state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.stencil.swizzle_mode);
541 state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.stencil.epitch);
542 } else {
543 state[3] |= S_008F1C_SW_MODE(plane->surface.u.gfx9.surf.swizzle_mode);
544 state[4] |= S_008F20_PITCH(plane->surface.u.gfx9.surf.epitch);
545 }
546
547 state[5] &= C_008F24_META_DATA_ADDRESS &
548 C_008F24_META_PIPE_ALIGNED &
549 C_008F24_META_RB_ALIGNED;
550 if (meta_va) {
551 struct gfx9_surf_meta_flags meta;
552
553 if (image->dcc_offset)
554 meta = plane->surface.u.gfx9.dcc;
555 else
556 meta = plane->surface.u.gfx9.htile;
557
558 state[5] |= S_008F24_META_DATA_ADDRESS(meta_va >> 40) |
559 S_008F24_META_PIPE_ALIGNED(meta.pipe_aligned) |
560 S_008F24_META_RB_ALIGNED(meta.rb_aligned);
561 }
562 } else {
563 /* GFX6-GFX8 */
564 unsigned pitch = base_level_info->nblk_x * block_width;
565 unsigned index = si_tile_mode_index(plane, base_level, is_stencil);
566
567 state[3] &= C_008F1C_TILING_INDEX;
568 state[3] |= S_008F1C_TILING_INDEX(index);
569 state[4] &= C_008F20_PITCH;
570 state[4] |= S_008F20_PITCH(pitch - 1);
571 }
572 }
573
574 static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
575 unsigned nr_layers, unsigned nr_samples, bool is_storage_image, bool gfx9)
576 {
577 if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
578 return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
579
580 /* GFX9 allocates 1D textures as 2D. */
581 if (gfx9 && image_type == VK_IMAGE_TYPE_1D)
582 image_type = VK_IMAGE_TYPE_2D;
583 switch (image_type) {
584 case VK_IMAGE_TYPE_1D:
585 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
586 case VK_IMAGE_TYPE_2D:
587 if (nr_samples > 1)
588 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY : V_008F1C_SQ_RSRC_IMG_2D_MSAA;
589 else
590 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_2D;
591 case VK_IMAGE_TYPE_3D:
592 if (view_type == VK_IMAGE_VIEW_TYPE_3D)
593 return V_008F1C_SQ_RSRC_IMG_3D;
594 else
595 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
596 default:
597 unreachable("illegal image type");
598 }
599 }
600
601 static unsigned gfx9_border_color_swizzle(const enum vk_swizzle swizzle[4])
602 {
603 unsigned bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
604
605 if (swizzle[3] == VK_SWIZZLE_X) {
606 /* For the pre-defined border color values (white, opaque
607 * black, transparent black), the only thing that matters is
608 * that the alpha channel winds up in the correct place
609 * (because the RGB channels are all the same) so either of
610 * these enumerations will work.
611 */
612 if (swizzle[2] == VK_SWIZZLE_Y)
613 bc_swizzle = V_008F20_BC_SWIZZLE_WZYX;
614 else
615 bc_swizzle = V_008F20_BC_SWIZZLE_WXYZ;
616 } else if (swizzle[0] == VK_SWIZZLE_X) {
617 if (swizzle[1] == VK_SWIZZLE_Y)
618 bc_swizzle = V_008F20_BC_SWIZZLE_XYZW;
619 else
620 bc_swizzle = V_008F20_BC_SWIZZLE_XWYZ;
621 } else if (swizzle[1] == VK_SWIZZLE_X) {
622 bc_swizzle = V_008F20_BC_SWIZZLE_YXWZ;
623 } else if (swizzle[2] == VK_SWIZZLE_X) {
624 bc_swizzle = V_008F20_BC_SWIZZLE_ZYXW;
625 }
626
627 return bc_swizzle;
628 }
629
630 static bool vi_alpha_is_on_msb(struct radv_device *device, VkFormat format)
631 {
632 const struct vk_format_description *desc = vk_format_description(format);
633
634 if (device->physical_device->rad_info.chip_class >= GFX10 && desc->nr_channels == 1)
635 return desc->swizzle[3] == VK_SWIZZLE_X;
636
637 return radv_translate_colorswap(format, false) <= 1;
638 }
639 /**
640 * Build the sampler view descriptor for a texture (GFX10).
641 */
642 static void
643 gfx10_make_texture_descriptor(struct radv_device *device,
644 struct radv_image *image,
645 bool is_storage_image,
646 VkImageViewType view_type,
647 VkFormat vk_format,
648 const VkComponentMapping *mapping,
649 unsigned first_level, unsigned last_level,
650 unsigned first_layer, unsigned last_layer,
651 unsigned width, unsigned height, unsigned depth,
652 uint32_t *state,
653 uint32_t *fmask_state)
654 {
655 const struct vk_format_description *desc;
656 enum vk_swizzle swizzle[4];
657 unsigned img_format;
658 unsigned type;
659
660 desc = vk_format_description(vk_format);
661 img_format = gfx10_format_table[vk_format].img_format;
662
663 if (desc->colorspace == VK_FORMAT_COLORSPACE_ZS) {
664 const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
665 vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
666 } else {
667 vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
668 }
669
670 type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
671 is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
672 if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
673 height = 1;
674 depth = image->info.array_size;
675 } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY ||
676 type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
677 if (view_type != VK_IMAGE_VIEW_TYPE_3D)
678 depth = image->info.array_size;
679 } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
680 depth = image->info.array_size / 6;
681
682 state[0] = 0;
683 state[1] = S_00A004_FORMAT(img_format) |
684 S_00A004_WIDTH_LO(width - 1);
685 state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) |
686 S_00A008_HEIGHT(height - 1) |
687 S_00A008_RESOURCE_LEVEL(1);
688 state[3] = S_00A00C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
689 S_00A00C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
690 S_00A00C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
691 S_00A00C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
692 S_00A00C_BASE_LEVEL(image->info.samples > 1 ?
693 0 : first_level) |
694 S_00A00C_LAST_LEVEL(image->info.samples > 1 ?
695 util_logbase2(image->info.samples) :
696 last_level) |
697 S_00A00C_BC_SWIZZLE(gfx9_border_color_swizzle(swizzle)) |
698 S_00A00C_TYPE(type);
699 /* Depth is the the last accessible layer on gfx9+. The hw doesn't need
700 * to know the total number of layers.
701 */
702 state[4] = S_00A010_DEPTH(type == V_008F1C_SQ_RSRC_IMG_3D ? depth - 1 : last_layer) |
703 S_00A010_BASE_ARRAY(first_layer);
704 state[5] = S_00A014_ARRAY_PITCH(!!(type == V_008F1C_SQ_RSRC_IMG_3D)) |
705 S_00A014_MAX_MIP(image->info.samples > 1 ?
706 util_logbase2(image->info.samples) :
707 image->info.levels - 1) |
708 S_00A014_PERF_MOD(4);
709 state[6] = 0;
710 state[7] = 0;
711
712 if (radv_dcc_enabled(image, first_level)) {
713 state[6] |= S_00A018_MAX_UNCOMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_256B) |
714 S_00A018_MAX_COMPRESSED_BLOCK_SIZE(V_028C78_MAX_BLOCK_SIZE_128B) |
715 S_00A018_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
716 }
717
718 /* Initialize the sampler view for FMASK. */
719 if (radv_image_has_fmask(image)) {
720 uint64_t gpu_address = radv_buffer_get_va(image->bo);
721 uint32_t format;
722 uint64_t va;
723
724 assert(image->plane_count == 1);
725
726 va = gpu_address + image->offset + image->fmask_offset;
727
728 switch (image->info.samples) {
729 case 2:
730 format = V_008F0C_IMG_FORMAT_FMASK8_S2_F2;
731 break;
732 case 4:
733 format = V_008F0C_IMG_FORMAT_FMASK8_S4_F4;
734 break;
735 case 8:
736 format = V_008F0C_IMG_FORMAT_FMASK32_S8_F8;
737 break;
738 default:
739 unreachable("invalid nr_samples");
740 }
741
742 fmask_state[0] = (va >> 8) | image->planes[0].surface.fmask_tile_swizzle;
743 fmask_state[1] = S_00A004_BASE_ADDRESS_HI(va >> 40) |
744 S_00A004_FORMAT(format) |
745 S_00A004_WIDTH_LO(width - 1);
746 fmask_state[2] = S_00A008_WIDTH_HI((width - 1) >> 2) |
747 S_00A008_HEIGHT(height - 1) |
748 S_00A008_RESOURCE_LEVEL(1);
749 fmask_state[3] = S_00A00C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
750 S_00A00C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
751 S_00A00C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
752 S_00A00C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
753 S_00A00C_SW_MODE(image->planes[0].surface.u.gfx9.fmask.swizzle_mode) |
754 S_00A00C_TYPE(radv_tex_dim(image->type, view_type, image->info.array_size, 0, false, false));
755 fmask_state[4] = S_00A010_DEPTH(last_layer) |
756 S_00A010_BASE_ARRAY(first_layer);
757 fmask_state[5] = 0;
758 fmask_state[6] = S_00A018_META_PIPE_ALIGNED(image->planes[0].surface.u.gfx9.cmask.pipe_aligned);
759 fmask_state[7] = 0;
760 } else if (fmask_state)
761 memset(fmask_state, 0, 8 * 4);
762 }
763
764 /**
765 * Build the sampler view descriptor for a texture (SI-GFX9)
766 */
767 static void
768 si_make_texture_descriptor(struct radv_device *device,
769 struct radv_image *image,
770 bool is_storage_image,
771 VkImageViewType view_type,
772 VkFormat vk_format,
773 const VkComponentMapping *mapping,
774 unsigned first_level, unsigned last_level,
775 unsigned first_layer, unsigned last_layer,
776 unsigned width, unsigned height, unsigned depth,
777 uint32_t *state,
778 uint32_t *fmask_state)
779 {
780 const struct vk_format_description *desc;
781 enum vk_swizzle swizzle[4];
782 int first_non_void;
783 unsigned num_format, data_format, type;
784
785 desc = vk_format_description(vk_format);
786
787 if (desc->colorspace == VK_FORMAT_COLORSPACE_ZS) {
788 const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
789 vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
790 } else {
791 vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
792 }
793
794 first_non_void = vk_format_get_first_non_void_channel(vk_format);
795
796 num_format = radv_translate_tex_numformat(vk_format, desc, first_non_void);
797 if (num_format == ~0) {
798 num_format = 0;
799 }
800
801 data_format = radv_translate_tex_dataformat(vk_format, desc, first_non_void);
802 if (data_format == ~0) {
803 data_format = 0;
804 }
805
806 /* S8 with either Z16 or Z32 HTILE need a special format. */
807 if (device->physical_device->rad_info.chip_class == GFX9 &&
808 vk_format == VK_FORMAT_S8_UINT &&
809 radv_image_is_tc_compat_htile(image)) {
810 if (image->vk_format == VK_FORMAT_D32_SFLOAT_S8_UINT)
811 data_format = V_008F14_IMG_DATA_FORMAT_S8_32;
812 else if (image->vk_format == VK_FORMAT_D16_UNORM_S8_UINT)
813 data_format = V_008F14_IMG_DATA_FORMAT_S8_16;
814 }
815 type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
816 is_storage_image, device->physical_device->rad_info.chip_class == GFX9);
817 if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
818 height = 1;
819 depth = image->info.array_size;
820 } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY ||
821 type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
822 if (view_type != VK_IMAGE_VIEW_TYPE_3D)
823 depth = image->info.array_size;
824 } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
825 depth = image->info.array_size / 6;
826
827 state[0] = 0;
828 state[1] = (S_008F14_DATA_FORMAT(data_format) |
829 S_008F14_NUM_FORMAT(num_format));
830 state[2] = (S_008F18_WIDTH(width - 1) |
831 S_008F18_HEIGHT(height - 1) |
832 S_008F18_PERF_MOD(4));
833 state[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
834 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
835 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
836 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
837 S_008F1C_BASE_LEVEL(image->info.samples > 1 ?
838 0 : first_level) |
839 S_008F1C_LAST_LEVEL(image->info.samples > 1 ?
840 util_logbase2(image->info.samples) :
841 last_level) |
842 S_008F1C_TYPE(type));
843 state[4] = 0;
844 state[5] = S_008F24_BASE_ARRAY(first_layer);
845 state[6] = 0;
846 state[7] = 0;
847
848 if (device->physical_device->rad_info.chip_class == GFX9) {
849 unsigned bc_swizzle = gfx9_border_color_swizzle(swizzle);
850
851 /* Depth is the last accessible layer on Gfx9.
852 * The hw doesn't need to know the total number of layers.
853 */
854 if (type == V_008F1C_SQ_RSRC_IMG_3D)
855 state[4] |= S_008F20_DEPTH(depth - 1);
856 else
857 state[4] |= S_008F20_DEPTH(last_layer);
858
859 state[4] |= S_008F20_BC_SWIZZLE(bc_swizzle);
860 state[5] |= S_008F24_MAX_MIP(image->info.samples > 1 ?
861 util_logbase2(image->info.samples) :
862 image->info.levels - 1);
863 } else {
864 state[3] |= S_008F1C_POW2_PAD(image->info.levels > 1);
865 state[4] |= S_008F20_DEPTH(depth - 1);
866 state[5] |= S_008F24_LAST_ARRAY(last_layer);
867 }
868 if (image->dcc_offset) {
869 state[6] = S_008F28_ALPHA_IS_ON_MSB(vi_alpha_is_on_msb(device, vk_format));
870 } else {
871 /* The last dword is unused by hw. The shader uses it to clear
872 * bits in the first dword of sampler state.
873 */
874 if (device->physical_device->rad_info.chip_class <= GFX7 && image->info.samples <= 1) {
875 if (first_level == last_level)
876 state[7] = C_008F30_MAX_ANISO_RATIO;
877 else
878 state[7] = 0xffffffff;
879 }
880 }
881
882 /* Initialize the sampler view for FMASK. */
883 if (radv_image_has_fmask(image)) {
884 uint32_t fmask_format, num_format;
885 uint64_t gpu_address = radv_buffer_get_va(image->bo);
886 uint64_t va;
887
888 assert(image->plane_count == 1);
889
890 va = gpu_address + image->offset + image->fmask_offset;
891
892 if (device->physical_device->rad_info.chip_class == GFX9) {
893 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK;
894 switch (image->info.samples) {
895 case 2:
896 num_format = V_008F14_IMG_FMASK_8_2_2;
897 break;
898 case 4:
899 num_format = V_008F14_IMG_FMASK_8_4_4;
900 break;
901 case 8:
902 num_format = V_008F14_IMG_FMASK_32_8_8;
903 break;
904 default:
905 unreachable("invalid nr_samples");
906 }
907 } else {
908 switch (image->info.samples) {
909 case 2:
910 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
911 break;
912 case 4:
913 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
914 break;
915 case 8:
916 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
917 break;
918 default:
919 assert(0);
920 fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
921 }
922 num_format = V_008F14_IMG_NUM_FORMAT_UINT;
923 }
924
925 fmask_state[0] = va >> 8;
926 fmask_state[0] |= image->planes[0].surface.fmask_tile_swizzle;
927 fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
928 S_008F14_DATA_FORMAT(fmask_format) |
929 S_008F14_NUM_FORMAT(num_format);
930 fmask_state[2] = S_008F18_WIDTH(width - 1) |
931 S_008F18_HEIGHT(height - 1);
932 fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
933 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
934 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
935 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
936 S_008F1C_TYPE(radv_tex_dim(image->type, view_type, image->info.array_size, 0, false, false));
937 fmask_state[4] = 0;
938 fmask_state[5] = S_008F24_BASE_ARRAY(first_layer);
939 fmask_state[6] = 0;
940 fmask_state[7] = 0;
941
942 if (device->physical_device->rad_info.chip_class == GFX9) {
943 fmask_state[3] |= S_008F1C_SW_MODE(image->planes[0].surface.u.gfx9.fmask.swizzle_mode);
944 fmask_state[4] |= S_008F20_DEPTH(last_layer) |
945 S_008F20_PITCH(image->planes[0].surface.u.gfx9.fmask.epitch);
946 fmask_state[5] |= S_008F24_META_PIPE_ALIGNED(image->planes[0].surface.u.gfx9.cmask.pipe_aligned) |
947 S_008F24_META_RB_ALIGNED(image->planes[0].surface.u.gfx9.cmask.rb_aligned);
948
949 if (radv_image_is_tc_compat_cmask(image)) {
950 va = gpu_address + image->offset + image->cmask_offset;
951
952 fmask_state[5] |= S_008F24_META_DATA_ADDRESS(va >> 40);
953 fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
954 fmask_state[7] |= va >> 8;
955 }
956 } else {
957 fmask_state[3] |= S_008F1C_TILING_INDEX(image->planes[0].surface.u.legacy.fmask.tiling_index);
958 fmask_state[4] |= S_008F20_DEPTH(depth - 1) |
959 S_008F20_PITCH(image->planes[0].surface.u.legacy.fmask.pitch_in_pixels - 1);
960 fmask_state[5] |= S_008F24_LAST_ARRAY(last_layer);
961
962 if (radv_image_is_tc_compat_cmask(image)) {
963 va = gpu_address + image->offset + image->cmask_offset;
964
965 fmask_state[6] |= S_008F28_COMPRESSION_EN(1);
966 fmask_state[7] |= va >> 8;
967 }
968 }
969 } else if (fmask_state)
970 memset(fmask_state, 0, 8 * 4);
971 }
972
973 static void
974 radv_make_texture_descriptor(struct radv_device *device,
975 struct radv_image *image,
976 bool is_storage_image,
977 VkImageViewType view_type,
978 VkFormat vk_format,
979 const VkComponentMapping *mapping,
980 unsigned first_level, unsigned last_level,
981 unsigned first_layer, unsigned last_layer,
982 unsigned width, unsigned height, unsigned depth,
983 uint32_t *state,
984 uint32_t *fmask_state)
985 {
986 if (device->physical_device->rad_info.chip_class >= GFX10) {
987 gfx10_make_texture_descriptor(device, image, is_storage_image,
988 view_type, vk_format, mapping,
989 first_level, last_level,
990 first_layer, last_layer,
991 width, height, depth,
992 state, fmask_state);
993 } else {
994 si_make_texture_descriptor(device, image, is_storage_image,
995 view_type, vk_format, mapping,
996 first_level, last_level,
997 first_layer, last_layer,
998 width, height, depth,
999 state, fmask_state);
1000 }
1001 }
1002
1003 static void
1004 radv_query_opaque_metadata(struct radv_device *device,
1005 struct radv_image *image,
1006 struct radeon_bo_metadata *md)
1007 {
1008 static const VkComponentMapping fixedmapping;
1009 uint32_t desc[8], i;
1010
1011 assert(image->plane_count == 1);
1012
1013 /* Metadata image format format version 1:
1014 * [0] = 1 (metadata format identifier)
1015 * [1] = (VENDOR_ID << 16) | PCI_ID
1016 * [2:9] = image descriptor for the whole resource
1017 * [2] is always 0, because the base address is cleared
1018 * [9] is the DCC offset bits [39:8] from the beginning of
1019 * the buffer
1020 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
1021 */
1022 md->metadata[0] = 1; /* metadata image format version 1 */
1023
1024 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
1025 md->metadata[1] = si_get_bo_metadata_word1(device);
1026
1027
1028 radv_make_texture_descriptor(device, image, false,
1029 (VkImageViewType)image->type, image->vk_format,
1030 &fixedmapping, 0, image->info.levels - 1, 0,
1031 image->info.array_size - 1,
1032 image->info.width, image->info.height,
1033 image->info.depth,
1034 desc, NULL);
1035
1036 si_set_mutable_tex_desc_fields(device, image, &image->planes[0].surface.u.legacy.level[0], 0, 0, 0,
1037 image->planes[0].surface.blk_w, false, false, false, desc);
1038
1039 /* Clear the base address and set the relative DCC offset. */
1040 desc[0] = 0;
1041 desc[1] &= C_008F14_BASE_ADDRESS_HI;
1042 desc[7] = image->dcc_offset >> 8;
1043
1044 /* Dwords [2:9] contain the image descriptor. */
1045 memcpy(&md->metadata[2], desc, sizeof(desc));
1046
1047 /* Dwords [10:..] contain the mipmap level offsets. */
1048 if (device->physical_device->rad_info.chip_class <= GFX8) {
1049 for (i = 0; i <= image->info.levels - 1; i++)
1050 md->metadata[10+i] = image->planes[0].surface.u.legacy.level[i].offset >> 8;
1051 md->size_metadata = (11 + image->info.levels - 1) * 4;
1052 } else
1053 md->size_metadata = 10 * 4;
1054 }
1055
1056 void
1057 radv_init_metadata(struct radv_device *device,
1058 struct radv_image *image,
1059 struct radeon_bo_metadata *metadata)
1060 {
1061 struct radeon_surf *surface = &image->planes[0].surface;
1062
1063 memset(metadata, 0, sizeof(*metadata));
1064
1065 if (device->physical_device->rad_info.chip_class >= GFX9) {
1066 metadata->u.gfx9.swizzle_mode = surface->u.gfx9.surf.swizzle_mode;
1067 } else {
1068 metadata->u.legacy.microtile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_1D ?
1069 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
1070 metadata->u.legacy.macrotile = surface->u.legacy.level[0].mode >= RADEON_SURF_MODE_2D ?
1071 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
1072 metadata->u.legacy.pipe_config = surface->u.legacy.pipe_config;
1073 metadata->u.legacy.bankw = surface->u.legacy.bankw;
1074 metadata->u.legacy.bankh = surface->u.legacy.bankh;
1075 metadata->u.legacy.tile_split = surface->u.legacy.tile_split;
1076 metadata->u.legacy.mtilea = surface->u.legacy.mtilea;
1077 metadata->u.legacy.num_banks = surface->u.legacy.num_banks;
1078 metadata->u.legacy.stride = surface->u.legacy.level[0].nblk_x * surface->bpe;
1079 metadata->u.legacy.scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
1080 }
1081 radv_query_opaque_metadata(device, image, metadata);
1082 }
1083
1084 void
1085 radv_image_override_offset_stride(struct radv_device *device,
1086 struct radv_image *image,
1087 uint64_t offset, uint32_t stride)
1088 {
1089 struct radeon_surf *surface = &image->planes[0].surface;
1090 unsigned bpe = vk_format_get_blocksizebits(image->vk_format) / 8;
1091
1092 if (device->physical_device->rad_info.chip_class >= GFX9) {
1093 if (stride) {
1094 surface->u.gfx9.surf_pitch = stride;
1095 surface->u.gfx9.surf_slice_size =
1096 (uint64_t)stride * surface->u.gfx9.surf_height * bpe;
1097 }
1098 surface->u.gfx9.surf_offset = offset;
1099 } else {
1100 surface->u.legacy.level[0].nblk_x = stride;
1101 surface->u.legacy.level[0].slice_size_dw =
1102 ((uint64_t)stride * surface->u.legacy.level[0].nblk_y * bpe) / 4;
1103
1104 if (offset) {
1105 for (unsigned i = 0; i < ARRAY_SIZE(surface->u.legacy.level); ++i)
1106 surface->u.legacy.level[i].offset += offset;
1107 }
1108
1109 }
1110 }
1111
1112 static void
1113 radv_image_alloc_fmask(struct radv_device *device,
1114 struct radv_image *image)
1115 {
1116 unsigned fmask_alignment = image->planes[0].surface.fmask_alignment;
1117
1118 image->fmask_offset = align64(image->size, fmask_alignment);
1119 image->size = image->fmask_offset + image->planes[0].surface.fmask_size;
1120 image->alignment = MAX2(image->alignment, fmask_alignment);
1121 }
1122
1123 static void
1124 radv_image_alloc_cmask(struct radv_device *device,
1125 struct radv_image *image)
1126 {
1127 unsigned cmask_alignment = image->planes[0].surface.cmask_alignment;
1128 unsigned cmask_size = image->planes[0].surface.cmask_size;
1129 uint32_t clear_value_size = 0;
1130
1131 if (!cmask_size)
1132 return;
1133
1134 assert(cmask_alignment);
1135
1136 image->cmask_offset = align64(image->size, cmask_alignment);
1137 /* + 8 for storing the clear values */
1138 if (!image->clear_value_offset) {
1139 image->clear_value_offset = image->cmask_offset + cmask_size;
1140 clear_value_size = 8;
1141 }
1142 image->size = image->cmask_offset + cmask_size + clear_value_size;
1143 image->alignment = MAX2(image->alignment, cmask_alignment);
1144 }
1145
1146 static void
1147 radv_image_alloc_dcc(struct radv_image *image)
1148 {
1149 assert(image->plane_count == 1);
1150
1151 image->dcc_offset = align64(image->size, image->planes[0].surface.dcc_alignment);
1152 /* + 24 for storing the clear values + fce pred + dcc pred for each mip */
1153 image->clear_value_offset = image->dcc_offset + image->planes[0].surface.dcc_size;
1154 image->fce_pred_offset = image->clear_value_offset + 8 * image->info.levels;
1155 image->dcc_pred_offset = image->clear_value_offset + 16 * image->info.levels;
1156 image->size = image->dcc_offset + image->planes[0].surface.dcc_size + 24 * image->info.levels;
1157 image->alignment = MAX2(image->alignment, image->planes[0].surface.dcc_alignment);
1158 }
1159
1160 static void
1161 radv_image_alloc_htile(struct radv_device *device, struct radv_image *image)
1162 {
1163 image->htile_offset = align64(image->size, image->planes[0].surface.htile_alignment);
1164
1165 /* + 8 for storing the clear values */
1166 image->clear_value_offset = image->htile_offset + image->planes[0].surface.htile_size;
1167 image->size = image->clear_value_offset + 8;
1168 if (radv_image_is_tc_compat_htile(image) &&
1169 device->physical_device->has_tc_compat_zrange_bug) {
1170 /* Metadata for the TC-compatible HTILE hardware bug which
1171 * have to be fixed by updating ZRANGE_PRECISION when doing
1172 * fast depth clears to 0.0f.
1173 */
1174 image->tc_compat_zrange_offset = image->size;
1175 image->size = image->tc_compat_zrange_offset + 4;
1176 }
1177 image->alignment = align64(image->alignment, image->planes[0].surface.htile_alignment);
1178 }
1179
1180 static inline bool
1181 radv_image_can_enable_dcc_or_cmask(struct radv_image *image)
1182 {
1183 if (image->info.samples <= 1 &&
1184 image->info.width * image->info.height <= 512 * 512) {
1185 /* Do not enable CMASK or DCC for small surfaces where the cost
1186 * of the eliminate pass can be higher than the benefit of fast
1187 * clear. RadeonSI does this, but the image threshold is
1188 * different.
1189 */
1190 return false;
1191 }
1192
1193 return image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT &&
1194 (image->exclusive || image->queue_family_mask == 1);
1195 }
1196
1197 static inline bool
1198 radv_image_can_enable_dcc(struct radv_device *device, struct radv_image *image)
1199 {
1200 if (!radv_image_can_enable_dcc_or_cmask(image) ||
1201 !radv_image_has_dcc(image))
1202 return false;
1203
1204 /* On GFX8, DCC layers can be interleaved and it's currently only
1205 * enabled if slice size is equal to the per slice fast clear size
1206 * because the driver assumes that portions of multiple layers are
1207 * contiguous during fast clears.
1208 */
1209 if (image->info.array_size > 1) {
1210 const struct legacy_surf_level *surf_level =
1211 &image->planes[0].surface.u.legacy.level[0];
1212
1213 assert(device->physical_device->rad_info.chip_class == GFX8);
1214
1215 if (image->planes[0].surface.dcc_slice_size != surf_level->dcc_fast_clear_size)
1216 return false;
1217 }
1218
1219 return true;
1220 }
1221
1222 static inline bool
1223 radv_image_can_enable_cmask(struct radv_image *image)
1224 {
1225 if (image->planes[0].surface.bpe > 8 && image->info.samples == 1) {
1226 /* Do not enable CMASK for non-MSAA images (fast color clear)
1227 * because 128 bit formats are not supported, but FMASK might
1228 * still be used.
1229 */
1230 return false;
1231 }
1232
1233 return radv_image_can_enable_dcc_or_cmask(image) &&
1234 image->info.levels == 1 &&
1235 image->info.depth == 1 &&
1236 !image->planes[0].surface.is_linear;
1237 }
1238
1239 static inline bool
1240 radv_image_can_enable_fmask(struct radv_image *image)
1241 {
1242 return image->info.samples > 1 && vk_format_is_color(image->vk_format);
1243 }
1244
1245 static inline bool
1246 radv_image_can_enable_htile(struct radv_image *image)
1247 {
1248 return radv_image_has_htile(image) &&
1249 image->info.levels == 1 &&
1250 image->info.width * image->info.height >= 8 * 8;
1251 }
1252
1253 static void radv_image_disable_dcc(struct radv_image *image)
1254 {
1255 for (unsigned i = 0; i < image->plane_count; ++i)
1256 image->planes[i].surface.dcc_size = 0;
1257 }
1258
1259 static void radv_image_disable_htile(struct radv_image *image)
1260 {
1261 for (unsigned i = 0; i < image->plane_count; ++i)
1262 image->planes[i].surface.htile_size = 0;
1263 }
1264
1265 VkResult
1266 radv_image_create(VkDevice _device,
1267 const struct radv_image_create_info *create_info,
1268 const VkAllocationCallbacks* alloc,
1269 VkImage *pImage)
1270 {
1271 RADV_FROM_HANDLE(radv_device, device, _device);
1272 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
1273 struct radv_image *image = NULL;
1274 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
1275
1276 const unsigned plane_count = vk_format_get_plane_count(pCreateInfo->format);
1277 const size_t image_struct_size = sizeof(*image) + sizeof(struct radv_image_plane) * plane_count;
1278
1279 radv_assert(pCreateInfo->mipLevels > 0);
1280 radv_assert(pCreateInfo->arrayLayers > 0);
1281 radv_assert(pCreateInfo->samples > 0);
1282 radv_assert(pCreateInfo->extent.width > 0);
1283 radv_assert(pCreateInfo->extent.height > 0);
1284 radv_assert(pCreateInfo->extent.depth > 0);
1285
1286 image = vk_zalloc2(&device->alloc, alloc, image_struct_size, 8,
1287 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1288 if (!image)
1289 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1290
1291 image->type = pCreateInfo->imageType;
1292 image->info.width = pCreateInfo->extent.width;
1293 image->info.height = pCreateInfo->extent.height;
1294 image->info.depth = pCreateInfo->extent.depth;
1295 image->info.samples = pCreateInfo->samples;
1296 image->info.storage_samples = pCreateInfo->samples;
1297 image->info.array_size = pCreateInfo->arrayLayers;
1298 image->info.levels = pCreateInfo->mipLevels;
1299 image->info.num_channels = vk_format_get_nr_components(pCreateInfo->format);
1300
1301 image->vk_format = pCreateInfo->format;
1302 image->tiling = pCreateInfo->tiling;
1303 image->usage = pCreateInfo->usage;
1304 image->flags = pCreateInfo->flags;
1305
1306 image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
1307 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
1308 for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
1309 if (pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_EXTERNAL ||
1310 pCreateInfo->pQueueFamilyIndices[i] == VK_QUEUE_FAMILY_FOREIGN_EXT)
1311 image->queue_family_mask |= (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
1312 else
1313 image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i];
1314 }
1315
1316 image->shareable = vk_find_struct_const(pCreateInfo->pNext,
1317 EXTERNAL_MEMORY_IMAGE_CREATE_INFO) != NULL;
1318 if (!vk_format_is_depth_or_stencil(pCreateInfo->format) &&
1319 !radv_surface_has_scanout(device, create_info) && !image->shareable) {
1320 image->info.surf_index = &device->image_mrt_offset_counter;
1321 }
1322
1323 image->plane_count = plane_count;
1324 image->size = 0;
1325 image->alignment = 1;
1326 for (unsigned plane = 0; plane < plane_count; ++plane) {
1327 struct ac_surf_info info = image->info;
1328 radv_init_surface(device, image, &image->planes[plane].surface, plane, create_info);
1329
1330 if (plane) {
1331 const struct vk_format_description *desc = vk_format_description(pCreateInfo->format);
1332 assert(info.width % desc->width_divisor == 0);
1333 assert(info.height % desc->height_divisor == 0);
1334
1335 info.width /= desc->width_divisor;
1336 info.height /= desc->height_divisor;
1337 }
1338
1339 device->ws->surface_init(device->ws, &info, &image->planes[plane].surface);
1340
1341 image->planes[plane].offset = align(image->size, image->planes[plane].surface.surf_alignment);
1342 image->size = image->planes[plane].offset + image->planes[plane].surface.surf_size;
1343 image->alignment = image->planes[plane].surface.surf_alignment;
1344
1345 image->planes[plane].format = vk_format_get_plane_format(image->vk_format, plane);
1346 }
1347
1348 if (!create_info->no_metadata_planes) {
1349 /* Try to enable DCC first. */
1350 if (radv_image_can_enable_dcc(device, image)) {
1351 radv_image_alloc_dcc(image);
1352 if (image->info.samples > 1) {
1353 /* CMASK should be enabled because DCC fast
1354 * clear with MSAA needs it.
1355 */
1356 assert(radv_image_can_enable_cmask(image));
1357 radv_image_alloc_cmask(device, image);
1358 }
1359 } else {
1360 /* When DCC cannot be enabled, try CMASK. */
1361 radv_image_disable_dcc(image);
1362 if (radv_image_can_enable_cmask(image)) {
1363 radv_image_alloc_cmask(device, image);
1364 }
1365 }
1366
1367 /* Try to enable FMASK for multisampled images. */
1368 if (radv_image_can_enable_fmask(image)) {
1369 radv_image_alloc_fmask(device, image);
1370
1371 if (radv_use_tc_compat_cmask_for_image(device, image))
1372 image->tc_compatible_cmask = true;
1373 } else {
1374 /* Otherwise, try to enable HTILE for depth surfaces. */
1375 if (radv_image_can_enable_htile(image) &&
1376 !(device->instance->debug_flags & RADV_DEBUG_NO_HIZ)) {
1377 image->tc_compatible_htile = image->planes[0].surface.flags & RADEON_SURF_TC_COMPATIBLE_HTILE;
1378 radv_image_alloc_htile(device, image);
1379 } else {
1380 radv_image_disable_htile(image);
1381 }
1382 }
1383 } else {
1384 radv_image_disable_dcc(image);
1385 radv_image_disable_htile(image);
1386 }
1387
1388 if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
1389 image->alignment = MAX2(image->alignment, 4096);
1390 image->size = align64(image->size, image->alignment);
1391 image->offset = 0;
1392
1393 image->bo = device->ws->buffer_create(device->ws, image->size, image->alignment,
1394 0, RADEON_FLAG_VIRTUAL, RADV_BO_PRIORITY_VIRTUAL);
1395 if (!image->bo) {
1396 vk_free2(&device->alloc, alloc, image);
1397 return vk_error(device->instance, VK_ERROR_OUT_OF_DEVICE_MEMORY);
1398 }
1399 }
1400
1401 *pImage = radv_image_to_handle(image);
1402
1403 return VK_SUCCESS;
1404 }
1405
1406 static void
1407 radv_image_view_make_descriptor(struct radv_image_view *iview,
1408 struct radv_device *device,
1409 VkFormat vk_format,
1410 const VkComponentMapping *components,
1411 bool is_storage_image, bool disable_compression,
1412 unsigned plane_id, unsigned descriptor_plane_id)
1413 {
1414 struct radv_image *image = iview->image;
1415 struct radv_image_plane *plane = &image->planes[plane_id];
1416 const struct vk_format_description *format_desc = vk_format_description(image->vk_format);
1417 bool is_stencil = iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT;
1418 uint32_t blk_w;
1419 union radv_descriptor *descriptor;
1420 uint32_t hw_level = 0;
1421
1422 if (is_storage_image) {
1423 descriptor = &iview->storage_descriptor;
1424 } else {
1425 descriptor = &iview->descriptor;
1426 }
1427
1428 assert(vk_format_get_plane_count(vk_format) == 1);
1429 assert(plane->surface.blk_w % vk_format_get_blockwidth(plane->format) == 0);
1430 blk_w = plane->surface.blk_w / vk_format_get_blockwidth(plane->format) * vk_format_get_blockwidth(vk_format);
1431
1432 if (device->physical_device->rad_info.chip_class >= GFX9)
1433 hw_level = iview->base_mip;
1434 radv_make_texture_descriptor(device, image, is_storage_image,
1435 iview->type,
1436 vk_format,
1437 components,
1438 hw_level, hw_level + iview->level_count - 1,
1439 iview->base_layer,
1440 iview->base_layer + iview->layer_count - 1,
1441 iview->extent.width / (plane_id ? format_desc->width_divisor : 1),
1442 iview->extent.height / (plane_id ? format_desc->height_divisor : 1),
1443 iview->extent.depth,
1444 descriptor->plane_descriptors[descriptor_plane_id],
1445 descriptor_plane_id ? NULL : descriptor->fmask_descriptor);
1446
1447 const struct legacy_surf_level *base_level_info = NULL;
1448 if (device->physical_device->rad_info.chip_class <= GFX9) {
1449 if (is_stencil)
1450 base_level_info = &plane->surface.u.legacy.stencil_level[iview->base_mip];
1451 else
1452 base_level_info = &plane->surface.u.legacy.level[iview->base_mip];
1453 }
1454
1455 if (is_storage_image && radv_image_has_dcc(iview->image) &&
1456 !radv_support_storage_dcc(device->physical_device))
1457 disable_compression = true;
1458 si_set_mutable_tex_desc_fields(device, image,
1459 base_level_info,
1460 plane_id,
1461 iview->base_mip,
1462 iview->base_mip,
1463 blk_w, is_stencil, is_storage_image,
1464 disable_compression,
1465 descriptor->plane_descriptors[descriptor_plane_id]);
1466 }
1467
1468 static unsigned
1469 radv_plane_from_aspect(VkImageAspectFlags mask)
1470 {
1471 switch(mask) {
1472 case VK_IMAGE_ASPECT_PLANE_1_BIT:
1473 return 1;
1474 case VK_IMAGE_ASPECT_PLANE_2_BIT:
1475 return 2;
1476 default:
1477 return 0;
1478 }
1479 }
1480
1481 VkFormat
1482 radv_get_aspect_format(struct radv_image *image, VkImageAspectFlags mask)
1483 {
1484 switch(mask) {
1485 case VK_IMAGE_ASPECT_PLANE_0_BIT:
1486 return image->planes[0].format;
1487 case VK_IMAGE_ASPECT_PLANE_1_BIT:
1488 return image->planes[1].format;
1489 case VK_IMAGE_ASPECT_PLANE_2_BIT:
1490 return image->planes[2].format;
1491 case VK_IMAGE_ASPECT_STENCIL_BIT:
1492 return vk_format_stencil_only(image->vk_format);
1493 case VK_IMAGE_ASPECT_DEPTH_BIT:
1494 return vk_format_depth_only(image->vk_format);
1495 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
1496 return vk_format_depth_only(image->vk_format);
1497 default:
1498 return image->vk_format;
1499 }
1500 }
1501
1502 void
1503 radv_image_view_init(struct radv_image_view *iview,
1504 struct radv_device *device,
1505 const VkImageViewCreateInfo* pCreateInfo,
1506 const struct radv_image_view_extra_create_info* extra_create_info)
1507 {
1508 RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
1509 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
1510
1511 switch (image->type) {
1512 case VK_IMAGE_TYPE_1D:
1513 case VK_IMAGE_TYPE_2D:
1514 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= image->info.array_size);
1515 break;
1516 case VK_IMAGE_TYPE_3D:
1517 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1
1518 <= radv_minify(image->info.depth, range->baseMipLevel));
1519 break;
1520 default:
1521 unreachable("bad VkImageType");
1522 }
1523 iview->image = image;
1524 iview->bo = image->bo;
1525 iview->type = pCreateInfo->viewType;
1526 iview->plane_id = radv_plane_from_aspect(pCreateInfo->subresourceRange.aspectMask);
1527 iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
1528 iview->multiple_planes = vk_format_get_plane_count(image->vk_format) > 1 && iview->aspect_mask == VK_IMAGE_ASPECT_COLOR_BIT;
1529 iview->vk_format = pCreateInfo->format;
1530
1531 if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
1532 iview->vk_format = vk_format_stencil_only(iview->vk_format);
1533 } else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
1534 iview->vk_format = vk_format_depth_only(iview->vk_format);
1535 }
1536
1537 if (device->physical_device->rad_info.chip_class >= GFX9) {
1538 iview->extent = (VkExtent3D) {
1539 .width = image->info.width,
1540 .height = image->info.height,
1541 .depth = image->info.depth,
1542 };
1543 } else {
1544 iview->extent = (VkExtent3D) {
1545 .width = radv_minify(image->info.width , range->baseMipLevel),
1546 .height = radv_minify(image->info.height, range->baseMipLevel),
1547 .depth = radv_minify(image->info.depth , range->baseMipLevel),
1548 };
1549 }
1550
1551 if (iview->vk_format != image->planes[iview->plane_id].format) {
1552 unsigned view_bw = vk_format_get_blockwidth(iview->vk_format);
1553 unsigned view_bh = vk_format_get_blockheight(iview->vk_format);
1554 unsigned img_bw = vk_format_get_blockwidth(image->vk_format);
1555 unsigned img_bh = vk_format_get_blockheight(image->vk_format);
1556
1557 iview->extent.width = round_up_u32(iview->extent.width * view_bw, img_bw);
1558 iview->extent.height = round_up_u32(iview->extent.height * view_bh, img_bh);
1559
1560 /* Comment ported from amdvlk -
1561 * If we have the following image:
1562 * Uncompressed pixels Compressed block sizes (4x4)
1563 * mip0: 22 x 22 6 x 6
1564 * mip1: 11 x 11 3 x 3
1565 * mip2: 5 x 5 2 x 2
1566 * mip3: 2 x 2 1 x 1
1567 * mip4: 1 x 1 1 x 1
1568 *
1569 * On GFX9 the descriptor is always programmed with the WIDTH and HEIGHT of the base level and the HW is
1570 * calculating the degradation of the block sizes down the mip-chain as follows (straight-up
1571 * divide-by-two integer math):
1572 * mip0: 6x6
1573 * mip1: 3x3
1574 * mip2: 1x1
1575 * mip3: 1x1
1576 *
1577 * This means that mip2 will be missing texels.
1578 *
1579 * Fix this by calculating the base mip's width and height, then convert that, and round it
1580 * back up to get the level 0 size.
1581 * Clamp the converted size between the original values, and next power of two, which
1582 * means we don't oversize the image.
1583 */
1584 if (device->physical_device->rad_info.chip_class >= GFX9 &&
1585 vk_format_is_compressed(image->vk_format) &&
1586 !vk_format_is_compressed(iview->vk_format)) {
1587 unsigned lvl_width = radv_minify(image->info.width , range->baseMipLevel);
1588 unsigned lvl_height = radv_minify(image->info.height, range->baseMipLevel);
1589
1590 lvl_width = round_up_u32(lvl_width * view_bw, img_bw);
1591 lvl_height = round_up_u32(lvl_height * view_bh, img_bh);
1592
1593 lvl_width <<= range->baseMipLevel;
1594 lvl_height <<= range->baseMipLevel;
1595
1596 iview->extent.width = CLAMP(lvl_width, iview->extent.width, iview->image->planes[0].surface.u.gfx9.surf_pitch);
1597 iview->extent.height = CLAMP(lvl_height, iview->extent.height, iview->image->planes[0].surface.u.gfx9.surf_height);
1598 }
1599 }
1600
1601 iview->base_layer = range->baseArrayLayer;
1602 iview->layer_count = radv_get_layerCount(image, range);
1603 iview->base_mip = range->baseMipLevel;
1604 iview->level_count = radv_get_levelCount(image, range);
1605
1606 bool disable_compression = extra_create_info ? extra_create_info->disable_compression: false;
1607 for (unsigned i = 0; i < (iview->multiple_planes ? vk_format_get_plane_count(image->vk_format) : 1); ++i) {
1608 VkFormat format = vk_format_get_plane_format(iview->vk_format, i);
1609 radv_image_view_make_descriptor(iview, device, format,
1610 &pCreateInfo->components,
1611 false, disable_compression,
1612 iview->plane_id + i, i);
1613 radv_image_view_make_descriptor(iview, device,
1614 format, &pCreateInfo->components,
1615 true, disable_compression,
1616 iview->plane_id + i, i);
1617 }
1618 }
1619
1620 bool radv_layout_has_htile(const struct radv_image *image,
1621 VkImageLayout layout,
1622 bool in_render_loop,
1623 unsigned queue_mask)
1624 {
1625 if (radv_image_is_tc_compat_htile(image))
1626 return layout != VK_IMAGE_LAYOUT_GENERAL;
1627
1628 return radv_image_has_htile(image) &&
1629 (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
1630 (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
1631 queue_mask == (1u << RADV_QUEUE_GENERAL)));
1632 }
1633
1634 bool radv_layout_is_htile_compressed(const struct radv_image *image,
1635 VkImageLayout layout,
1636 bool in_render_loop,
1637 unsigned queue_mask)
1638 {
1639 if (radv_image_is_tc_compat_htile(image))
1640 return layout != VK_IMAGE_LAYOUT_GENERAL;
1641
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)));
1646 }
1647
1648 bool radv_layout_can_fast_clear(const struct radv_image *image,
1649 VkImageLayout layout,
1650 bool in_render_loop,
1651 unsigned queue_mask)
1652 {
1653 return layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
1654 }
1655
1656 bool radv_layout_dcc_compressed(const struct radv_device *device,
1657 const struct radv_image *image,
1658 VkImageLayout layout,
1659 bool in_render_loop,
1660 unsigned queue_mask)
1661 {
1662 /* Don't compress compute transfer dst, as image stores are not supported. */
1663 if (layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL &&
1664 (queue_mask & (1u << RADV_QUEUE_COMPUTE)) &&
1665 !radv_support_storage_dcc(device->physical_device))
1666 return false;
1667
1668 return radv_image_has_dcc(image) && layout != VK_IMAGE_LAYOUT_GENERAL;
1669 }
1670
1671
1672 unsigned radv_image_queue_family_mask(const struct radv_image *image, uint32_t family, uint32_t queue_family)
1673 {
1674 if (!image->exclusive)
1675 return image->queue_family_mask;
1676 if (family == VK_QUEUE_FAMILY_EXTERNAL ||
1677 family == VK_QUEUE_FAMILY_FOREIGN_EXT)
1678 return (1u << RADV_MAX_QUEUE_FAMILIES) - 1u;
1679 if (family == VK_QUEUE_FAMILY_IGNORED)
1680 return 1u << queue_family;
1681 return 1u << family;
1682 }
1683
1684 VkResult
1685 radv_CreateImage(VkDevice device,
1686 const VkImageCreateInfo *pCreateInfo,
1687 const VkAllocationCallbacks *pAllocator,
1688 VkImage *pImage)
1689 {
1690 #ifdef ANDROID
1691 const VkNativeBufferANDROID *gralloc_info =
1692 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
1693
1694 if (gralloc_info)
1695 return radv_image_from_gralloc(device, pCreateInfo, gralloc_info,
1696 pAllocator, pImage);
1697 #endif
1698
1699 const struct wsi_image_create_info *wsi_info =
1700 vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
1701 bool scanout = wsi_info && wsi_info->scanout;
1702
1703 return radv_image_create(device,
1704 &(struct radv_image_create_info) {
1705 .vk_info = pCreateInfo,
1706 .scanout = scanout,
1707 },
1708 pAllocator,
1709 pImage);
1710 }
1711
1712 void
1713 radv_DestroyImage(VkDevice _device, VkImage _image,
1714 const VkAllocationCallbacks *pAllocator)
1715 {
1716 RADV_FROM_HANDLE(radv_device, device, _device);
1717 RADV_FROM_HANDLE(radv_image, image, _image);
1718
1719 if (!image)
1720 return;
1721
1722 if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
1723 device->ws->buffer_destroy(image->bo);
1724
1725 if (image->owned_memory != VK_NULL_HANDLE)
1726 radv_FreeMemory(_device, image->owned_memory, pAllocator);
1727
1728 vk_free2(&device->alloc, pAllocator, image);
1729 }
1730
1731 void radv_GetImageSubresourceLayout(
1732 VkDevice _device,
1733 VkImage _image,
1734 const VkImageSubresource* pSubresource,
1735 VkSubresourceLayout* pLayout)
1736 {
1737 RADV_FROM_HANDLE(radv_image, image, _image);
1738 RADV_FROM_HANDLE(radv_device, device, _device);
1739 int level = pSubresource->mipLevel;
1740 int layer = pSubresource->arrayLayer;
1741
1742 unsigned plane_id = radv_plane_from_aspect(pSubresource->aspectMask);
1743
1744 struct radv_image_plane *plane = &image->planes[plane_id];
1745 struct radeon_surf *surface = &plane->surface;
1746
1747 if (device->physical_device->rad_info.chip_class >= GFX9) {
1748 pLayout->offset = plane->offset + surface->u.gfx9.offset[level] + surface->u.gfx9.surf_slice_size * layer;
1749 if (image->vk_format == VK_FORMAT_R32G32B32_UINT ||
1750 image->vk_format == VK_FORMAT_R32G32B32_SINT ||
1751 image->vk_format == VK_FORMAT_R32G32B32_SFLOAT) {
1752 /* Adjust the number of bytes between each row because
1753 * the pitch is actually the number of components per
1754 * row.
1755 */
1756 pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe / 3;
1757 } else {
1758 assert(util_is_power_of_two_nonzero(surface->bpe));
1759 pLayout->rowPitch = surface->u.gfx9.surf_pitch * surface->bpe;
1760 }
1761
1762 pLayout->arrayPitch = surface->u.gfx9.surf_slice_size;
1763 pLayout->depthPitch = surface->u.gfx9.surf_slice_size;
1764 pLayout->size = surface->u.gfx9.surf_slice_size;
1765 if (image->type == VK_IMAGE_TYPE_3D)
1766 pLayout->size *= u_minify(image->info.depth, level);
1767 } else {
1768 pLayout->offset = plane->offset + surface->u.legacy.level[level].offset + (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4 * layer;
1769 pLayout->rowPitch = surface->u.legacy.level[level].nblk_x * surface->bpe;
1770 pLayout->arrayPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1771 pLayout->depthPitch = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1772 pLayout->size = (uint64_t)surface->u.legacy.level[level].slice_size_dw * 4;
1773 if (image->type == VK_IMAGE_TYPE_3D)
1774 pLayout->size *= u_minify(image->info.depth, level);
1775 }
1776 }
1777
1778
1779 VkResult
1780 radv_CreateImageView(VkDevice _device,
1781 const VkImageViewCreateInfo *pCreateInfo,
1782 const VkAllocationCallbacks *pAllocator,
1783 VkImageView *pView)
1784 {
1785 RADV_FROM_HANDLE(radv_device, device, _device);
1786 struct radv_image_view *view;
1787
1788 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
1789 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1790 if (view == NULL)
1791 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1792
1793 radv_image_view_init(view, device, pCreateInfo, NULL);
1794
1795 *pView = radv_image_view_to_handle(view);
1796
1797 return VK_SUCCESS;
1798 }
1799
1800 void
1801 radv_DestroyImageView(VkDevice _device, VkImageView _iview,
1802 const VkAllocationCallbacks *pAllocator)
1803 {
1804 RADV_FROM_HANDLE(radv_device, device, _device);
1805 RADV_FROM_HANDLE(radv_image_view, iview, _iview);
1806
1807 if (!iview)
1808 return;
1809 vk_free2(&device->alloc, pAllocator, iview);
1810 }
1811
1812 void radv_buffer_view_init(struct radv_buffer_view *view,
1813 struct radv_device *device,
1814 const VkBufferViewCreateInfo* pCreateInfo)
1815 {
1816 RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
1817
1818 view->bo = buffer->bo;
1819 view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
1820 buffer->size - pCreateInfo->offset : pCreateInfo->range;
1821 view->vk_format = pCreateInfo->format;
1822
1823 radv_make_buffer_descriptor(device, buffer, view->vk_format,
1824 pCreateInfo->offset, view->range, view->state);
1825 }
1826
1827 VkResult
1828 radv_CreateBufferView(VkDevice _device,
1829 const VkBufferViewCreateInfo *pCreateInfo,
1830 const VkAllocationCallbacks *pAllocator,
1831 VkBufferView *pView)
1832 {
1833 RADV_FROM_HANDLE(radv_device, device, _device);
1834 struct radv_buffer_view *view;
1835
1836 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
1837 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1838 if (!view)
1839 return vk_error(device->instance, VK_ERROR_OUT_OF_HOST_MEMORY);
1840
1841 radv_buffer_view_init(view, device, pCreateInfo);
1842
1843 *pView = radv_buffer_view_to_handle(view);
1844
1845 return VK_SUCCESS;
1846 }
1847
1848 void
1849 radv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
1850 const VkAllocationCallbacks *pAllocator)
1851 {
1852 RADV_FROM_HANDLE(radv_device, device, _device);
1853 RADV_FROM_HANDLE(radv_buffer_view, view, bufferView);
1854
1855 if (!view)
1856 return;
1857
1858 vk_free2(&device->alloc, pAllocator, view);
1859 }