radv: move some image info into a separate struct.
[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_private.h"
29 #include "vk_format.h"
30 #include "radv_radeon_winsys.h"
31 #include "sid.h"
32 #include "util/debug.h"
33 static unsigned
34 radv_choose_tiling(struct radv_device *Device,
35 const struct radv_image_create_info *create_info)
36 {
37 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
38
39 if (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) {
40 assert(pCreateInfo->samples <= 1);
41 return RADEON_SURF_MODE_LINEAR_ALIGNED;
42 }
43
44 /* Textures with a very small height are recommended to be linear. */
45 if (pCreateInfo->imageType == VK_IMAGE_TYPE_1D ||
46 /* Only very thin and long 2D textures should benefit from
47 * linear_aligned. */
48 (pCreateInfo->extent.width > 8 && pCreateInfo->extent.height <= 2))
49 return RADEON_SURF_MODE_LINEAR_ALIGNED;
50
51 /* MSAA resources must be 2D tiled. */
52 if (pCreateInfo->samples > 1)
53 return RADEON_SURF_MODE_2D;
54
55 return RADEON_SURF_MODE_2D;
56 }
57 static int
58 radv_init_surface(struct radv_device *device,
59 struct radeon_surf *surface,
60 const struct radv_image_create_info *create_info)
61 {
62 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
63 unsigned array_mode = radv_choose_tiling(device, create_info);
64 const struct vk_format_description *desc =
65 vk_format_description(pCreateInfo->format);
66 bool is_depth, is_stencil, blendable;
67
68 is_depth = vk_format_has_depth(desc);
69 is_stencil = vk_format_has_stencil(desc);
70 surface->npix_x = pCreateInfo->extent.width;
71 surface->npix_y = pCreateInfo->extent.height;
72 surface->npix_z = pCreateInfo->extent.depth;
73
74 surface->blk_w = vk_format_get_blockwidth(pCreateInfo->format);
75 surface->blk_h = vk_format_get_blockheight(pCreateInfo->format);
76 surface->blk_d = 1;
77 surface->array_size = pCreateInfo->arrayLayers;
78 surface->last_level = pCreateInfo->mipLevels - 1;
79
80 surface->bpe = vk_format_get_blocksize(pCreateInfo->format);
81 /* align byte per element on dword */
82 if (surface->bpe == 3) {
83 surface->bpe = 4;
84 }
85 surface->nsamples = pCreateInfo->samples ? pCreateInfo->samples : 1;
86 surface->flags = RADEON_SURF_SET(array_mode, MODE);
87
88 switch (pCreateInfo->imageType){
89 case VK_IMAGE_TYPE_1D:
90 if (pCreateInfo->arrayLayers > 1)
91 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D_ARRAY, TYPE);
92 else
93 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_1D, TYPE);
94 break;
95 case VK_IMAGE_TYPE_2D:
96 if (pCreateInfo->arrayLayers > 1)
97 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D_ARRAY, TYPE);
98 else
99 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_2D, TYPE);
100 break;
101 case VK_IMAGE_TYPE_3D:
102 surface->flags |= RADEON_SURF_SET(RADEON_SURF_TYPE_3D, TYPE);
103 break;
104 default:
105 unreachable("unhandled image type");
106 }
107
108 if (is_depth) {
109 surface->flags |= RADEON_SURF_ZBUFFER;
110 }
111
112 if (is_stencil)
113 surface->flags |= RADEON_SURF_SBUFFER |
114 RADEON_SURF_HAS_SBUFFER_MIPTREE;
115
116 surface->flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
117
118 if ((pCreateInfo->usage & (VK_IMAGE_USAGE_TRANSFER_SRC_BIT |
119 VK_IMAGE_USAGE_STORAGE_BIT)) ||
120 (pCreateInfo->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) ||
121 (pCreateInfo->tiling == VK_IMAGE_TILING_LINEAR) ||
122 device->physical_device->rad_info.chip_class < VI ||
123 create_info->scanout || (device->debug_flags & RADV_DEBUG_NO_DCC) ||
124 !radv_is_colorbuffer_format_supported(pCreateInfo->format, &blendable))
125 surface->flags |= RADEON_SURF_DISABLE_DCC;
126 if (create_info->scanout)
127 surface->flags |= RADEON_SURF_SCANOUT;
128 return 0;
129 }
130 #define ATI_VENDOR_ID 0x1002
131 static uint32_t si_get_bo_metadata_word1(struct radv_device *device)
132 {
133 return (ATI_VENDOR_ID << 16) | device->physical_device->rad_info.pci_id;
134 }
135
136 static inline unsigned
137 si_tile_mode_index(const struct radv_image *image, unsigned level, bool stencil)
138 {
139 if (stencil)
140 return image->surface.stencil_tiling_index[level];
141 else
142 return image->surface.tiling_index[level];
143 }
144
145 static unsigned radv_map_swizzle(unsigned swizzle)
146 {
147 switch (swizzle) {
148 case VK_SWIZZLE_Y:
149 return V_008F0C_SQ_SEL_Y;
150 case VK_SWIZZLE_Z:
151 return V_008F0C_SQ_SEL_Z;
152 case VK_SWIZZLE_W:
153 return V_008F0C_SQ_SEL_W;
154 case VK_SWIZZLE_0:
155 return V_008F0C_SQ_SEL_0;
156 case VK_SWIZZLE_1:
157 return V_008F0C_SQ_SEL_1;
158 default: /* VK_SWIZZLE_X */
159 return V_008F0C_SQ_SEL_X;
160 }
161 }
162
163 static void
164 radv_make_buffer_descriptor(struct radv_device *device,
165 struct radv_buffer *buffer,
166 VkFormat vk_format,
167 unsigned offset,
168 unsigned range,
169 uint32_t *state)
170 {
171 const struct vk_format_description *desc;
172 unsigned stride;
173 uint64_t gpu_address = device->ws->buffer_get_va(buffer->bo);
174 uint64_t va = gpu_address + buffer->offset;
175 unsigned num_format, data_format;
176 int first_non_void;
177 desc = vk_format_description(vk_format);
178 first_non_void = vk_format_get_first_non_void_channel(vk_format);
179 stride = desc->block.bits / 8;
180
181 num_format = radv_translate_buffer_numformat(desc, first_non_void);
182 data_format = radv_translate_buffer_dataformat(desc, first_non_void);
183
184 va += offset;
185 state[0] = va;
186 state[1] = S_008F04_BASE_ADDRESS_HI(va >> 32) |
187 S_008F04_STRIDE(stride);
188 state[2] = range;
189 state[3] = S_008F0C_DST_SEL_X(radv_map_swizzle(desc->swizzle[0])) |
190 S_008F0C_DST_SEL_Y(radv_map_swizzle(desc->swizzle[1])) |
191 S_008F0C_DST_SEL_Z(radv_map_swizzle(desc->swizzle[2])) |
192 S_008F0C_DST_SEL_W(radv_map_swizzle(desc->swizzle[3])) |
193 S_008F0C_NUM_FORMAT(num_format) |
194 S_008F0C_DATA_FORMAT(data_format);
195 }
196
197 static void
198 si_set_mutable_tex_desc_fields(struct radv_device *device,
199 struct radv_image *image,
200 const struct radeon_surf_level *base_level_info,
201 unsigned base_level, unsigned first_level,
202 unsigned block_width, bool is_stencil,
203 uint32_t *state)
204 {
205 uint64_t gpu_address = device->ws->buffer_get_va(image->bo) + image->offset;
206 uint64_t va = gpu_address + base_level_info->offset;
207 unsigned pitch = base_level_info->nblk_x * block_width;
208
209 state[1] &= C_008F14_BASE_ADDRESS_HI;
210 state[3] &= C_008F1C_TILING_INDEX;
211 state[4] &= C_008F20_PITCH_GFX6;
212 state[6] &= C_008F28_COMPRESSION_EN;
213
214 assert(!(va & 255));
215
216 state[0] = va >> 8;
217 state[1] |= S_008F14_BASE_ADDRESS_HI(va >> 40);
218 state[3] |= S_008F1C_TILING_INDEX(si_tile_mode_index(image, base_level,
219 is_stencil));
220 state[4] |= S_008F20_PITCH_GFX6(pitch - 1);
221
222 if (image->surface.dcc_size && image->surface.level[first_level].dcc_enabled) {
223 state[6] |= S_008F28_COMPRESSION_EN(1);
224 state[7] = (gpu_address +
225 image->dcc_offset +
226 base_level_info->dcc_offset) >> 8;
227 }
228 }
229
230 static unsigned radv_tex_dim(VkImageType image_type, VkImageViewType view_type,
231 unsigned nr_layers, unsigned nr_samples, bool is_storage_image)
232 {
233 if (view_type == VK_IMAGE_VIEW_TYPE_CUBE || view_type == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY)
234 return is_storage_image ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_CUBE;
235 switch (image_type) {
236 case VK_IMAGE_TYPE_1D:
237 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_1D_ARRAY : V_008F1C_SQ_RSRC_IMG_1D;
238 case VK_IMAGE_TYPE_2D:
239 if (nr_samples > 1)
240 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY : V_008F1C_SQ_RSRC_IMG_2D_MSAA;
241 else
242 return nr_layers > 1 ? V_008F1C_SQ_RSRC_IMG_2D_ARRAY : V_008F1C_SQ_RSRC_IMG_2D;
243 case VK_IMAGE_TYPE_3D:
244 if (view_type == VK_IMAGE_VIEW_TYPE_3D)
245 return V_008F1C_SQ_RSRC_IMG_3D;
246 else
247 return V_008F1C_SQ_RSRC_IMG_2D_ARRAY;
248 default:
249 unreachable("illegale image type");
250 }
251 }
252 /**
253 * Build the sampler view descriptor for a texture.
254 */
255 static void
256 si_make_texture_descriptor(struct radv_device *device,
257 struct radv_image *image,
258 bool sampler,
259 VkImageViewType view_type,
260 VkFormat vk_format,
261 const VkComponentMapping *mapping,
262 unsigned first_level, unsigned last_level,
263 unsigned first_layer, unsigned last_layer,
264 unsigned width, unsigned height, unsigned depth,
265 uint32_t *state,
266 uint32_t *fmask_state)
267 {
268 const struct vk_format_description *desc;
269 enum vk_swizzle swizzle[4];
270 int first_non_void;
271 unsigned num_format, data_format, type;
272
273 desc = vk_format_description(vk_format);
274
275 if (desc->colorspace == VK_FORMAT_COLORSPACE_ZS) {
276 const unsigned char swizzle_xxxx[4] = {0, 0, 0, 0};
277 vk_format_compose_swizzles(mapping, swizzle_xxxx, swizzle);
278 } else {
279 vk_format_compose_swizzles(mapping, desc->swizzle, swizzle);
280 }
281
282 first_non_void = vk_format_get_first_non_void_channel(vk_format);
283
284 num_format = radv_translate_tex_numformat(vk_format, desc, first_non_void);
285 if (num_format == ~0) {
286 num_format = 0;
287 }
288
289 data_format = radv_translate_tex_dataformat(vk_format, desc, first_non_void);
290 if (data_format == ~0) {
291 data_format = 0;
292 }
293
294 type = radv_tex_dim(image->type, view_type, image->info.array_size, image->info.samples,
295 (image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
296 if (type == V_008F1C_SQ_RSRC_IMG_1D_ARRAY) {
297 height = 1;
298 depth = image->info.array_size;
299 } else if (type == V_008F1C_SQ_RSRC_IMG_2D_ARRAY ||
300 type == V_008F1C_SQ_RSRC_IMG_2D_MSAA_ARRAY) {
301 if (view_type != VK_IMAGE_VIEW_TYPE_3D)
302 depth = image->info.array_size;
303 } else if (type == V_008F1C_SQ_RSRC_IMG_CUBE)
304 depth = image->info.array_size / 6;
305
306 state[0] = 0;
307 state[1] = (S_008F14_DATA_FORMAT_GFX6(data_format) |
308 S_008F14_NUM_FORMAT_GFX6(num_format));
309 state[2] = (S_008F18_WIDTH(width - 1) |
310 S_008F18_HEIGHT(height - 1));
311 state[3] = (S_008F1C_DST_SEL_X(radv_map_swizzle(swizzle[0])) |
312 S_008F1C_DST_SEL_Y(radv_map_swizzle(swizzle[1])) |
313 S_008F1C_DST_SEL_Z(radv_map_swizzle(swizzle[2])) |
314 S_008F1C_DST_SEL_W(radv_map_swizzle(swizzle[3])) |
315 S_008F1C_BASE_LEVEL(image->info.samples > 1 ?
316 0 : first_level) |
317 S_008F1C_LAST_LEVEL(image->info.samples > 1 ?
318 util_logbase2(image->info.samples) :
319 last_level) |
320 S_008F1C_POW2_PAD(image->info.levels > 1) |
321 S_008F1C_TYPE(type));
322 state[4] = S_008F20_DEPTH(depth - 1);
323 state[5] = (S_008F24_BASE_ARRAY(first_layer) |
324 S_008F24_LAST_ARRAY(last_layer));
325 state[6] = 0;
326 state[7] = 0;
327
328 if (image->dcc_offset) {
329 unsigned swap = radv_translate_colorswap(vk_format, FALSE);
330
331 state[6] = S_008F28_ALPHA_IS_ON_MSB(swap <= 1);
332 } else {
333 /* The last dword is unused by hw. The shader uses it to clear
334 * bits in the first dword of sampler state.
335 */
336 if (device->physical_device->rad_info.chip_class <= CIK && image->info.samples <= 1) {
337 if (first_level == last_level)
338 state[7] = C_008F30_MAX_ANISO_RATIO;
339 else
340 state[7] = 0xffffffff;
341 }
342 }
343
344 /* Initialize the sampler view for FMASK. */
345 if (image->fmask.size) {
346 uint32_t fmask_format;
347 uint64_t gpu_address = device->ws->buffer_get_va(image->bo);
348 uint64_t va;
349
350 va = gpu_address + image->offset + image->fmask.offset;
351
352 switch (image->info.samples) {
353 case 2:
354 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S2_F2;
355 break;
356 case 4:
357 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK8_S4_F4;
358 break;
359 case 8:
360 fmask_format = V_008F14_IMG_DATA_FORMAT_FMASK32_S8_F8;
361 break;
362 default:
363 assert(0);
364 fmask_format = V_008F14_IMG_DATA_FORMAT_INVALID;
365 }
366
367 fmask_state[0] = va >> 8;
368 fmask_state[1] = S_008F14_BASE_ADDRESS_HI(va >> 40) |
369 S_008F14_DATA_FORMAT_GFX6(fmask_format) |
370 S_008F14_NUM_FORMAT_GFX6(V_008F14_IMG_NUM_FORMAT_UINT);
371 fmask_state[2] = S_008F18_WIDTH(width - 1) |
372 S_008F18_HEIGHT(height - 1);
373 fmask_state[3] = S_008F1C_DST_SEL_X(V_008F1C_SQ_SEL_X) |
374 S_008F1C_DST_SEL_Y(V_008F1C_SQ_SEL_X) |
375 S_008F1C_DST_SEL_Z(V_008F1C_SQ_SEL_X) |
376 S_008F1C_DST_SEL_W(V_008F1C_SQ_SEL_X) |
377 S_008F1C_TILING_INDEX(image->fmask.tile_mode_index) |
378 S_008F1C_TYPE(radv_tex_dim(image->type, view_type, 1, 0, false));
379 fmask_state[4] = S_008F20_DEPTH(depth - 1) |
380 S_008F20_PITCH_GFX6(image->fmask.pitch_in_pixels - 1);
381 fmask_state[5] = S_008F24_BASE_ARRAY(first_layer) |
382 S_008F24_LAST_ARRAY(last_layer);
383 fmask_state[6] = 0;
384 fmask_state[7] = 0;
385 }
386 }
387
388 static void
389 radv_query_opaque_metadata(struct radv_device *device,
390 struct radv_image *image,
391 struct radeon_bo_metadata *md)
392 {
393 static const VkComponentMapping fixedmapping;
394 uint32_t desc[8], i;
395
396 /* Metadata image format format version 1:
397 * [0] = 1 (metadata format identifier)
398 * [1] = (VENDOR_ID << 16) | PCI_ID
399 * [2:9] = image descriptor for the whole resource
400 * [2] is always 0, because the base address is cleared
401 * [9] is the DCC offset bits [39:8] from the beginning of
402 * the buffer
403 * [10:10+LAST_LEVEL] = mipmap level offset bits [39:8] for each level
404 */
405 md->metadata[0] = 1; /* metadata image format version 1 */
406
407 /* TILE_MODE_INDEX is ambiguous without a PCI ID. */
408 md->metadata[1] = si_get_bo_metadata_word1(device);
409
410
411 si_make_texture_descriptor(device, image, true,
412 (VkImageViewType)image->type, image->vk_format,
413 &fixedmapping, 0, image->info.levels - 1, 0,
414 image->info.array_size,
415 image->info.width, image->info.height,
416 image->info.depth,
417 desc, NULL);
418
419 si_set_mutable_tex_desc_fields(device, image, &image->surface.level[0], 0, 0,
420 image->surface.blk_w, false, desc);
421
422 /* Clear the base address and set the relative DCC offset. */
423 desc[0] = 0;
424 desc[1] &= C_008F14_BASE_ADDRESS_HI;
425 desc[7] = image->dcc_offset >> 8;
426
427 /* Dwords [2:9] contain the image descriptor. */
428 memcpy(&md->metadata[2], desc, sizeof(desc));
429
430 /* Dwords [10:..] contain the mipmap level offsets. */
431 for (i = 0; i <= image->info.levels - 1; i++)
432 md->metadata[10+i] = image->surface.level[i].offset >> 8;
433
434 md->size_metadata = (11 + image->info.levels - 1) * 4;
435 }
436
437 void
438 radv_init_metadata(struct radv_device *device,
439 struct radv_image *image,
440 struct radeon_bo_metadata *metadata)
441 {
442 struct radeon_surf *surface = &image->surface;
443
444 memset(metadata, 0, sizeof(*metadata));
445 metadata->microtile = surface->level[0].mode >= RADEON_SURF_MODE_1D ?
446 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
447 metadata->macrotile = surface->level[0].mode >= RADEON_SURF_MODE_2D ?
448 RADEON_LAYOUT_TILED : RADEON_LAYOUT_LINEAR;
449 metadata->pipe_config = surface->pipe_config;
450 metadata->bankw = surface->bankw;
451 metadata->bankh = surface->bankh;
452 metadata->tile_split = surface->tile_split;
453 metadata->mtilea = surface->mtilea;
454 metadata->num_banks = surface->num_banks;
455 metadata->stride = surface->level[0].pitch_bytes;
456 metadata->scanout = (surface->flags & RADEON_SURF_SCANOUT) != 0;
457
458 radv_query_opaque_metadata(device, image, metadata);
459 }
460
461 /* The number of samples can be specified independently of the texture. */
462 static void
463 radv_image_get_fmask_info(struct radv_device *device,
464 struct radv_image *image,
465 unsigned nr_samples,
466 struct radv_fmask_info *out)
467 {
468 /* FMASK is allocated like an ordinary texture. */
469 struct radeon_surf fmask = image->surface;
470
471 memset(out, 0, sizeof(*out));
472
473 fmask.bo_alignment = 0;
474 fmask.bo_size = 0;
475 fmask.nsamples = 1;
476 fmask.flags |= RADEON_SURF_FMASK;
477
478 /* Force 2D tiling if it wasn't set. This may occur when creating
479 * FMASK for MSAA resolve on R6xx. On R6xx, the single-sample
480 * destination buffer must have an FMASK too. */
481 fmask.flags = RADEON_SURF_CLR(fmask.flags, MODE);
482 fmask.flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
483
484 fmask.flags |= RADEON_SURF_HAS_TILE_MODE_INDEX;
485
486 switch (nr_samples) {
487 case 2:
488 case 4:
489 fmask.bpe = 1;
490 break;
491 case 8:
492 fmask.bpe = 4;
493 break;
494 default:
495 return;
496 }
497
498 device->ws->surface_init(device->ws, &fmask);
499 assert(fmask.level[0].mode == RADEON_SURF_MODE_2D);
500
501 out->slice_tile_max = (fmask.level[0].nblk_x * fmask.level[0].nblk_y) / 64;
502 if (out->slice_tile_max)
503 out->slice_tile_max -= 1;
504
505 out->tile_mode_index = fmask.tiling_index[0];
506 out->pitch_in_pixels = fmask.level[0].nblk_x;
507 out->bank_height = fmask.bankh;
508 out->alignment = MAX2(256, fmask.bo_alignment);
509 out->size = fmask.bo_size;
510 }
511
512 static void
513 radv_image_alloc_fmask(struct radv_device *device,
514 struct radv_image *image)
515 {
516 radv_image_get_fmask_info(device, image, image->info.samples, &image->fmask);
517
518 image->fmask.offset = align64(image->size, image->fmask.alignment);
519 image->size = image->fmask.offset + image->fmask.size;
520 image->alignment = MAX2(image->alignment, image->fmask.alignment);
521 }
522
523 static void
524 radv_image_get_cmask_info(struct radv_device *device,
525 struct radv_image *image,
526 struct radv_cmask_info *out)
527 {
528 unsigned pipe_interleave_bytes = device->physical_device->rad_info.pipe_interleave_bytes;
529 unsigned num_pipes = device->physical_device->rad_info.num_tile_pipes;
530 unsigned cl_width, cl_height;
531
532 switch (num_pipes) {
533 case 2:
534 cl_width = 32;
535 cl_height = 16;
536 break;
537 case 4:
538 cl_width = 32;
539 cl_height = 32;
540 break;
541 case 8:
542 cl_width = 64;
543 cl_height = 32;
544 break;
545 case 16: /* Hawaii */
546 cl_width = 64;
547 cl_height = 64;
548 break;
549 default:
550 assert(0);
551 return;
552 }
553
554 unsigned base_align = num_pipes * pipe_interleave_bytes;
555
556 unsigned width = align(image->surface.npix_x, cl_width*8);
557 unsigned height = align(image->surface.npix_y, cl_height*8);
558 unsigned slice_elements = (width * height) / (8*8);
559
560 /* Each element of CMASK is a nibble. */
561 unsigned slice_bytes = slice_elements / 2;
562
563 out->slice_tile_max = (width * height) / (128*128);
564 if (out->slice_tile_max)
565 out->slice_tile_max -= 1;
566
567 out->alignment = MAX2(256, base_align);
568 out->size = (image->type == VK_IMAGE_TYPE_3D ? image->info.depth : image->info.array_size) *
569 align(slice_bytes, base_align);
570 }
571
572 static void
573 radv_image_alloc_cmask(struct radv_device *device,
574 struct radv_image *image)
575 {
576 radv_image_get_cmask_info(device, image, &image->cmask);
577
578 image->cmask.offset = align64(image->size, image->cmask.alignment);
579 /* + 8 for storing the clear values */
580 image->clear_value_offset = image->cmask.offset + image->cmask.size;
581 image->size = image->cmask.offset + image->cmask.size + 8;
582 image->alignment = MAX2(image->alignment, image->cmask.alignment);
583 }
584
585 static void
586 radv_image_alloc_dcc(struct radv_device *device,
587 struct radv_image *image)
588 {
589 image->dcc_offset = align64(image->size, image->surface.dcc_alignment);
590 /* + 8 for storing the clear values */
591 image->clear_value_offset = image->dcc_offset + image->surface.dcc_size;
592 image->size = image->dcc_offset + image->surface.dcc_size + 8;
593 image->alignment = MAX2(image->alignment, image->surface.dcc_alignment);
594 }
595
596 static void
597 radv_image_alloc_htile(struct radv_device *device,
598 struct radv_image *image)
599 {
600 if ((device->debug_flags & RADV_DEBUG_NO_HIZ) || image->info.levels > 1) {
601 image->surface.htile_size = 0;
602 return;
603 }
604
605 image->htile_offset = align64(image->size, image->surface.htile_alignment);
606
607 /* + 8 for storing the clear values */
608 image->clear_value_offset = image->htile_offset + image->surface.htile_size;
609 image->size = image->clear_value_offset + 8;
610 image->alignment = align64(image->alignment, image->surface.htile_alignment);
611 }
612
613 VkResult
614 radv_image_create(VkDevice _device,
615 const struct radv_image_create_info *create_info,
616 const VkAllocationCallbacks* alloc,
617 VkImage *pImage)
618 {
619 RADV_FROM_HANDLE(radv_device, device, _device);
620 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
621 struct radv_image *image = NULL;
622 bool can_cmask_dcc = false;
623 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
624
625 radv_assert(pCreateInfo->mipLevels > 0);
626 radv_assert(pCreateInfo->arrayLayers > 0);
627 radv_assert(pCreateInfo->samples > 0);
628 radv_assert(pCreateInfo->extent.width > 0);
629 radv_assert(pCreateInfo->extent.height > 0);
630 radv_assert(pCreateInfo->extent.depth > 0);
631
632 image = vk_alloc2(&device->alloc, alloc, sizeof(*image), 8,
633 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
634 if (!image)
635 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
636
637 memset(image, 0, sizeof(*image));
638 image->type = pCreateInfo->imageType;
639 image->info.width = pCreateInfo->extent.width;
640 image->info.height = pCreateInfo->extent.height;
641 image->info.depth = pCreateInfo->extent.depth;
642 image->info.samples = pCreateInfo->samples;
643 image->info.array_size = pCreateInfo->arrayLayers;
644 image->info.levels = pCreateInfo->mipLevels;
645
646 image->vk_format = pCreateInfo->format;
647 image->tiling = pCreateInfo->tiling;
648 image->usage = pCreateInfo->usage;
649 image->flags = pCreateInfo->flags;
650
651 image->exclusive = pCreateInfo->sharingMode == VK_SHARING_MODE_EXCLUSIVE;
652 if (pCreateInfo->sharingMode == VK_SHARING_MODE_CONCURRENT) {
653 for (uint32_t i = 0; i < pCreateInfo->queueFamilyIndexCount; ++i)
654 image->queue_family_mask |= 1u << pCreateInfo->pQueueFamilyIndices[i];
655 }
656
657 radv_init_surface(device, &image->surface, create_info);
658
659 device->ws->surface_init(device->ws, &image->surface);
660
661 image->size = image->surface.bo_size;
662 image->alignment = image->surface.bo_alignment;
663
664 if (image->exclusive || image->queue_family_mask == 1)
665 can_cmask_dcc = true;
666
667 if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
668 image->surface.dcc_size && can_cmask_dcc)
669 radv_image_alloc_dcc(device, image);
670 else
671 image->surface.dcc_size = 0;
672
673 if ((pCreateInfo->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) &&
674 pCreateInfo->mipLevels == 1 &&
675 !image->surface.dcc_size && image->info.depth == 1 && can_cmask_dcc)
676 radv_image_alloc_cmask(device, image);
677 if (image->info.samples > 1 && vk_format_is_color(pCreateInfo->format)) {
678 radv_image_alloc_fmask(device, image);
679 } else if (vk_format_is_depth(pCreateInfo->format)) {
680
681 radv_image_alloc_htile(device, image);
682 }
683
684
685 if (create_info->stride && create_info->stride != image->surface.level[0].pitch_bytes) {
686 image->surface.level[0].nblk_x = create_info->stride / image->surface.bpe;
687 image->surface.level[0].pitch_bytes = create_info->stride;
688 image->surface.level[0].slice_size = create_info->stride * image->surface.level[0].nblk_y;
689 }
690
691 if (pCreateInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) {
692 image->alignment = MAX2(image->alignment, 4096);
693 image->size = align64(image->size, image->alignment);
694 image->offset = 0;
695
696 image->bo = device->ws->buffer_create(device->ws, image->size, image->alignment,
697 0, RADEON_FLAG_VIRTUAL);
698 if (!image->bo) {
699 vk_free2(&device->alloc, alloc, image);
700 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
701 }
702 }
703
704 *pImage = radv_image_to_handle(image);
705
706 return VK_SUCCESS;
707 }
708
709 void
710 radv_image_view_init(struct radv_image_view *iview,
711 struct radv_device *device,
712 const VkImageViewCreateInfo* pCreateInfo,
713 struct radv_cmd_buffer *cmd_buffer,
714 VkImageUsageFlags usage_mask)
715 {
716 RADV_FROM_HANDLE(radv_image, image, pCreateInfo->image);
717 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
718 uint32_t blk_w;
719 bool is_stencil = false;
720 switch (image->type) {
721 case VK_IMAGE_TYPE_1D:
722 case VK_IMAGE_TYPE_2D:
723 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1 <= image->info.array_size);
724 break;
725 case VK_IMAGE_TYPE_3D:
726 assert(range->baseArrayLayer + radv_get_layerCount(image, range) - 1
727 <= radv_minify(image->info.depth, range->baseMipLevel));
728 break;
729 default:
730 unreachable("bad VkImageType");
731 }
732 iview->image = image;
733 iview->bo = image->bo;
734 iview->type = pCreateInfo->viewType;
735 iview->vk_format = pCreateInfo->format;
736 iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
737
738 if (iview->aspect_mask == VK_IMAGE_ASPECT_STENCIL_BIT) {
739 is_stencil = true;
740 iview->vk_format = vk_format_stencil_only(iview->vk_format);
741 } else if (iview->aspect_mask == VK_IMAGE_ASPECT_DEPTH_BIT) {
742 iview->vk_format = vk_format_depth_only(iview->vk_format);
743 }
744
745 iview->extent = (VkExtent3D) {
746 .width = radv_minify(image->info.width , range->baseMipLevel),
747 .height = radv_minify(image->info.height, range->baseMipLevel),
748 .depth = radv_minify(image->info.depth , range->baseMipLevel),
749 };
750
751 iview->extent.width = round_up_u32(iview->extent.width * vk_format_get_blockwidth(iview->vk_format),
752 vk_format_get_blockwidth(image->vk_format));
753 iview->extent.height = round_up_u32(iview->extent.height * vk_format_get_blockheight(iview->vk_format),
754 vk_format_get_blockheight(image->vk_format));
755
756 assert(image->surface.blk_w % vk_format_get_blockwidth(image->vk_format) == 0);
757 blk_w = image->surface.blk_w / vk_format_get_blockwidth(image->vk_format) * vk_format_get_blockwidth(iview->vk_format);
758 iview->base_layer = range->baseArrayLayer;
759 iview->layer_count = radv_get_layerCount(image, range);
760 iview->base_mip = range->baseMipLevel;
761
762 si_make_texture_descriptor(device, image, false,
763 iview->type,
764 iview->vk_format,
765 &pCreateInfo->components,
766 0, radv_get_levelCount(image, range) - 1,
767 range->baseArrayLayer,
768 range->baseArrayLayer + radv_get_layerCount(image, range) - 1,
769 iview->extent.width,
770 iview->extent.height,
771 iview->extent.depth,
772 iview->descriptor,
773 iview->fmask_descriptor);
774 si_set_mutable_tex_desc_fields(device, image,
775 is_stencil ? &image->surface.stencil_level[range->baseMipLevel] : &image->surface.level[range->baseMipLevel], range->baseMipLevel,
776 range->baseMipLevel,
777 blk_w, is_stencil, iview->descriptor);
778 }
779
780 void radv_image_set_optimal_micro_tile_mode(struct radv_device *device,
781 struct radv_image *image, uint32_t micro_tile_mode)
782 {
783 /* These magic numbers were copied from addrlib. It doesn't use any
784 * definitions for them either. They are all 2D_TILED_THIN1 modes with
785 * different bpp and micro tile mode.
786 */
787 if (device->physical_device->rad_info.chip_class >= CIK) {
788 switch (micro_tile_mode) {
789 case 0: /* displayable */
790 image->surface.tiling_index[0] = 10;
791 break;
792 case 1: /* thin */
793 image->surface.tiling_index[0] = 14;
794 break;
795 case 3: /* rotated */
796 image->surface.tiling_index[0] = 28;
797 break;
798 default: /* depth, thick */
799 assert(!"unexpected micro mode");
800 return;
801 }
802 } else { /* SI */
803 switch (micro_tile_mode) {
804 case 0: /* displayable */
805 switch (image->surface.bpe) {
806 case 1:
807 image->surface.tiling_index[0] = 10;
808 break;
809 case 2:
810 image->surface.tiling_index[0] = 11;
811 break;
812 default: /* 4, 8 */
813 image->surface.tiling_index[0] = 12;
814 break;
815 }
816 break;
817 case 1: /* thin */
818 switch (image->surface.bpe) {
819 case 1:
820 image->surface.tiling_index[0] = 14;
821 break;
822 case 2:
823 image->surface.tiling_index[0] = 15;
824 break;
825 case 4:
826 image->surface.tiling_index[0] = 16;
827 break;
828 default: /* 8, 16 */
829 image->surface.tiling_index[0] = 17;
830 break;
831 }
832 break;
833 default: /* depth, thick */
834 assert(!"unexpected micro mode");
835 return;
836 }
837 }
838
839 image->surface.micro_tile_mode = micro_tile_mode;
840 }
841
842 bool radv_layout_has_htile(const struct radv_image *image,
843 VkImageLayout layout)
844 {
845 return (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
846 layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
847 }
848
849 bool radv_layout_is_htile_compressed(const struct radv_image *image,
850 VkImageLayout layout)
851 {
852 return layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
853 }
854
855 bool radv_layout_can_expclear(const struct radv_image *image,
856 VkImageLayout layout)
857 {
858 return (layout == VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL ||
859 layout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
860 }
861
862 bool radv_layout_can_fast_clear(const struct radv_image *image,
863 VkImageLayout layout,
864 unsigned queue_mask)
865 {
866 return layout == VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL &&
867 queue_mask == (1u << RADV_QUEUE_GENERAL);
868 }
869
870
871 unsigned radv_image_queue_family_mask(const struct radv_image *image, uint32_t family, uint32_t queue_family)
872 {
873 if (!image->exclusive)
874 return image->queue_family_mask;
875 if (family == VK_QUEUE_FAMILY_IGNORED)
876 return 1u << queue_family;
877 return 1u << family;
878 }
879
880 VkResult
881 radv_CreateImage(VkDevice device,
882 const VkImageCreateInfo *pCreateInfo,
883 const VkAllocationCallbacks *pAllocator,
884 VkImage *pImage)
885 {
886 return radv_image_create(device,
887 &(struct radv_image_create_info) {
888 .vk_info = pCreateInfo,
889 .scanout = false,
890 },
891 pAllocator,
892 pImage);
893 }
894
895 void
896 radv_DestroyImage(VkDevice _device, VkImage _image,
897 const VkAllocationCallbacks *pAllocator)
898 {
899 RADV_FROM_HANDLE(radv_device, device, _device);
900 RADV_FROM_HANDLE(radv_image, image, _image);
901
902 if (!image)
903 return;
904
905 if (image->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT)
906 device->ws->buffer_destroy(image->bo);
907
908 vk_free2(&device->alloc, pAllocator, image);
909 }
910
911 void radv_GetImageSubresourceLayout(
912 VkDevice device,
913 VkImage _image,
914 const VkImageSubresource* pSubresource,
915 VkSubresourceLayout* pLayout)
916 {
917 RADV_FROM_HANDLE(radv_image, image, _image);
918 int level = pSubresource->mipLevel;
919 int layer = pSubresource->arrayLayer;
920
921 pLayout->offset = image->surface.level[level].offset + image->surface.level[level].slice_size * layer;
922 pLayout->rowPitch = image->surface.level[level].pitch_bytes;
923 pLayout->arrayPitch = image->surface.level[level].slice_size;
924 pLayout->depthPitch = image->surface.level[level].slice_size;
925 pLayout->size = image->surface.level[level].slice_size;
926 if (image->type == VK_IMAGE_TYPE_3D)
927 pLayout->size *= image->surface.level[level].nblk_z;
928 }
929
930
931 VkResult
932 radv_CreateImageView(VkDevice _device,
933 const VkImageViewCreateInfo *pCreateInfo,
934 const VkAllocationCallbacks *pAllocator,
935 VkImageView *pView)
936 {
937 RADV_FROM_HANDLE(radv_device, device, _device);
938 struct radv_image_view *view;
939
940 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
941 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
942 if (view == NULL)
943 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
944
945 radv_image_view_init(view, device, pCreateInfo, NULL, ~0);
946
947 *pView = radv_image_view_to_handle(view);
948
949 return VK_SUCCESS;
950 }
951
952 void
953 radv_DestroyImageView(VkDevice _device, VkImageView _iview,
954 const VkAllocationCallbacks *pAllocator)
955 {
956 RADV_FROM_HANDLE(radv_device, device, _device);
957 RADV_FROM_HANDLE(radv_image_view, iview, _iview);
958
959 if (!iview)
960 return;
961 vk_free2(&device->alloc, pAllocator, iview);
962 }
963
964 void radv_buffer_view_init(struct radv_buffer_view *view,
965 struct radv_device *device,
966 const VkBufferViewCreateInfo* pCreateInfo,
967 struct radv_cmd_buffer *cmd_buffer)
968 {
969 RADV_FROM_HANDLE(radv_buffer, buffer, pCreateInfo->buffer);
970
971 view->bo = buffer->bo;
972 view->range = pCreateInfo->range == VK_WHOLE_SIZE ?
973 buffer->size - pCreateInfo->offset : pCreateInfo->range;
974 view->vk_format = pCreateInfo->format;
975
976 radv_make_buffer_descriptor(device, buffer, view->vk_format,
977 pCreateInfo->offset, view->range, view->state);
978 }
979
980 VkResult
981 radv_CreateBufferView(VkDevice _device,
982 const VkBufferViewCreateInfo *pCreateInfo,
983 const VkAllocationCallbacks *pAllocator,
984 VkBufferView *pView)
985 {
986 RADV_FROM_HANDLE(radv_device, device, _device);
987 struct radv_buffer_view *view;
988
989 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
990 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
991 if (!view)
992 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
993
994 radv_buffer_view_init(view, device, pCreateInfo, NULL);
995
996 *pView = radv_buffer_view_to_handle(view);
997
998 return VK_SUCCESS;
999 }
1000
1001 void
1002 radv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
1003 const VkAllocationCallbacks *pAllocator)
1004 {
1005 RADV_FROM_HANDLE(radv_device, device, _device);
1006 RADV_FROM_HANDLE(radv_buffer_view, view, bufferView);
1007
1008 if (!view)
1009 return;
1010
1011 vk_free2(&device->alloc, pAllocator, view);
1012 }