c34cf209e75d1dbf4f2fc400ce411e805b38f417
[mesa.git] / src / intel / vulkan / anv_image.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29 #include <sys/mman.h>
30 #include "drm-uapi/drm_fourcc.h"
31
32 #include "anv_private.h"
33 #include "util/debug.h"
34 #include "vk_util.h"
35 #include "util/u_math.h"
36
37 #include "common/gen_aux_map.h"
38
39 #include "vk_format_info.h"
40
41 static isl_surf_usage_flags_t
42 choose_isl_surf_usage(VkImageCreateFlags vk_create_flags,
43 VkImageUsageFlags vk_usage,
44 isl_surf_usage_flags_t isl_extra_usage,
45 VkImageAspectFlagBits aspect)
46 {
47 isl_surf_usage_flags_t isl_usage = isl_extra_usage;
48
49 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
50 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
51
52 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
53 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
54
55 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
56 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
57
58 if (vk_create_flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
59 isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
60
61 /* Even if we're only using it for transfer operations, clears to depth and
62 * stencil images happen as depth and stencil so they need the right ISL
63 * usage bits or else things will fall apart.
64 */
65 switch (aspect) {
66 case VK_IMAGE_ASPECT_DEPTH_BIT:
67 isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
68 break;
69 case VK_IMAGE_ASPECT_STENCIL_BIT:
70 isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
71 break;
72 case VK_IMAGE_ASPECT_COLOR_BIT:
73 case VK_IMAGE_ASPECT_PLANE_0_BIT:
74 case VK_IMAGE_ASPECT_PLANE_1_BIT:
75 case VK_IMAGE_ASPECT_PLANE_2_BIT:
76 break;
77 default:
78 unreachable("bad VkImageAspect");
79 }
80
81 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
82 /* blorp implements transfers by sampling from the source image. */
83 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
84 }
85
86 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&
87 aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
88 /* blorp implements transfers by rendering into the destination image.
89 * Only request this with color images, as we deal with depth/stencil
90 * formats differently. */
91 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
92 }
93
94 return isl_usage;
95 }
96
97 static isl_tiling_flags_t
98 choose_isl_tiling_flags(const struct anv_image_create_info *anv_info,
99 const struct isl_drm_modifier_info *isl_mod_info,
100 bool legacy_scanout)
101 {
102 const VkImageCreateInfo *base_info = anv_info->vk_info;
103 isl_tiling_flags_t flags = 0;
104
105 switch (base_info->tiling) {
106 default:
107 unreachable("bad VkImageTiling");
108 case VK_IMAGE_TILING_OPTIMAL:
109 flags = ISL_TILING_ANY_MASK;
110 break;
111 case VK_IMAGE_TILING_LINEAR:
112 flags = ISL_TILING_LINEAR_BIT;
113 break;
114 }
115
116 if (anv_info->isl_tiling_flags)
117 flags &= anv_info->isl_tiling_flags;
118
119 if (legacy_scanout)
120 flags &= ISL_TILING_LINEAR_BIT | ISL_TILING_X_BIT;
121
122 if (isl_mod_info)
123 flags &= 1 << isl_mod_info->tiling;
124
125 assert(flags);
126
127 return flags;
128 }
129
130 static struct anv_surface *
131 get_surface(struct anv_image *image, VkImageAspectFlagBits aspect)
132 {
133 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
134 return &image->planes[plane].surface;
135 }
136
137 static void
138 add_surface(struct anv_image *image, struct anv_surface *surf, uint32_t plane)
139 {
140 assert(surf->isl.size_B > 0); /* isl surface must be initialized */
141
142 if (image->disjoint) {
143 surf->offset = align_u32(image->planes[plane].size,
144 surf->isl.alignment_B);
145 /* Plane offset is always 0 when it's disjoint. */
146 } else {
147 surf->offset = align_u32(image->size, surf->isl.alignment_B);
148 /* Determine plane's offset only once when the first surface is added. */
149 if (image->planes[plane].size == 0)
150 image->planes[plane].offset = image->size;
151 }
152
153 image->size = surf->offset + surf->isl.size_B;
154 image->planes[plane].size = (surf->offset + surf->isl.size_B) - image->planes[plane].offset;
155
156 image->alignment = MAX2(image->alignment, surf->isl.alignment_B);
157 image->planes[plane].alignment = MAX2(image->planes[plane].alignment,
158 surf->isl.alignment_B);
159 }
160
161
162 static bool
163 all_formats_ccs_e_compatible(const struct gen_device_info *devinfo,
164 const VkImageFormatListCreateInfoKHR *fmt_list,
165 struct anv_image *image)
166 {
167 enum isl_format format =
168 anv_get_isl_format(devinfo, image->vk_format,
169 VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
170
171 if (!isl_format_supports_ccs_e(devinfo, format))
172 return false;
173
174 if (!(image->create_flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT))
175 return true;
176
177 if (!fmt_list || fmt_list->viewFormatCount == 0)
178 return false;
179
180 for (uint32_t i = 0; i < fmt_list->viewFormatCount; i++) {
181 enum isl_format view_format =
182 anv_get_isl_format(devinfo, fmt_list->pViewFormats[i],
183 VK_IMAGE_ASPECT_COLOR_BIT, image->tiling);
184
185 if (!isl_formats_are_ccs_e_compatible(devinfo, format, view_format))
186 return false;
187 }
188
189 return true;
190 }
191
192 /**
193 * For color images that have an auxiliary surface, request allocation for an
194 * additional buffer that mainly stores fast-clear values. Use of this buffer
195 * allows us to access the image's subresources while being aware of their
196 * fast-clear values in non-trivial cases (e.g., outside of a render pass in
197 * which a fast clear has occurred).
198 *
199 * In order to avoid having multiple clear colors for a single plane of an
200 * image (hence a single RENDER_SURFACE_STATE), we only allow fast-clears on
201 * the first slice (level 0, layer 0). At the time of our testing (Jan 17,
202 * 2018), there were no known applications which would benefit from fast-
203 * clearing more than just the first slice.
204 *
205 * The fast clear portion of the image is laid out in the following order:
206 *
207 * * 1 or 4 dwords (depending on hardware generation) for the clear color
208 * * 1 dword for the anv_fast_clear_type of the clear color
209 * * On gen9+, 1 dword per level and layer of the image (3D levels count
210 * multiple layers) in level-major order for compression state.
211 *
212 * For the purpose of discoverability, the algorithm used to manage
213 * compression and fast-clears is described here:
214 *
215 * * On a transition from UNDEFINED or PREINITIALIZED to a defined layout,
216 * all of the values in the fast clear portion of the image are initialized
217 * to default values.
218 *
219 * * On fast-clear, the clear value is written into surface state and also
220 * into the buffer and the fast clear type is set appropriately. Both
221 * setting the fast-clear value in the buffer and setting the fast-clear
222 * type happen from the GPU using MI commands.
223 *
224 * * Whenever a render or blorp operation is performed with CCS_E, we call
225 * genX(cmd_buffer_mark_image_written) to set the compression state to
226 * true (which is represented by UINT32_MAX).
227 *
228 * * On pipeline barrier transitions, the worst-case transition is computed
229 * from the image layouts. The command streamer inspects the fast clear
230 * type and compression state dwords and constructs a predicate. The
231 * worst-case resolve is performed with the given predicate and the fast
232 * clear and compression state is set accordingly.
233 *
234 * See anv_layout_to_aux_usage and anv_layout_to_fast_clear_type functions for
235 * details on exactly what is allowed in what layouts.
236 *
237 * On gen7-9, we do not have a concept of indirect clear colors in hardware.
238 * In order to deal with this, we have to do some clear color management.
239 *
240 * * For LOAD_OP_LOAD at the top of a renderpass, we have to copy the clear
241 * value from the buffer into the surface state with MI commands.
242 *
243 * * For any blorp operations, we pass the address to the clear value into
244 * blorp and it knows to copy the clear color.
245 */
246 static void
247 add_aux_state_tracking_buffer(struct anv_image *image,
248 uint32_t plane,
249 const struct anv_device *device)
250 {
251 assert(image && device);
252 assert(image->planes[plane].aux_surface.isl.size_B > 0 &&
253 image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
254
255 /* Compressed images must be tiled and therefore everything should be 4K
256 * aligned. The CCS has the same alignment requirements. This is good
257 * because we need at least dword-alignment for MI_LOAD/STORE operations.
258 */
259 assert(image->alignment % 4 == 0);
260 assert((image->planes[plane].offset + image->planes[plane].size) % 4 == 0);
261
262 /* This buffer should be at the very end of the plane. */
263 if (image->disjoint) {
264 assert(image->planes[plane].size ==
265 (image->planes[plane].offset + image->planes[plane].size));
266 } else {
267 assert(image->size ==
268 (image->planes[plane].offset + image->planes[plane].size));
269 }
270
271 const unsigned clear_color_state_size = device->info.gen >= 10 ?
272 device->isl_dev.ss.clear_color_state_size :
273 device->isl_dev.ss.clear_value_size;
274
275 /* Clear color and fast clear type */
276 unsigned state_size = clear_color_state_size + 4;
277
278 /* We only need to track compression on CCS_E surfaces. */
279 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E) {
280 if (image->type == VK_IMAGE_TYPE_3D) {
281 for (uint32_t l = 0; l < image->levels; l++)
282 state_size += anv_minify(image->extent.depth, l) * 4;
283 } else {
284 state_size += image->levels * image->array_size * 4;
285 }
286 }
287
288 image->planes[plane].fast_clear_state_offset =
289 image->planes[plane].offset + image->planes[plane].size;
290
291 image->planes[plane].size += state_size;
292 image->size += state_size;
293 }
294
295 /**
296 * Initialize the anv_image::*_surface selected by \a aspect. Then update the
297 * image's memory requirements (that is, the image's size and alignment).
298 */
299 static VkResult
300 make_surface(const struct anv_device *dev,
301 struct anv_image *image,
302 uint32_t stride,
303 isl_tiling_flags_t tiling_flags,
304 isl_surf_usage_flags_t isl_extra_usage_flags,
305 VkImageAspectFlagBits aspect)
306 {
307 bool ok;
308
309 static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
310 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
311 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
312 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
313 };
314
315 image->extent = anv_sanitize_image_extent(image->type, image->extent);
316
317 const unsigned plane = anv_image_aspect_to_plane(image->aspects, aspect);
318 const struct anv_format_plane plane_format =
319 anv_get_format_plane(&dev->info, image->vk_format, aspect, image->tiling);
320 struct anv_surface *anv_surf = &image->planes[plane].surface;
321
322 const isl_surf_usage_flags_t usage =
323 choose_isl_surf_usage(image->create_flags, image->usage,
324 isl_extra_usage_flags, aspect);
325
326 /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to
327 * fall back to linear on Broadwell and earlier because we aren't
328 * guaranteed that we can handle offsets correctly. On Sky Lake, the
329 * horizontal and vertical alignments are sufficiently high that we can
330 * just use RENDER_SURFACE_STATE::X/Y Offset.
331 */
332 bool needs_shadow = false;
333 isl_surf_usage_flags_t shadow_usage = 0;
334 if (dev->info.gen <= 8 &&
335 (image->create_flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT) &&
336 image->tiling == VK_IMAGE_TILING_OPTIMAL) {
337 assert(isl_format_is_compressed(plane_format.isl_format));
338 tiling_flags = ISL_TILING_LINEAR_BIT;
339 needs_shadow = true;
340 shadow_usage = ISL_SURF_USAGE_TEXTURE_BIT |
341 (usage & ISL_SURF_USAGE_CUBE_BIT);
342 }
343
344 if (dev->info.gen <= 7 &&
345 aspect == VK_IMAGE_ASPECT_STENCIL_BIT &&
346 (image->stencil_usage & VK_IMAGE_USAGE_SAMPLED_BIT)) {
347 needs_shadow = true;
348 shadow_usage = ISL_SURF_USAGE_TEXTURE_BIT |
349 (usage & ISL_SURF_USAGE_CUBE_BIT);
350 }
351
352 ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
353 .dim = vk_to_isl_surf_dim[image->type],
354 .format = plane_format.isl_format,
355 .width = image->extent.width / plane_format.denominator_scales[0],
356 .height = image->extent.height / plane_format.denominator_scales[1],
357 .depth = image->extent.depth,
358 .levels = image->levels,
359 .array_len = image->array_size,
360 .samples = image->samples,
361 .min_alignment_B = 0,
362 .row_pitch_B = stride,
363 .usage = usage,
364 .tiling_flags = tiling_flags);
365
366 if (!ok)
367 return VK_ERROR_OUT_OF_DEVICE_MEMORY;
368
369 image->planes[plane].aux_usage = ISL_AUX_USAGE_NONE;
370
371 add_surface(image, anv_surf, plane);
372
373 /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to
374 * create an identical tiled shadow surface for use while texturing so we
375 * don't get garbage performance. If we're on gen7 and the image contains
376 * stencil, then we need to maintain a shadow because we can't texture from
377 * W-tiled images.
378 */
379 if (needs_shadow) {
380 ok = isl_surf_init(&dev->isl_dev, &image->planes[plane].shadow_surface.isl,
381 .dim = vk_to_isl_surf_dim[image->type],
382 .format = plane_format.isl_format,
383 .width = image->extent.width,
384 .height = image->extent.height,
385 .depth = image->extent.depth,
386 .levels = image->levels,
387 .array_len = image->array_size,
388 .samples = image->samples,
389 .min_alignment_B = 0,
390 .row_pitch_B = stride,
391 .usage = shadow_usage,
392 .tiling_flags = ISL_TILING_ANY_MASK);
393
394 /* isl_surf_init() will fail only if provided invalid input. Invalid input
395 * is illegal in Vulkan.
396 */
397 assert(ok);
398
399 add_surface(image, &image->planes[plane].shadow_surface, plane);
400 }
401
402 /* Add a HiZ surface to a depth buffer that will be used for rendering.
403 */
404 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
405 /* We don't advertise that depth buffers could be used as storage
406 * images.
407 */
408 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
409
410 /* Allow the user to control HiZ enabling. Disable by default on gen7
411 * because resolves are not currently implemented pre-BDW.
412 */
413 if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
414 /* It will never be used as an attachment, HiZ is pointless. */
415 } else if (dev->info.gen == 7) {
416 anv_perf_warn(dev->instance, image, "Implement gen7 HiZ");
417 } else if (image->levels > 1) {
418 anv_perf_warn(dev->instance, image, "Enable multi-LOD HiZ");
419 } else if (image->array_size > 1) {
420 anv_perf_warn(dev->instance, image,
421 "Implement multi-arrayLayer HiZ clears and resolves");
422 } else if (dev->info.gen == 8 && image->samples > 1) {
423 anv_perf_warn(dev->instance, image, "Enable gen8 multisampled HiZ");
424 } else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) {
425 assert(image->planes[plane].aux_surface.isl.size_B == 0);
426 ok = isl_surf_get_hiz_surf(&dev->isl_dev,
427 &image->planes[plane].surface.isl,
428 &image->planes[plane].aux_surface.isl);
429 assert(ok);
430 add_surface(image, &image->planes[plane].aux_surface, plane);
431 image->planes[plane].aux_usage = ISL_AUX_USAGE_HIZ;
432 }
433 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples == 1) {
434 /* TODO: Disallow compression with :
435 *
436 * 1) non multiplanar images (We appear to hit a sampler bug with
437 * CCS & R16G16 format. Putting the clear state a page/4096bytes
438 * further fixes the issue).
439 *
440 * 2) alias images, because they might be aliases of images
441 * described in 1)
442 *
443 * 3) compression disabled by debug
444 */
445 const bool allow_compression =
446 image->n_planes == 1 &&
447 (image->create_flags & VK_IMAGE_CREATE_ALIAS_BIT) == 0 &&
448 likely((INTEL_DEBUG & DEBUG_NO_RBC) == 0);
449
450 if (allow_compression) {
451 assert(image->planes[plane].aux_surface.isl.size_B == 0);
452 ok = isl_surf_get_ccs_surf(&dev->isl_dev,
453 &image->planes[plane].surface.isl,
454 &image->planes[plane].aux_surface.isl,
455 NULL, 0);
456 if (ok) {
457
458 /* Disable CCS when it is not useful (i.e., when you can't render
459 * to the image with CCS enabled).
460 */
461 if (!isl_format_supports_rendering(&dev->info,
462 plane_format.isl_format)) {
463 /* While it may be technically possible to enable CCS for this
464 * image, we currently don't have things hooked up to get it
465 * working.
466 */
467 anv_perf_warn(dev->instance, image,
468 "This image format doesn't support rendering. "
469 "Not allocating an CCS buffer.");
470 image->planes[plane].aux_surface.isl.size_B = 0;
471 return VK_SUCCESS;
472 }
473
474 /* For images created without MUTABLE_FORMAT_BIT set, we know that
475 * they will always be used with the original format. In
476 * particular, they will always be used with a format that
477 * supports color compression. If it's never used as a storage
478 * image, then it will only be used through the sampler or the as
479 * a render target. This means that it's safe to just leave
480 * compression on at all times for these formats.
481 */
482 if (!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
483 image->ccs_e_compatible) {
484 image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;
485 } else if (dev->info.gen >= 12) {
486 anv_perf_warn(dev->instance, image,
487 "The CCS_D aux mode is not yet handled on "
488 "Gen12+. Not allocating a CCS buffer.");
489 image->planes[plane].aux_surface.isl.size_B = 0;
490 return VK_SUCCESS;
491 }
492
493 add_surface(image, &image->planes[plane].aux_surface, plane);
494 add_aux_state_tracking_buffer(image, plane, dev);
495 }
496 }
497 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) {
498 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
499 assert(image->planes[plane].aux_surface.isl.size_B == 0);
500 ok = isl_surf_get_mcs_surf(&dev->isl_dev,
501 &image->planes[plane].surface.isl,
502 &image->planes[plane].aux_surface.isl);
503 if (ok) {
504 add_surface(image, &image->planes[plane].aux_surface, plane);
505 add_aux_state_tracking_buffer(image, plane, dev);
506 image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS;
507 }
508 }
509
510 assert((image->planes[plane].offset + image->planes[plane].size) == image->size);
511
512 /* Upper bound of the last surface should be smaller than the plane's
513 * size.
514 */
515 assert((MAX2(image->planes[plane].surface.offset,
516 image->planes[plane].aux_surface.offset) +
517 (image->planes[plane].aux_surface.isl.size_B > 0 ?
518 image->planes[plane].aux_surface.isl.size_B :
519 image->planes[plane].surface.isl.size_B)) <=
520 (image->planes[plane].offset + image->planes[plane].size));
521
522 if (image->planes[plane].aux_surface.isl.size_B) {
523 /* assert(image->planes[plane].fast_clear_state_offset == */
524 /* (image->planes[plane].aux_surface.offset + image->planes[plane].aux_surface.isl.size_B)); */
525 assert(image->planes[plane].fast_clear_state_offset <
526 (image->planes[plane].offset + image->planes[plane].size));
527 }
528
529 return VK_SUCCESS;
530 }
531
532 static uint32_t
533 score_drm_format_mod(uint64_t modifier)
534 {
535 switch (modifier) {
536 case DRM_FORMAT_MOD_LINEAR: return 1;
537 case I915_FORMAT_MOD_X_TILED: return 2;
538 case I915_FORMAT_MOD_Y_TILED: return 3;
539 case I915_FORMAT_MOD_Y_TILED_CCS: return 4;
540 default: unreachable("bad DRM format modifier");
541 }
542 }
543
544 static const struct isl_drm_modifier_info *
545 choose_drm_format_mod(const struct anv_physical_device *device,
546 uint32_t modifier_count, const uint64_t *modifiers)
547 {
548 uint64_t best_mod = UINT64_MAX;
549 uint32_t best_score = 0;
550
551 for (uint32_t i = 0; i < modifier_count; ++i) {
552 uint32_t score = score_drm_format_mod(modifiers[i]);
553 if (score > best_score) {
554 best_mod = modifiers[i];
555 best_score = score;
556 }
557 }
558
559 if (best_score > 0)
560 return isl_drm_modifier_get_info(best_mod);
561 else
562 return NULL;
563 }
564
565 VkResult
566 anv_image_create(VkDevice _device,
567 const struct anv_image_create_info *create_info,
568 const VkAllocationCallbacks* alloc,
569 VkImage *pImage)
570 {
571 ANV_FROM_HANDLE(anv_device, device, _device);
572 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
573 const struct isl_drm_modifier_info *isl_mod_info = NULL;
574 struct anv_image *image = NULL;
575 VkResult r;
576
577 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
578
579 const struct wsi_image_create_info *wsi_info =
580 vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
581 if (wsi_info && wsi_info->modifier_count > 0) {
582 isl_mod_info = choose_drm_format_mod(&device->instance->physicalDevice,
583 wsi_info->modifier_count,
584 wsi_info->modifiers);
585 assert(isl_mod_info);
586 }
587
588 anv_assert(pCreateInfo->mipLevels > 0);
589 anv_assert(pCreateInfo->arrayLayers > 0);
590 anv_assert(pCreateInfo->samples > 0);
591 anv_assert(pCreateInfo->extent.width > 0);
592 anv_assert(pCreateInfo->extent.height > 0);
593 anv_assert(pCreateInfo->extent.depth > 0);
594
595 image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
596 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
597 if (!image)
598 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
599
600 image->type = pCreateInfo->imageType;
601 image->extent = pCreateInfo->extent;
602 image->vk_format = pCreateInfo->format;
603 image->format = anv_get_format(pCreateInfo->format);
604 image->aspects = vk_format_aspects(image->vk_format);
605 image->levels = pCreateInfo->mipLevels;
606 image->array_size = pCreateInfo->arrayLayers;
607 image->samples = pCreateInfo->samples;
608 image->usage = pCreateInfo->usage;
609 image->create_flags = pCreateInfo->flags;
610 image->tiling = pCreateInfo->tiling;
611 image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
612 image->needs_set_tiling = wsi_info && wsi_info->scanout;
613 image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
614 DRM_FORMAT_MOD_INVALID;
615
616 if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
617 image->stencil_usage = pCreateInfo->usage;
618 const VkImageStencilUsageCreateInfoEXT *stencil_usage_info =
619 vk_find_struct_const(pCreateInfo->pNext,
620 IMAGE_STENCIL_USAGE_CREATE_INFO_EXT);
621 if (stencil_usage_info)
622 image->stencil_usage = stencil_usage_info->stencilUsage;
623 }
624
625 /* In case of external format, We don't know format yet,
626 * so skip the rest for now.
627 */
628 if (create_info->external_format) {
629 image->external_format = true;
630 *pImage = anv_image_to_handle(image);
631 return VK_SUCCESS;
632 }
633
634 const struct anv_format *format = anv_get_format(image->vk_format);
635 assert(format != NULL);
636
637 const isl_tiling_flags_t isl_tiling_flags =
638 choose_isl_tiling_flags(create_info, isl_mod_info,
639 image->needs_set_tiling);
640
641 image->n_planes = format->n_planes;
642
643 const VkImageFormatListCreateInfoKHR *fmt_list =
644 vk_find_struct_const(pCreateInfo->pNext,
645 IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
646
647 image->ccs_e_compatible =
648 all_formats_ccs_e_compatible(&device->info, fmt_list, image);
649
650 uint32_t b;
651 for_each_bit(b, image->aspects) {
652 r = make_surface(device, image, create_info->stride, isl_tiling_flags,
653 create_info->isl_extra_usage_flags, (1 << b));
654 if (r != VK_SUCCESS)
655 goto fail;
656 }
657
658 *pImage = anv_image_to_handle(image);
659
660 return VK_SUCCESS;
661
662 fail:
663 if (image)
664 vk_free2(&device->alloc, alloc, image);
665
666 return r;
667 }
668
669 static struct anv_image *
670 anv_swapchain_get_image(VkSwapchainKHR swapchain,
671 uint32_t index)
672 {
673 uint32_t n_images = index + 1;
674 VkImage *images = malloc(sizeof(*images) * n_images);
675 VkResult result = wsi_common_get_images(swapchain, &n_images, images);
676
677 if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
678 free(images);
679 return NULL;
680 }
681
682 ANV_FROM_HANDLE(anv_image, image, images[index]);
683 free(images);
684
685 return image;
686 }
687
688 static VkResult
689 anv_image_from_swapchain(VkDevice device,
690 const VkImageCreateInfo *pCreateInfo,
691 const VkImageSwapchainCreateInfoKHR *swapchain_info,
692 const VkAllocationCallbacks *pAllocator,
693 VkImage *pImage)
694 {
695 struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0);
696 assert(swapchain_image);
697
698 assert(swapchain_image->type == pCreateInfo->imageType);
699 assert(swapchain_image->vk_format == pCreateInfo->format);
700 assert(swapchain_image->extent.width == pCreateInfo->extent.width);
701 assert(swapchain_image->extent.height == pCreateInfo->extent.height);
702 assert(swapchain_image->extent.depth == pCreateInfo->extent.depth);
703 assert(swapchain_image->array_size == pCreateInfo->arrayLayers);
704 /* Color attachment is added by the wsi code. */
705 assert(swapchain_image->usage == (pCreateInfo->usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
706
707 VkImageCreateInfo local_create_info;
708 local_create_info = *pCreateInfo;
709 local_create_info.pNext = NULL;
710 /* The following parameters are implictly selected by the wsi code. */
711 local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
712 local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
713 local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
714
715 /* If the image has a particular modifier, specify that modifier. */
716 struct wsi_image_create_info local_wsi_info = {
717 .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
718 .modifier_count = 1,
719 .modifiers = &swapchain_image->drm_format_mod,
720 };
721 if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)
722 __vk_append_struct(&local_create_info, &local_wsi_info);
723
724 return anv_image_create(device,
725 &(struct anv_image_create_info) {
726 .vk_info = &local_create_info,
727 .external_format = swapchain_image->external_format,
728 },
729 pAllocator,
730 pImage);
731 }
732
733 VkResult
734 anv_CreateImage(VkDevice device,
735 const VkImageCreateInfo *pCreateInfo,
736 const VkAllocationCallbacks *pAllocator,
737 VkImage *pImage)
738 {
739 const struct VkExternalMemoryImageCreateInfo *create_info =
740 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
741
742 if (create_info && (create_info->handleTypes &
743 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))
744 return anv_image_from_external(device, pCreateInfo, create_info,
745 pAllocator, pImage);
746
747 bool use_external_format = false;
748 const struct VkExternalFormatANDROID *ext_format =
749 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
750
751 /* "If externalFormat is zero, the effect is as if the
752 * VkExternalFormatANDROID structure was not present. Otherwise, the image
753 * will have the specified external format."
754 */
755 if (ext_format && ext_format->externalFormat != 0)
756 use_external_format = true;
757
758 const VkNativeBufferANDROID *gralloc_info =
759 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
760 if (gralloc_info)
761 return anv_image_from_gralloc(device, pCreateInfo, gralloc_info,
762 pAllocator, pImage);
763
764 const VkImageSwapchainCreateInfoKHR *swapchain_info =
765 vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
766 if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
767 return anv_image_from_swapchain(device, pCreateInfo, swapchain_info,
768 pAllocator, pImage);
769
770 return anv_image_create(device,
771 &(struct anv_image_create_info) {
772 .vk_info = pCreateInfo,
773 .external_format = use_external_format,
774 },
775 pAllocator,
776 pImage);
777 }
778
779 void
780 anv_DestroyImage(VkDevice _device, VkImage _image,
781 const VkAllocationCallbacks *pAllocator)
782 {
783 ANV_FROM_HANDLE(anv_device, device, _device);
784 ANV_FROM_HANDLE(anv_image, image, _image);
785
786 if (!image)
787 return;
788
789 for (uint32_t p = 0; p < image->n_planes; ++p) {
790 if (anv_image_plane_uses_aux_map(device, image, p) &&
791 image->planes[p].address.bo) {
792 gen_aux_map_unmap_range(device->aux_map_ctx,
793 image->planes[p].aux_map_surface_address,
794 image->planes[p].surface.isl.size_B);
795 }
796 if (image->planes[p].bo_is_owned) {
797 assert(image->planes[p].address.bo != NULL);
798 anv_bo_cache_release(device, &device->bo_cache,
799 image->planes[p].address.bo);
800 }
801 }
802
803 vk_free2(&device->alloc, pAllocator, image);
804 }
805
806 static void anv_image_bind_memory_plane(struct anv_device *device,
807 struct anv_image *image,
808 uint32_t plane,
809 struct anv_device_memory *memory,
810 uint32_t memory_offset)
811 {
812 assert(!image->planes[plane].bo_is_owned);
813
814 if (!memory) {
815 if (anv_image_plane_uses_aux_map(device, image, plane) &&
816 image->planes[plane].address.bo) {
817 gen_aux_map_unmap_range(device->aux_map_ctx,
818 image->planes[plane].aux_map_surface_address,
819 image->planes[plane].surface.isl.size_B);
820 }
821 image->planes[plane].address = ANV_NULL_ADDRESS;
822 return;
823 }
824
825 image->planes[plane].address = (struct anv_address) {
826 .bo = memory->bo,
827 .offset = memory_offset,
828 };
829
830 if (anv_image_plane_uses_aux_map(device, image, plane)) {
831 image->planes[plane].aux_map_surface_address =
832 anv_address_physical(
833 anv_address_add(image->planes[plane].address,
834 image->planes[plane].surface.offset));
835
836 gen_aux_map_add_image(device->aux_map_ctx,
837 &image->planes[plane].surface.isl,
838 image->planes[plane].aux_map_surface_address,
839 anv_address_physical(
840 anv_address_add(image->planes[plane].address,
841 image->planes[plane].aux_surface.offset)));
842 }
843 }
844
845 /* We are binding AHardwareBuffer. Get a description, resolve the
846 * format and prepare anv_image properly.
847 */
848 static void
849 resolve_ahw_image(struct anv_device *device,
850 struct anv_image *image,
851 struct anv_device_memory *mem)
852 {
853 #if defined(ANDROID) && ANDROID_API_LEVEL >= 26
854 assert(mem->ahw);
855 AHardwareBuffer_Desc desc;
856 AHardwareBuffer_describe(mem->ahw, &desc);
857
858 /* Check tiling. */
859 int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);
860 VkImageTiling vk_tiling;
861 isl_tiling_flags_t isl_tiling_flags = 0;
862
863 switch (i915_tiling) {
864 case I915_TILING_NONE:
865 vk_tiling = VK_IMAGE_TILING_LINEAR;
866 isl_tiling_flags = ISL_TILING_LINEAR_BIT;
867 break;
868 case I915_TILING_X:
869 vk_tiling = VK_IMAGE_TILING_OPTIMAL;
870 isl_tiling_flags = ISL_TILING_X_BIT;
871 break;
872 case I915_TILING_Y:
873 vk_tiling = VK_IMAGE_TILING_OPTIMAL;
874 isl_tiling_flags = ISL_TILING_Y0_BIT;
875 break;
876 case -1:
877 default:
878 unreachable("Invalid tiling flags.");
879 }
880
881 assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||
882 vk_tiling == VK_IMAGE_TILING_OPTIMAL);
883
884 /* Check format. */
885 VkFormat vk_format = vk_format_from_android(desc.format, desc.usage);
886 enum isl_format isl_fmt = anv_get_isl_format(&device->info,
887 vk_format,
888 VK_IMAGE_ASPECT_COLOR_BIT,
889 vk_tiling);
890 assert(isl_fmt != ISL_FORMAT_UNSUPPORTED);
891
892 /* Handle RGB(X)->RGBA fallback. */
893 switch (desc.format) {
894 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
895 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
896 if (isl_format_is_rgb(isl_fmt))
897 isl_fmt = isl_format_rgb_to_rgba(isl_fmt);
898 break;
899 }
900
901 /* Now we are able to fill anv_image fields properly and create
902 * isl_surface for it.
903 */
904 image->vk_format = vk_format;
905 image->format = anv_get_format(vk_format);
906 image->aspects = vk_format_aspects(image->vk_format);
907 image->n_planes = image->format->n_planes;
908 image->ccs_e_compatible = false;
909
910 uint32_t stride = desc.stride *
911 (isl_format_get_layout(isl_fmt)->bpb / 8);
912
913 uint32_t b;
914 for_each_bit(b, image->aspects) {
915 VkResult r = make_surface(device, image, stride, isl_tiling_flags,
916 ISL_SURF_USAGE_DISABLE_AUX_BIT, (1 << b));
917 assert(r == VK_SUCCESS);
918 }
919 #endif
920 }
921
922 VkResult anv_BindImageMemory(
923 VkDevice _device,
924 VkImage _image,
925 VkDeviceMemory _memory,
926 VkDeviceSize memoryOffset)
927 {
928 ANV_FROM_HANDLE(anv_device, device, _device);
929 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
930 ANV_FROM_HANDLE(anv_image, image, _image);
931
932 if (mem->ahw)
933 resolve_ahw_image(device, image, mem);
934
935 uint32_t aspect_bit;
936 anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) {
937 uint32_t plane =
938 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
939 anv_image_bind_memory_plane(device, image, plane, mem, memoryOffset);
940 }
941
942 return VK_SUCCESS;
943 }
944
945 VkResult anv_BindImageMemory2(
946 VkDevice _device,
947 uint32_t bindInfoCount,
948 const VkBindImageMemoryInfo* pBindInfos)
949 {
950 ANV_FROM_HANDLE(anv_device, device, _device);
951
952 for (uint32_t i = 0; i < bindInfoCount; i++) {
953 const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
954 ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory);
955 ANV_FROM_HANDLE(anv_image, image, bind_info->image);
956
957 /* Resolve will alter the image's aspects, do this first. */
958 if (mem && mem->ahw)
959 resolve_ahw_image(device, image, mem);
960
961 VkImageAspectFlags aspects = image->aspects;
962 vk_foreach_struct_const(s, bind_info->pNext) {
963 switch (s->sType) {
964 case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: {
965 const VkBindImagePlaneMemoryInfo *plane_info =
966 (const VkBindImagePlaneMemoryInfo *) s;
967
968 aspects = plane_info->planeAspect;
969 break;
970 }
971 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
972 const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
973 (const VkBindImageMemorySwapchainInfoKHR *) s;
974 struct anv_image *swapchain_image =
975 anv_swapchain_get_image(swapchain_info->swapchain,
976 swapchain_info->imageIndex);
977 assert(swapchain_image);
978 assert(image->aspects == swapchain_image->aspects);
979 assert(mem == NULL);
980
981 uint32_t aspect_bit;
982 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) {
983 uint32_t plane =
984 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
985 struct anv_device_memory mem = {
986 .bo = swapchain_image->planes[plane].address.bo,
987 };
988 anv_image_bind_memory_plane(device, image, plane,
989 &mem, bind_info->memoryOffset);
990 }
991 break;
992 }
993 default:
994 anv_debug_ignored_stype(s->sType);
995 break;
996 }
997 }
998
999 /* VkBindImageMemorySwapchainInfoKHR requires memory to be
1000 * VK_NULL_HANDLE. In such case, just carry one with the next bind
1001 * item.
1002 */
1003 if (!mem)
1004 continue;
1005
1006 uint32_t aspect_bit;
1007 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) {
1008 uint32_t plane =
1009 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
1010 anv_image_bind_memory_plane(device, image, plane,
1011 mem, bind_info->memoryOffset);
1012 }
1013 }
1014
1015 return VK_SUCCESS;
1016 }
1017
1018 void anv_GetImageSubresourceLayout(
1019 VkDevice device,
1020 VkImage _image,
1021 const VkImageSubresource* subresource,
1022 VkSubresourceLayout* layout)
1023 {
1024 ANV_FROM_HANDLE(anv_image, image, _image);
1025
1026 const struct anv_surface *surface;
1027 if (subresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT &&
1028 image->drm_format_mod != DRM_FORMAT_MOD_INVALID &&
1029 isl_drm_modifier_has_aux(image->drm_format_mod))
1030 surface = &image->planes[0].aux_surface;
1031 else
1032 surface = get_surface(image, subresource->aspectMask);
1033
1034 assert(__builtin_popcount(subresource->aspectMask) == 1);
1035
1036 layout->offset = surface->offset;
1037 layout->rowPitch = surface->isl.row_pitch_B;
1038 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
1039 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
1040
1041 if (subresource->mipLevel > 0 || subresource->arrayLayer > 0) {
1042 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1043
1044 uint32_t offset_B;
1045 isl_surf_get_image_offset_B_tile_sa(&surface->isl,
1046 subresource->mipLevel,
1047 subresource->arrayLayer,
1048 0 /* logical_z_offset_px */,
1049 &offset_B, NULL, NULL);
1050 layout->offset += offset_B;
1051 layout->size = layout->rowPitch * anv_minify(image->extent.height,
1052 subresource->mipLevel);
1053 } else {
1054 layout->size = surface->isl.size_B;
1055 }
1056 }
1057
1058 /**
1059 * This function determines the optimal buffer to use for a given
1060 * VkImageLayout and other pieces of information needed to make that
1061 * determination. This does not determine the optimal buffer to use
1062 * during a resolve operation.
1063 *
1064 * @param devinfo The device information of the Intel GPU.
1065 * @param image The image that may contain a collection of buffers.
1066 * @param aspect The aspect of the image to be accessed.
1067 * @param layout The current layout of the image aspect(s).
1068 *
1069 * @return The primary buffer that should be used for the given layout.
1070 */
1071 enum isl_aux_usage
1072 anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
1073 const struct anv_image * const image,
1074 const VkImageAspectFlagBits aspect,
1075 const VkImageLayout layout)
1076 {
1077 /* Validate the inputs. */
1078
1079 /* The devinfo is needed as the optimal buffer varies across generations. */
1080 assert(devinfo != NULL);
1081
1082 /* The layout of a NULL image is not properly defined. */
1083 assert(image != NULL);
1084
1085 /* The aspect must be exactly one of the image aspects. */
1086 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));
1087
1088 /* Determine the optimal buffer. */
1089
1090 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1091
1092 /* If there is no auxiliary surface allocated, we must use the one and only
1093 * main buffer.
1094 */
1095 if (image->planes[plane].aux_surface.isl.size_B == 0)
1096 return ISL_AUX_USAGE_NONE;
1097
1098 /* All images that use an auxiliary surface are required to be tiled. */
1099 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
1100
1101 /* Stencil has no aux */
1102 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
1103
1104 switch (layout) {
1105
1106 /* Invalid Layouts */
1107 case VK_IMAGE_LAYOUT_RANGE_SIZE:
1108 case VK_IMAGE_LAYOUT_MAX_ENUM:
1109 unreachable("Invalid image layout.");
1110
1111 /* Undefined layouts
1112 *
1113 * The pre-initialized layout is equivalent to the undefined layout for
1114 * optimally-tiled images. We can only do color compression (CCS or HiZ)
1115 * on tiled images.
1116 */
1117 case VK_IMAGE_LAYOUT_UNDEFINED:
1118 case VK_IMAGE_LAYOUT_PREINITIALIZED:
1119 return ISL_AUX_USAGE_NONE;
1120
1121
1122 /* Transfer Layouts
1123 */
1124 case VK_IMAGE_LAYOUT_GENERAL:
1125 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
1126 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
1127 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1128 /* This buffer could be a depth buffer used in a transfer operation.
1129 * BLORP currently doesn't use HiZ for transfer operations so we must
1130 * use the main buffer for this layout. TODO: Enable HiZ in BLORP.
1131 */
1132 assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_HIZ);
1133 return ISL_AUX_USAGE_NONE;
1134 } else {
1135 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1136 return image->planes[plane].aux_usage;
1137 }
1138
1139
1140 /* Sampling Layouts */
1141 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
1142 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
1143 assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1144 /* Fall-through */
1145 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
1146 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1147 if (anv_can_sample_with_hiz(devinfo, image))
1148 return ISL_AUX_USAGE_HIZ;
1149 else
1150 return ISL_AUX_USAGE_NONE;
1151 } else {
1152 return image->planes[plane].aux_usage;
1153 }
1154
1155
1156 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
1157 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1158
1159 /* When handing the image off to the presentation engine, we need to
1160 * ensure that things are properly resolved. For images with no
1161 * modifier, we assume that they follow the old rules and always need
1162 * a full resolve because the PE doesn't understand any form of
1163 * compression. For images with modifiers, we use the aux usage from
1164 * the modifier.
1165 */
1166 const struct isl_drm_modifier_info *mod_info =
1167 isl_drm_modifier_get_info(image->drm_format_mod);
1168 return mod_info ? mod_info->aux_usage : ISL_AUX_USAGE_NONE;
1169 }
1170
1171
1172 /* Rendering Layouts */
1173 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
1174 assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1175 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) {
1176 assert(image->samples == 1);
1177 return ISL_AUX_USAGE_CCS_D;
1178 } else {
1179 assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_CCS_D);
1180 return image->planes[plane].aux_usage;
1181 }
1182
1183 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
1184 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
1185 assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
1186 return ISL_AUX_USAGE_HIZ;
1187
1188 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
1189 unreachable("VK_KHR_shared_presentable_image is unsupported");
1190
1191 case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
1192 unreachable("VK_EXT_fragment_density_map is unsupported");
1193
1194 case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
1195 unreachable("VK_NV_shading_rate_image is unsupported");
1196 }
1197
1198 /* If the layout isn't recognized in the exhaustive switch above, the
1199 * VkImageLayout value is not defined in vulkan.h.
1200 */
1201 unreachable("layout is not a VkImageLayout enumeration member.");
1202 }
1203
1204 /**
1205 * This function returns the level of unresolved fast-clear support of the
1206 * given image in the given VkImageLayout.
1207 *
1208 * @param devinfo The device information of the Intel GPU.
1209 * @param image The image that may contain a collection of buffers.
1210 * @param aspect The aspect of the image to be accessed.
1211 * @param layout The current layout of the image aspect(s).
1212 */
1213 enum anv_fast_clear_type
1214 anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
1215 const struct anv_image * const image,
1216 const VkImageAspectFlagBits aspect,
1217 const VkImageLayout layout)
1218 {
1219 if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
1220 return ANV_FAST_CLEAR_NONE;
1221
1222 /* The aspect must be exactly one of the image aspects. */
1223 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));
1224
1225 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1226
1227 /* If there is no auxiliary surface allocated, there are no fast-clears */
1228 if (image->planes[plane].aux_surface.isl.size_B == 0)
1229 return ANV_FAST_CLEAR_NONE;
1230
1231 /* All images that use an auxiliary surface are required to be tiled. */
1232 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
1233
1234 /* Stencil has no aux */
1235 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
1236
1237 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1238 /* For depth images (with HiZ), the layout supports fast-clears if and
1239 * only if it supports HiZ. However, we only support fast-clears to the
1240 * default depth value.
1241 */
1242 enum isl_aux_usage aux_usage =
1243 anv_layout_to_aux_usage(devinfo, image, aspect, layout);
1244 return aux_usage == ISL_AUX_USAGE_HIZ ?
1245 ANV_FAST_CLEAR_DEFAULT_VALUE : ANV_FAST_CLEAR_NONE;
1246 }
1247
1248 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1249
1250 /* We don't support MSAA fast-clears on Ivybridge or Bay Trail because they
1251 * lack the MI ALU which we need to determine the predicates.
1252 */
1253 if (devinfo->gen == 7 && !devinfo->is_haswell && image->samples > 1)
1254 return ANV_FAST_CLEAR_NONE;
1255
1256 switch (layout) {
1257 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
1258 return ANV_FAST_CLEAR_ANY;
1259
1260 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
1261 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1262 #ifndef NDEBUG
1263 /* We do not yet support any modifiers which support clear color so we
1264 * just always return NONE. One day, this will change.
1265 */
1266 const struct isl_drm_modifier_info *mod_info =
1267 isl_drm_modifier_get_info(image->drm_format_mod);
1268 assert(!mod_info || !mod_info->supports_clear_color);
1269 #endif
1270 return ANV_FAST_CLEAR_NONE;
1271 }
1272
1273 default:
1274 /* If the image has MCS or CCS_E enabled all the time then we can use
1275 * fast-clear as long as the clear color is the default value of zero
1276 * since this is the default value we program into every surface state
1277 * used for texturing.
1278 */
1279 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS ||
1280 image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E)
1281 return ANV_FAST_CLEAR_DEFAULT_VALUE;
1282 else
1283 return ANV_FAST_CLEAR_NONE;
1284 }
1285 }
1286
1287
1288 static struct anv_state
1289 alloc_surface_state(struct anv_device *device)
1290 {
1291 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1292 }
1293
1294 static enum isl_channel_select
1295 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
1296 struct isl_swizzle format_swizzle)
1297 {
1298 if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
1299 swizzle = component;
1300
1301 switch (swizzle) {
1302 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO;
1303 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE;
1304 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r;
1305 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g;
1306 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b;
1307 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a;
1308 default:
1309 unreachable("Invalid swizzle");
1310 }
1311 }
1312
1313 void
1314 anv_image_fill_surface_state(struct anv_device *device,
1315 const struct anv_image *image,
1316 VkImageAspectFlagBits aspect,
1317 const struct isl_view *view_in,
1318 isl_surf_usage_flags_t view_usage,
1319 enum isl_aux_usage aux_usage,
1320 const union isl_color_value *clear_color,
1321 enum anv_image_view_state_flags flags,
1322 struct anv_surface_state *state_inout,
1323 struct brw_image_param *image_param_out)
1324 {
1325 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1326
1327 const struct anv_surface *surface = &image->planes[plane].surface,
1328 *aux_surface = &image->planes[plane].aux_surface;
1329
1330 struct isl_view view = *view_in;
1331 view.usage |= view_usage;
1332
1333 /* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a
1334 * compressed surface with a shadow surface, we use the shadow instead of
1335 * the primary surface. The shadow surface will be tiled, unlike the main
1336 * surface, so it should get significantly better performance.
1337 */
1338 if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
1339 isl_format_is_compressed(view.format) &&
1340 (flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) {
1341 assert(isl_format_is_compressed(surface->isl.format));
1342 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1343 assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR);
1344 surface = &image->planes[plane].shadow_surface;
1345 }
1346
1347 /* For texturing from stencil on gen7, we have to sample from a shadow
1348 * surface because we don't support W-tiling in the sampler.
1349 */
1350 if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
1351 aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
1352 assert(device->info.gen == 7);
1353 assert(view_usage & ISL_SURF_USAGE_TEXTURE_BIT);
1354 surface = &image->planes[plane].shadow_surface;
1355 }
1356
1357 if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)
1358 view.swizzle = anv_swizzle_for_render(view.swizzle);
1359
1360 /* On Ivy Bridge and Bay Trail we do the swizzle in the shader */
1361 if (device->info.gen == 7 && !device->info.is_haswell)
1362 view.swizzle = ISL_SWIZZLE_IDENTITY;
1363
1364 /* If this is a HiZ buffer we can sample from with a programmable clear
1365 * value (SKL+), define the clear value to the optimal constant.
1366 */
1367 union isl_color_value default_clear_color = { .u32 = { 0, } };
1368 if (device->info.gen >= 9 && aux_usage == ISL_AUX_USAGE_HIZ)
1369 default_clear_color.f32[0] = ANV_HZ_FC_VAL;
1370 if (!clear_color)
1371 clear_color = &default_clear_color;
1372
1373 const struct anv_address address =
1374 anv_address_add(image->planes[plane].address, surface->offset);
1375
1376 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
1377 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) &&
1378 !isl_has_matching_typed_storage_image_format(&device->info,
1379 view.format)) {
1380 /* In this case, we are a writeable storage buffer which needs to be
1381 * lowered to linear. All tiling and offset calculations will be done in
1382 * the shader.
1383 */
1384 assert(aux_usage == ISL_AUX_USAGE_NONE);
1385 isl_buffer_fill_state(&device->isl_dev, state_inout->state.map,
1386 .address = anv_address_physical(address),
1387 .size_B = surface->isl.size_B,
1388 .format = ISL_FORMAT_RAW,
1389 .swizzle = ISL_SWIZZLE_IDENTITY,
1390 .stride_B = 1,
1391 .mocs = anv_mocs_for_bo(device, address.bo));
1392 state_inout->address = address,
1393 state_inout->aux_address = ANV_NULL_ADDRESS;
1394 state_inout->clear_address = ANV_NULL_ADDRESS;
1395 } else {
1396 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
1397 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) {
1398 /* Typed surface reads support a very limited subset of the shader
1399 * image formats. Translate it into the closest format the hardware
1400 * supports.
1401 */
1402 assert(aux_usage == ISL_AUX_USAGE_NONE);
1403 view.format = isl_lower_storage_image_format(&device->info,
1404 view.format);
1405 }
1406
1407 const struct isl_surf *isl_surf = &surface->isl;
1408
1409 struct isl_surf tmp_surf;
1410 uint32_t offset_B = 0, tile_x_sa = 0, tile_y_sa = 0;
1411 if (isl_format_is_compressed(surface->isl.format) &&
1412 !isl_format_is_compressed(view.format)) {
1413 /* We're creating an uncompressed view of a compressed surface. This
1414 * is allowed but only for a single level/layer.
1415 */
1416 assert(surface->isl.samples == 1);
1417 assert(view.levels == 1);
1418 assert(view.array_len == 1);
1419
1420 isl_surf_get_image_surf(&device->isl_dev, isl_surf,
1421 view.base_level,
1422 surface->isl.dim == ISL_SURF_DIM_3D ?
1423 0 : view.base_array_layer,
1424 surface->isl.dim == ISL_SURF_DIM_3D ?
1425 view.base_array_layer : 0,
1426 &tmp_surf,
1427 &offset_B, &tile_x_sa, &tile_y_sa);
1428
1429 /* The newly created image represents the one subimage we're
1430 * referencing with this view so it only has one array slice and
1431 * miplevel.
1432 */
1433 view.base_array_layer = 0;
1434 view.base_level = 0;
1435
1436 /* We're making an uncompressed view here. The image dimensions need
1437 * to be scaled down by the block size.
1438 */
1439 const struct isl_format_layout *fmtl =
1440 isl_format_get_layout(surface->isl.format);
1441 tmp_surf.logical_level0_px =
1442 isl_surf_get_logical_level0_el(&tmp_surf);
1443 tmp_surf.phys_level0_sa = isl_surf_get_phys_level0_el(&tmp_surf);
1444 tmp_surf.format = view.format;
1445 tile_x_sa /= fmtl->bw;
1446 tile_y_sa /= fmtl->bh;
1447
1448 isl_surf = &tmp_surf;
1449
1450 if (device->info.gen <= 8) {
1451 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1452 assert(tile_x_sa == 0);
1453 assert(tile_y_sa == 0);
1454 }
1455 }
1456
1457 state_inout->address = anv_address_add(address, offset_B);
1458
1459 struct anv_address aux_address = ANV_NULL_ADDRESS;
1460 if (aux_usage != ISL_AUX_USAGE_NONE) {
1461 aux_address = anv_address_add(image->planes[plane].address,
1462 aux_surface->offset);
1463 }
1464 state_inout->aux_address = aux_address;
1465
1466 struct anv_address clear_address = ANV_NULL_ADDRESS;
1467 if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE) {
1468 if (aux_usage == ISL_AUX_USAGE_HIZ) {
1469 clear_address = (struct anv_address) {
1470 .bo = &device->hiz_clear_bo,
1471 .offset = 0,
1472 };
1473 } else {
1474 clear_address = anv_image_get_clear_color_addr(device, image, aspect);
1475 }
1476 }
1477 state_inout->clear_address = clear_address;
1478
1479 isl_surf_fill_state(&device->isl_dev, state_inout->state.map,
1480 .surf = isl_surf,
1481 .view = &view,
1482 .address = anv_address_physical(state_inout->address),
1483 .clear_color = *clear_color,
1484 .aux_surf = &aux_surface->isl,
1485 .aux_usage = aux_usage,
1486 .aux_address = anv_address_physical(aux_address),
1487 .clear_address = anv_address_physical(clear_address),
1488 .use_clear_address = !anv_address_is_null(clear_address),
1489 .mocs = anv_mocs_for_bo(device,
1490 state_inout->address.bo),
1491 .x_offset_sa = tile_x_sa,
1492 .y_offset_sa = tile_y_sa);
1493
1494 /* With the exception of gen8, the bottom 12 bits of the MCS base address
1495 * are used to store other information. This should be ok, however,
1496 * because the surface buffer addresses are always 4K page aligned.
1497 */
1498 uint32_t *aux_addr_dw = state_inout->state.map +
1499 device->isl_dev.ss.aux_addr_offset;
1500 assert((aux_address.offset & 0xfff) == 0);
1501 state_inout->aux_address.offset |= *aux_addr_dw & 0xfff;
1502
1503 if (device->info.gen >= 10 && clear_address.bo) {
1504 uint32_t *clear_addr_dw = state_inout->state.map +
1505 device->isl_dev.ss.clear_color_state_offset;
1506 assert((clear_address.offset & 0x3f) == 0);
1507 state_inout->clear_address.offset |= *clear_addr_dw & 0x3f;
1508 }
1509 }
1510
1511 if (image_param_out) {
1512 assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT);
1513 isl_surf_fill_image_param(&device->isl_dev, image_param_out,
1514 &surface->isl, &view);
1515 }
1516 }
1517
1518 static VkImageAspectFlags
1519 remap_aspect_flags(VkImageAspectFlags view_aspects)
1520 {
1521 if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {
1522 if (util_bitcount(view_aspects) == 1)
1523 return VK_IMAGE_ASPECT_COLOR_BIT;
1524
1525 VkImageAspectFlags color_aspects = 0;
1526 for (uint32_t i = 0; i < util_bitcount(view_aspects); i++)
1527 color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT << i;
1528 return color_aspects;
1529 }
1530 /* No special remapping needed for depth & stencil aspects. */
1531 return view_aspects;
1532 }
1533
1534 static uint32_t
1535 anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask)
1536 {
1537 uint32_t planes = 0;
1538
1539 if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT |
1540 VK_IMAGE_ASPECT_DEPTH_BIT |
1541 VK_IMAGE_ASPECT_STENCIL_BIT |
1542 VK_IMAGE_ASPECT_PLANE_0_BIT))
1543 planes++;
1544 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT)
1545 planes++;
1546 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT)
1547 planes++;
1548
1549 if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 &&
1550 (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)
1551 planes++;
1552
1553 return planes;
1554 }
1555
1556 VkResult
1557 anv_CreateImageView(VkDevice _device,
1558 const VkImageViewCreateInfo *pCreateInfo,
1559 const VkAllocationCallbacks *pAllocator,
1560 VkImageView *pView)
1561 {
1562 ANV_FROM_HANDLE(anv_device, device, _device);
1563 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
1564 struct anv_image_view *iview;
1565
1566 iview = vk_zalloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
1567 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1568 if (iview == NULL)
1569 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1570
1571 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
1572
1573 assert(range->layerCount > 0);
1574 assert(range->baseMipLevel < image->levels);
1575
1576 /* Check if a conversion info was passed. */
1577 const struct anv_format *conv_format = NULL;
1578 const struct VkSamplerYcbcrConversionInfo *conv_info =
1579 vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);
1580
1581 /* If image has an external format, the pNext chain must contain an instance of
1582 * VKSamplerYcbcrConversionInfo with a conversion object created with the same
1583 * external format as image."
1584 */
1585 assert(!image->external_format || conv_info);
1586
1587 if (conv_info) {
1588 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion);
1589 conv_format = conversion->format;
1590 }
1591
1592 VkImageUsageFlags image_usage = 0;
1593 if (range->aspectMask & ~VK_IMAGE_ASPECT_STENCIL_BIT)
1594 image_usage |= image->usage;
1595 if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
1596 image_usage |= image->stencil_usage;
1597
1598 const VkImageViewUsageCreateInfo *usage_info =
1599 vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO);
1600 VkImageUsageFlags view_usage = usage_info ? usage_info->usage : image_usage;
1601
1602 /* View usage should be a subset of image usage */
1603 assert((view_usage & ~image_usage) == 0);
1604 assert(view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
1605 VK_IMAGE_USAGE_STORAGE_BIT |
1606 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
1607 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
1608 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
1609
1610 switch (image->type) {
1611 default:
1612 unreachable("bad VkImageType");
1613 case VK_IMAGE_TYPE_1D:
1614 case VK_IMAGE_TYPE_2D:
1615 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);
1616 break;
1617 case VK_IMAGE_TYPE_3D:
1618 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1
1619 <= anv_minify(image->extent.depth, range->baseMipLevel));
1620 break;
1621 }
1622
1623 /* First expand aspects to the image's ones (for example
1624 * VK_IMAGE_ASPECT_COLOR_BIT will be converted to
1625 * VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT |
1626 * VK_IMAGE_ASPECT_PLANE_2_BIT for an image of format
1627 * VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.
1628 */
1629 VkImageAspectFlags expanded_aspects =
1630 anv_image_expand_aspects(image, range->aspectMask);
1631
1632 iview->image = image;
1633
1634 /* Remap the expanded aspects for the image view. For example if only
1635 * VK_IMAGE_ASPECT_PLANE_1_BIT was given in range->aspectMask, we will
1636 * convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of
1637 * the image view, it only has a single plane.
1638 */
1639 iview->aspect_mask = remap_aspect_flags(expanded_aspects);
1640 iview->n_planes = anv_image_aspect_get_planes(iview->aspect_mask);
1641 iview->vk_format = pCreateInfo->format;
1642
1643 /* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */
1644 assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED);
1645
1646 /* Format is undefined, this can happen when using external formats. Set
1647 * view format from the passed conversion info.
1648 */
1649 if (iview->vk_format == VK_FORMAT_UNDEFINED && conv_format)
1650 iview->vk_format = conv_format->vk_format;
1651
1652 iview->extent = (VkExtent3D) {
1653 .width = anv_minify(image->extent.width , range->baseMipLevel),
1654 .height = anv_minify(image->extent.height, range->baseMipLevel),
1655 .depth = anv_minify(image->extent.depth , range->baseMipLevel),
1656 };
1657
1658 /* Now go through the underlying image selected planes (computed in
1659 * expanded_aspects) and map them to planes in the image view.
1660 */
1661 uint32_t iaspect_bit, vplane = 0;
1662 anv_foreach_image_aspect_bit(iaspect_bit, image, expanded_aspects) {
1663 uint32_t iplane =
1664 anv_image_aspect_to_plane(image->aspects, 1UL << iaspect_bit);
1665 VkImageAspectFlags vplane_aspect =
1666 anv_plane_to_aspect(iview->aspect_mask, vplane);
1667 struct anv_format_plane format =
1668 anv_get_format_plane(&device->info, iview->vk_format,
1669 vplane_aspect, image->tiling);
1670
1671 iview->planes[vplane].image_plane = iplane;
1672
1673 iview->planes[vplane].isl = (struct isl_view) {
1674 .format = format.isl_format,
1675 .base_level = range->baseMipLevel,
1676 .levels = anv_get_levelCount(image, range),
1677 .base_array_layer = range->baseArrayLayer,
1678 .array_len = anv_get_layerCount(image, range),
1679 .swizzle = {
1680 .r = remap_swizzle(pCreateInfo->components.r,
1681 VK_COMPONENT_SWIZZLE_R, format.swizzle),
1682 .g = remap_swizzle(pCreateInfo->components.g,
1683 VK_COMPONENT_SWIZZLE_G, format.swizzle),
1684 .b = remap_swizzle(pCreateInfo->components.b,
1685 VK_COMPONENT_SWIZZLE_B, format.swizzle),
1686 .a = remap_swizzle(pCreateInfo->components.a,
1687 VK_COMPONENT_SWIZZLE_A, format.swizzle),
1688 },
1689 };
1690
1691 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
1692 iview->planes[vplane].isl.base_array_layer = 0;
1693 iview->planes[vplane].isl.array_len = iview->extent.depth;
1694 }
1695
1696 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1697 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
1698 iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT;
1699 } else {
1700 iview->planes[vplane].isl.usage = 0;
1701 }
1702
1703 if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
1704 (view_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
1705 !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
1706 iview->planes[vplane].optimal_sampler_surface_state.state = alloc_surface_state(device);
1707 iview->planes[vplane].general_sampler_surface_state.state = alloc_surface_state(device);
1708
1709 enum isl_aux_usage general_aux_usage =
1710 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,
1711 VK_IMAGE_LAYOUT_GENERAL);
1712 enum isl_aux_usage optimal_aux_usage =
1713 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,
1714 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1715
1716 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1717 &iview->planes[vplane].isl,
1718 ISL_SURF_USAGE_TEXTURE_BIT,
1719 optimal_aux_usage, NULL,
1720 ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL,
1721 &iview->planes[vplane].optimal_sampler_surface_state,
1722 NULL);
1723
1724 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1725 &iview->planes[vplane].isl,
1726 ISL_SURF_USAGE_TEXTURE_BIT,
1727 general_aux_usage, NULL,
1728 0,
1729 &iview->planes[vplane].general_sampler_surface_state,
1730 NULL);
1731 }
1732
1733 /* NOTE: This one needs to go last since it may stomp isl_view.format */
1734 if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1735 iview->planes[vplane].storage_surface_state.state = alloc_surface_state(device);
1736 iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device);
1737
1738 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1739 &iview->planes[vplane].isl,
1740 ISL_SURF_USAGE_STORAGE_BIT,
1741 ISL_AUX_USAGE_NONE, NULL,
1742 0,
1743 &iview->planes[vplane].storage_surface_state,
1744 &iview->planes[vplane].storage_image_param);
1745
1746 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1747 &iview->planes[vplane].isl,
1748 ISL_SURF_USAGE_STORAGE_BIT,
1749 ISL_AUX_USAGE_NONE, NULL,
1750 ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY,
1751 &iview->planes[vplane].writeonly_storage_surface_state,
1752 NULL);
1753 }
1754
1755 vplane++;
1756 }
1757
1758 *pView = anv_image_view_to_handle(iview);
1759
1760 return VK_SUCCESS;
1761 }
1762
1763 void
1764 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
1765 const VkAllocationCallbacks *pAllocator)
1766 {
1767 ANV_FROM_HANDLE(anv_device, device, _device);
1768 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
1769
1770 if (!iview)
1771 return;
1772
1773 for (uint32_t plane = 0; plane < iview->n_planes; plane++) {
1774 if (iview->planes[plane].optimal_sampler_surface_state.state.alloc_size > 0) {
1775 anv_state_pool_free(&device->surface_state_pool,
1776 iview->planes[plane].optimal_sampler_surface_state.state);
1777 }
1778
1779 if (iview->planes[plane].general_sampler_surface_state.state.alloc_size > 0) {
1780 anv_state_pool_free(&device->surface_state_pool,
1781 iview->planes[plane].general_sampler_surface_state.state);
1782 }
1783
1784 if (iview->planes[plane].storage_surface_state.state.alloc_size > 0) {
1785 anv_state_pool_free(&device->surface_state_pool,
1786 iview->planes[plane].storage_surface_state.state);
1787 }
1788
1789 if (iview->planes[plane].writeonly_storage_surface_state.state.alloc_size > 0) {
1790 anv_state_pool_free(&device->surface_state_pool,
1791 iview->planes[plane].writeonly_storage_surface_state.state);
1792 }
1793 }
1794
1795 vk_free2(&device->alloc, pAllocator, iview);
1796 }
1797
1798
1799 VkResult
1800 anv_CreateBufferView(VkDevice _device,
1801 const VkBufferViewCreateInfo *pCreateInfo,
1802 const VkAllocationCallbacks *pAllocator,
1803 VkBufferView *pView)
1804 {
1805 ANV_FROM_HANDLE(anv_device, device, _device);
1806 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
1807 struct anv_buffer_view *view;
1808
1809 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
1810 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1811 if (!view)
1812 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1813
1814 /* TODO: Handle the format swizzle? */
1815
1816 view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
1817 VK_IMAGE_ASPECT_COLOR_BIT,
1818 VK_IMAGE_TILING_LINEAR);
1819 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;
1820 view->range = anv_buffer_get_range(buffer, pCreateInfo->offset,
1821 pCreateInfo->range);
1822 view->range = align_down_npot_u32(view->range, format_bs);
1823
1824 view->address = anv_address_add(buffer->address, pCreateInfo->offset);
1825
1826 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
1827 view->surface_state = alloc_surface_state(device);
1828
1829 anv_fill_buffer_surface_state(device, view->surface_state,
1830 view->format,
1831 view->address, view->range, format_bs);
1832 } else {
1833 view->surface_state = (struct anv_state){ 0 };
1834 }
1835
1836 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
1837 view->storage_surface_state = alloc_surface_state(device);
1838 view->writeonly_storage_surface_state = alloc_surface_state(device);
1839
1840 enum isl_format storage_format =
1841 isl_has_matching_typed_storage_image_format(&device->info,
1842 view->format) ?
1843 isl_lower_storage_image_format(&device->info, view->format) :
1844 ISL_FORMAT_RAW;
1845
1846 anv_fill_buffer_surface_state(device, view->storage_surface_state,
1847 storage_format,
1848 view->address, view->range,
1849 (storage_format == ISL_FORMAT_RAW ? 1 :
1850 isl_format_get_layout(storage_format)->bpb / 8));
1851
1852 /* Write-only accesses should use the original format. */
1853 anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state,
1854 view->format,
1855 view->address, view->range,
1856 isl_format_get_layout(view->format)->bpb / 8);
1857
1858 isl_buffer_fill_image_param(&device->isl_dev,
1859 &view->storage_image_param,
1860 view->format, view->range);
1861 } else {
1862 view->storage_surface_state = (struct anv_state){ 0 };
1863 view->writeonly_storage_surface_state = (struct anv_state){ 0 };
1864 }
1865
1866 *pView = anv_buffer_view_to_handle(view);
1867
1868 return VK_SUCCESS;
1869 }
1870
1871 void
1872 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
1873 const VkAllocationCallbacks *pAllocator)
1874 {
1875 ANV_FROM_HANDLE(anv_device, device, _device);
1876 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
1877
1878 if (!view)
1879 return;
1880
1881 if (view->surface_state.alloc_size > 0)
1882 anv_state_pool_free(&device->surface_state_pool,
1883 view->surface_state);
1884
1885 if (view->storage_surface_state.alloc_size > 0)
1886 anv_state_pool_free(&device->surface_state_pool,
1887 view->storage_surface_state);
1888
1889 if (view->writeonly_storage_surface_state.alloc_size > 0)
1890 anv_state_pool_free(&device->surface_state_pool,
1891 view->writeonly_storage_surface_state);
1892
1893 vk_free2(&device->alloc, pAllocator, view);
1894 }
1895
1896 const struct anv_surface *
1897 anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
1898 VkImageAspectFlags aspect_mask)
1899 {
1900 VkImageAspectFlags sanitized_mask;
1901
1902 switch (aspect_mask) {
1903 case VK_IMAGE_ASPECT_COLOR_BIT:
1904 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1905 sanitized_mask = VK_IMAGE_ASPECT_COLOR_BIT;
1906 break;
1907 case VK_IMAGE_ASPECT_DEPTH_BIT:
1908 assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
1909 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
1910 break;
1911 case VK_IMAGE_ASPECT_STENCIL_BIT:
1912 assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
1913 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
1914 break;
1915 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
1916 /* FINISHME: The Vulkan spec (git a511ba2) requires support for
1917 * combined depth stencil formats. Specifically, it states:
1918 *
1919 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
1920 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
1921 *
1922 * Image views with both depth and stencil aspects are only valid for
1923 * render target attachments, in which case
1924 * cmd_buffer_emit_depth_stencil() will pick out both the depth and
1925 * stencil surfaces from the underlying surface.
1926 */
1927 if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1928 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
1929 } else {
1930 assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
1931 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
1932 }
1933 break;
1934 case VK_IMAGE_ASPECT_PLANE_0_BIT:
1935 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1936 sanitized_mask = VK_IMAGE_ASPECT_PLANE_0_BIT;
1937 break;
1938 case VK_IMAGE_ASPECT_PLANE_1_BIT:
1939 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1940 sanitized_mask = VK_IMAGE_ASPECT_PLANE_1_BIT;
1941 break;
1942 case VK_IMAGE_ASPECT_PLANE_2_BIT:
1943 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1944 sanitized_mask = VK_IMAGE_ASPECT_PLANE_2_BIT;
1945 break;
1946 default:
1947 unreachable("image does not have aspect");
1948 return NULL;
1949 }
1950
1951 uint32_t plane = anv_image_aspect_to_plane(image->aspects, sanitized_mask);
1952 return &image->planes[plane].surface;
1953 }