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