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