anv/image: Disable CCS_D on Gen12+
[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, 0);
455 if (ok) {
456
457 /* Disable CCS when it is not useful (i.e., when you can't render
458 * to the image with CCS enabled).
459 */
460 if (!isl_format_supports_rendering(&dev->info,
461 plane_format.isl_format)) {
462 /* While it may be technically possible to enable CCS for this
463 * image, we currently don't have things hooked up to get it
464 * working.
465 */
466 anv_perf_warn(dev->instance, image,
467 "This image format doesn't support rendering. "
468 "Not allocating an CCS buffer.");
469 image->planes[plane].aux_surface.isl.size_B = 0;
470 return VK_SUCCESS;
471 }
472
473 /* For images created without MUTABLE_FORMAT_BIT set, we know that
474 * they will always be used with the original format. In
475 * particular, they will always be used with a format that
476 * supports color compression. If it's never used as a storage
477 * image, then it will only be used through the sampler or the as
478 * a render target. This means that it's safe to just leave
479 * compression on at all times for these formats.
480 */
481 if (!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
482 image->ccs_e_compatible) {
483 image->planes[plane].aux_usage = ISL_AUX_USAGE_CCS_E;
484 } else if (dev->info.gen >= 12) {
485 anv_perf_warn(dev->instance, image,
486 "The CCS_D aux mode is not yet handled on "
487 "Gen12+. Not allocating a CCS buffer.");
488 image->planes[plane].aux_surface.isl.size_B = 0;
489 return VK_SUCCESS;
490 }
491
492 add_surface(image, &image->planes[plane].aux_surface, plane);
493 add_aux_state_tracking_buffer(image, plane, dev);
494 }
495 }
496 } else if ((aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) && image->samples > 1) {
497 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
498 assert(image->planes[plane].aux_surface.isl.size_B == 0);
499 ok = isl_surf_get_mcs_surf(&dev->isl_dev,
500 &image->planes[plane].surface.isl,
501 &image->planes[plane].aux_surface.isl);
502 if (ok) {
503 add_surface(image, &image->planes[plane].aux_surface, plane);
504 add_aux_state_tracking_buffer(image, plane, dev);
505 image->planes[plane].aux_usage = ISL_AUX_USAGE_MCS;
506 }
507 }
508
509 assert((image->planes[plane].offset + image->planes[plane].size) == image->size);
510
511 /* Upper bound of the last surface should be smaller than the plane's
512 * size.
513 */
514 assert((MAX2(image->planes[plane].surface.offset,
515 image->planes[plane].aux_surface.offset) +
516 (image->planes[plane].aux_surface.isl.size_B > 0 ?
517 image->planes[plane].aux_surface.isl.size_B :
518 image->planes[plane].surface.isl.size_B)) <=
519 (image->planes[plane].offset + image->planes[plane].size));
520
521 if (image->planes[plane].aux_surface.isl.size_B) {
522 /* assert(image->planes[plane].fast_clear_state_offset == */
523 /* (image->planes[plane].aux_surface.offset + image->planes[plane].aux_surface.isl.size_B)); */
524 assert(image->planes[plane].fast_clear_state_offset <
525 (image->planes[plane].offset + image->planes[plane].size));
526 }
527
528 return VK_SUCCESS;
529 }
530
531 static uint32_t
532 score_drm_format_mod(uint64_t modifier)
533 {
534 switch (modifier) {
535 case DRM_FORMAT_MOD_LINEAR: return 1;
536 case I915_FORMAT_MOD_X_TILED: return 2;
537 case I915_FORMAT_MOD_Y_TILED: return 3;
538 case I915_FORMAT_MOD_Y_TILED_CCS: return 4;
539 default: unreachable("bad DRM format modifier");
540 }
541 }
542
543 static const struct isl_drm_modifier_info *
544 choose_drm_format_mod(const struct anv_physical_device *device,
545 uint32_t modifier_count, const uint64_t *modifiers)
546 {
547 uint64_t best_mod = UINT64_MAX;
548 uint32_t best_score = 0;
549
550 for (uint32_t i = 0; i < modifier_count; ++i) {
551 uint32_t score = score_drm_format_mod(modifiers[i]);
552 if (score > best_score) {
553 best_mod = modifiers[i];
554 best_score = score;
555 }
556 }
557
558 if (best_score > 0)
559 return isl_drm_modifier_get_info(best_mod);
560 else
561 return NULL;
562 }
563
564 VkResult
565 anv_image_create(VkDevice _device,
566 const struct anv_image_create_info *create_info,
567 const VkAllocationCallbacks* alloc,
568 VkImage *pImage)
569 {
570 ANV_FROM_HANDLE(anv_device, device, _device);
571 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
572 const struct isl_drm_modifier_info *isl_mod_info = NULL;
573 struct anv_image *image = NULL;
574 VkResult r;
575
576 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
577
578 const struct wsi_image_create_info *wsi_info =
579 vk_find_struct_const(pCreateInfo->pNext, WSI_IMAGE_CREATE_INFO_MESA);
580 if (wsi_info && wsi_info->modifier_count > 0) {
581 isl_mod_info = choose_drm_format_mod(&device->instance->physicalDevice,
582 wsi_info->modifier_count,
583 wsi_info->modifiers);
584 assert(isl_mod_info);
585 }
586
587 anv_assert(pCreateInfo->mipLevels > 0);
588 anv_assert(pCreateInfo->arrayLayers > 0);
589 anv_assert(pCreateInfo->samples > 0);
590 anv_assert(pCreateInfo->extent.width > 0);
591 anv_assert(pCreateInfo->extent.height > 0);
592 anv_assert(pCreateInfo->extent.depth > 0);
593
594 image = vk_zalloc2(&device->alloc, alloc, sizeof(*image), 8,
595 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
596 if (!image)
597 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
598
599 image->type = pCreateInfo->imageType;
600 image->extent = pCreateInfo->extent;
601 image->vk_format = pCreateInfo->format;
602 image->format = anv_get_format(pCreateInfo->format);
603 image->aspects = vk_format_aspects(image->vk_format);
604 image->levels = pCreateInfo->mipLevels;
605 image->array_size = pCreateInfo->arrayLayers;
606 image->samples = pCreateInfo->samples;
607 image->usage = pCreateInfo->usage;
608 image->create_flags = pCreateInfo->flags;
609 image->tiling = pCreateInfo->tiling;
610 image->disjoint = pCreateInfo->flags & VK_IMAGE_CREATE_DISJOINT_BIT;
611 image->needs_set_tiling = wsi_info && wsi_info->scanout;
612 image->drm_format_mod = isl_mod_info ? isl_mod_info->modifier :
613 DRM_FORMAT_MOD_INVALID;
614
615 if (image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) {
616 image->stencil_usage = pCreateInfo->usage;
617 const VkImageStencilUsageCreateInfoEXT *stencil_usage_info =
618 vk_find_struct_const(pCreateInfo->pNext,
619 IMAGE_STENCIL_USAGE_CREATE_INFO_EXT);
620 if (stencil_usage_info)
621 image->stencil_usage = stencil_usage_info->stencilUsage;
622 }
623
624 /* In case of external format, We don't know format yet,
625 * so skip the rest for now.
626 */
627 if (create_info->external_format) {
628 image->external_format = true;
629 *pImage = anv_image_to_handle(image);
630 return VK_SUCCESS;
631 }
632
633 const struct anv_format *format = anv_get_format(image->vk_format);
634 assert(format != NULL);
635
636 const isl_tiling_flags_t isl_tiling_flags =
637 choose_isl_tiling_flags(create_info, isl_mod_info,
638 image->needs_set_tiling);
639
640 image->n_planes = format->n_planes;
641
642 const VkImageFormatListCreateInfoKHR *fmt_list =
643 vk_find_struct_const(pCreateInfo->pNext,
644 IMAGE_FORMAT_LIST_CREATE_INFO_KHR);
645
646 image->ccs_e_compatible =
647 all_formats_ccs_e_compatible(&device->info, fmt_list, image);
648
649 uint32_t b;
650 for_each_bit(b, image->aspects) {
651 r = make_surface(device, image, create_info->stride, isl_tiling_flags,
652 create_info->isl_extra_usage_flags, (1 << b));
653 if (r != VK_SUCCESS)
654 goto fail;
655 }
656
657 *pImage = anv_image_to_handle(image);
658
659 return VK_SUCCESS;
660
661 fail:
662 if (image)
663 vk_free2(&device->alloc, alloc, image);
664
665 return r;
666 }
667
668 static struct anv_image *
669 anv_swapchain_get_image(VkSwapchainKHR swapchain,
670 uint32_t index)
671 {
672 uint32_t n_images = index + 1;
673 VkImage *images = malloc(sizeof(*images) * n_images);
674 VkResult result = wsi_common_get_images(swapchain, &n_images, images);
675
676 if (result != VK_SUCCESS && result != VK_INCOMPLETE) {
677 free(images);
678 return NULL;
679 }
680
681 ANV_FROM_HANDLE(anv_image, image, images[index]);
682 free(images);
683
684 return image;
685 }
686
687 static VkResult
688 anv_image_from_swapchain(VkDevice device,
689 const VkImageCreateInfo *pCreateInfo,
690 const VkImageSwapchainCreateInfoKHR *swapchain_info,
691 const VkAllocationCallbacks *pAllocator,
692 VkImage *pImage)
693 {
694 struct anv_image *swapchain_image = anv_swapchain_get_image(swapchain_info->swapchain, 0);
695 assert(swapchain_image);
696
697 assert(swapchain_image->type == pCreateInfo->imageType);
698 assert(swapchain_image->vk_format == pCreateInfo->format);
699 assert(swapchain_image->extent.width == pCreateInfo->extent.width);
700 assert(swapchain_image->extent.height == pCreateInfo->extent.height);
701 assert(swapchain_image->extent.depth == pCreateInfo->extent.depth);
702 assert(swapchain_image->array_size == pCreateInfo->arrayLayers);
703 /* Color attachment is added by the wsi code. */
704 assert(swapchain_image->usage == (pCreateInfo->usage | VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
705
706 VkImageCreateInfo local_create_info;
707 local_create_info = *pCreateInfo;
708 local_create_info.pNext = NULL;
709 /* The following parameters are implictly selected by the wsi code. */
710 local_create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
711 local_create_info.samples = VK_SAMPLE_COUNT_1_BIT;
712 local_create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
713
714 /* If the image has a particular modifier, specify that modifier. */
715 struct wsi_image_create_info local_wsi_info = {
716 .sType = VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
717 .modifier_count = 1,
718 .modifiers = &swapchain_image->drm_format_mod,
719 };
720 if (swapchain_image->drm_format_mod != DRM_FORMAT_MOD_INVALID)
721 __vk_append_struct(&local_create_info, &local_wsi_info);
722
723 return anv_image_create(device,
724 &(struct anv_image_create_info) {
725 .vk_info = &local_create_info,
726 .external_format = swapchain_image->external_format,
727 },
728 pAllocator,
729 pImage);
730 }
731
732 VkResult
733 anv_CreateImage(VkDevice device,
734 const VkImageCreateInfo *pCreateInfo,
735 const VkAllocationCallbacks *pAllocator,
736 VkImage *pImage)
737 {
738 const struct VkExternalMemoryImageCreateInfo *create_info =
739 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_MEMORY_IMAGE_CREATE_INFO);
740
741 if (create_info && (create_info->handleTypes &
742 VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID))
743 return anv_image_from_external(device, pCreateInfo, create_info,
744 pAllocator, pImage);
745
746 bool use_external_format = false;
747 const struct VkExternalFormatANDROID *ext_format =
748 vk_find_struct_const(pCreateInfo->pNext, EXTERNAL_FORMAT_ANDROID);
749
750 /* "If externalFormat is zero, the effect is as if the
751 * VkExternalFormatANDROID structure was not present. Otherwise, the image
752 * will have the specified external format."
753 */
754 if (ext_format && ext_format->externalFormat != 0)
755 use_external_format = true;
756
757 const VkNativeBufferANDROID *gralloc_info =
758 vk_find_struct_const(pCreateInfo->pNext, NATIVE_BUFFER_ANDROID);
759 if (gralloc_info)
760 return anv_image_from_gralloc(device, pCreateInfo, gralloc_info,
761 pAllocator, pImage);
762
763 const VkImageSwapchainCreateInfoKHR *swapchain_info =
764 vk_find_struct_const(pCreateInfo->pNext, IMAGE_SWAPCHAIN_CREATE_INFO_KHR);
765 if (swapchain_info && swapchain_info->swapchain != VK_NULL_HANDLE)
766 return anv_image_from_swapchain(device, pCreateInfo, swapchain_info,
767 pAllocator, pImage);
768
769 return anv_image_create(device,
770 &(struct anv_image_create_info) {
771 .vk_info = pCreateInfo,
772 .external_format = use_external_format,
773 },
774 pAllocator,
775 pImage);
776 }
777
778 void
779 anv_DestroyImage(VkDevice _device, VkImage _image,
780 const VkAllocationCallbacks *pAllocator)
781 {
782 ANV_FROM_HANDLE(anv_device, device, _device);
783 ANV_FROM_HANDLE(anv_image, image, _image);
784
785 if (!image)
786 return;
787
788 for (uint32_t p = 0; p < image->n_planes; ++p) {
789 if (anv_image_plane_uses_aux_map(device, image, p) &&
790 image->planes[p].address.bo) {
791 gen_aux_map_unmap_range(device->aux_map_ctx,
792 image->planes[p].aux_map_surface_address,
793 image->planes[p].surface.isl.size_B);
794 }
795 if (image->planes[p].bo_is_owned) {
796 assert(image->planes[p].address.bo != NULL);
797 anv_bo_cache_release(device, &device->bo_cache,
798 image->planes[p].address.bo);
799 }
800 }
801
802 vk_free2(&device->alloc, pAllocator, image);
803 }
804
805 static void anv_image_bind_memory_plane(struct anv_device *device,
806 struct anv_image *image,
807 uint32_t plane,
808 struct anv_device_memory *memory,
809 uint32_t memory_offset)
810 {
811 assert(!image->planes[plane].bo_is_owned);
812
813 if (!memory) {
814 if (anv_image_plane_uses_aux_map(device, image, plane) &&
815 image->planes[plane].address.bo) {
816 gen_aux_map_unmap_range(device->aux_map_ctx,
817 image->planes[plane].aux_map_surface_address,
818 image->planes[plane].surface.isl.size_B);
819 }
820 image->planes[plane].address = ANV_NULL_ADDRESS;
821 return;
822 }
823
824 image->planes[plane].address = (struct anv_address) {
825 .bo = memory->bo,
826 .offset = memory_offset,
827 };
828
829 if (anv_image_plane_uses_aux_map(device, image, plane)) {
830 image->planes[plane].aux_map_surface_address =
831 anv_address_physical(
832 anv_address_add(image->planes[plane].address,
833 image->planes[plane].surface.offset));
834
835 gen_aux_map_add_image(device->aux_map_ctx,
836 &image->planes[plane].surface.isl,
837 image->planes[plane].aux_map_surface_address,
838 anv_address_physical(
839 anv_address_add(image->planes[plane].address,
840 image->planes[plane].aux_surface.offset)));
841 }
842 }
843
844 /* We are binding AHardwareBuffer. Get a description, resolve the
845 * format and prepare anv_image properly.
846 */
847 static void
848 resolve_ahw_image(struct anv_device *device,
849 struct anv_image *image,
850 struct anv_device_memory *mem)
851 {
852 #if defined(ANDROID) && ANDROID_API_LEVEL >= 26
853 assert(mem->ahw);
854 AHardwareBuffer_Desc desc;
855 AHardwareBuffer_describe(mem->ahw, &desc);
856
857 /* Check tiling. */
858 int i915_tiling = anv_gem_get_tiling(device, mem->bo->gem_handle);
859 VkImageTiling vk_tiling;
860 isl_tiling_flags_t isl_tiling_flags = 0;
861
862 switch (i915_tiling) {
863 case I915_TILING_NONE:
864 vk_tiling = VK_IMAGE_TILING_LINEAR;
865 isl_tiling_flags = ISL_TILING_LINEAR_BIT;
866 break;
867 case I915_TILING_X:
868 vk_tiling = VK_IMAGE_TILING_OPTIMAL;
869 isl_tiling_flags = ISL_TILING_X_BIT;
870 break;
871 case I915_TILING_Y:
872 vk_tiling = VK_IMAGE_TILING_OPTIMAL;
873 isl_tiling_flags = ISL_TILING_Y0_BIT;
874 break;
875 case -1:
876 default:
877 unreachable("Invalid tiling flags.");
878 }
879
880 assert(vk_tiling == VK_IMAGE_TILING_LINEAR ||
881 vk_tiling == VK_IMAGE_TILING_OPTIMAL);
882
883 /* Check format. */
884 VkFormat vk_format = vk_format_from_android(desc.format, desc.usage);
885 enum isl_format isl_fmt = anv_get_isl_format(&device->info,
886 vk_format,
887 VK_IMAGE_ASPECT_COLOR_BIT,
888 vk_tiling);
889 assert(isl_fmt != ISL_FORMAT_UNSUPPORTED);
890
891 /* Handle RGB(X)->RGBA fallback. */
892 switch (desc.format) {
893 case AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM:
894 case AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM:
895 if (isl_format_is_rgb(isl_fmt))
896 isl_fmt = isl_format_rgb_to_rgba(isl_fmt);
897 break;
898 }
899
900 /* Now we are able to fill anv_image fields properly and create
901 * isl_surface for it.
902 */
903 image->vk_format = vk_format;
904 image->format = anv_get_format(vk_format);
905 image->aspects = vk_format_aspects(image->vk_format);
906 image->n_planes = image->format->n_planes;
907 image->ccs_e_compatible = false;
908
909 uint32_t stride = desc.stride *
910 (isl_format_get_layout(isl_fmt)->bpb / 8);
911
912 uint32_t b;
913 for_each_bit(b, image->aspects) {
914 VkResult r = make_surface(device, image, stride, isl_tiling_flags,
915 ISL_SURF_USAGE_DISABLE_AUX_BIT, (1 << b));
916 assert(r == VK_SUCCESS);
917 }
918 #endif
919 }
920
921 VkResult anv_BindImageMemory(
922 VkDevice _device,
923 VkImage _image,
924 VkDeviceMemory _memory,
925 VkDeviceSize memoryOffset)
926 {
927 ANV_FROM_HANDLE(anv_device, device, _device);
928 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
929 ANV_FROM_HANDLE(anv_image, image, _image);
930
931 if (mem->ahw)
932 resolve_ahw_image(device, image, mem);
933
934 uint32_t aspect_bit;
935 anv_foreach_image_aspect_bit(aspect_bit, image, image->aspects) {
936 uint32_t plane =
937 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
938 anv_image_bind_memory_plane(device, image, plane, mem, memoryOffset);
939 }
940
941 return VK_SUCCESS;
942 }
943
944 VkResult anv_BindImageMemory2(
945 VkDevice _device,
946 uint32_t bindInfoCount,
947 const VkBindImageMemoryInfo* pBindInfos)
948 {
949 ANV_FROM_HANDLE(anv_device, device, _device);
950
951 for (uint32_t i = 0; i < bindInfoCount; i++) {
952 const VkBindImageMemoryInfo *bind_info = &pBindInfos[i];
953 ANV_FROM_HANDLE(anv_device_memory, mem, bind_info->memory);
954 ANV_FROM_HANDLE(anv_image, image, bind_info->image);
955
956 /* Resolve will alter the image's aspects, do this first. */
957 if (mem && mem->ahw)
958 resolve_ahw_image(device, image, mem);
959
960 VkImageAspectFlags aspects = image->aspects;
961 vk_foreach_struct_const(s, bind_info->pNext) {
962 switch (s->sType) {
963 case VK_STRUCTURE_TYPE_BIND_IMAGE_PLANE_MEMORY_INFO: {
964 const VkBindImagePlaneMemoryInfo *plane_info =
965 (const VkBindImagePlaneMemoryInfo *) s;
966
967 aspects = plane_info->planeAspect;
968 break;
969 }
970 case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR: {
971 const VkBindImageMemorySwapchainInfoKHR *swapchain_info =
972 (const VkBindImageMemorySwapchainInfoKHR *) s;
973 struct anv_image *swapchain_image =
974 anv_swapchain_get_image(swapchain_info->swapchain,
975 swapchain_info->imageIndex);
976 assert(swapchain_image);
977 assert(image->aspects == swapchain_image->aspects);
978 assert(mem == NULL);
979
980 uint32_t aspect_bit;
981 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) {
982 uint32_t plane =
983 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
984 struct anv_device_memory mem = {
985 .bo = swapchain_image->planes[plane].address.bo,
986 };
987 anv_image_bind_memory_plane(device, image, plane,
988 &mem, bind_info->memoryOffset);
989 }
990 break;
991 }
992 default:
993 anv_debug_ignored_stype(s->sType);
994 break;
995 }
996 }
997
998 /* VkBindImageMemorySwapchainInfoKHR requires memory to be
999 * VK_NULL_HANDLE. In such case, just carry one with the next bind
1000 * item.
1001 */
1002 if (!mem)
1003 continue;
1004
1005 uint32_t aspect_bit;
1006 anv_foreach_image_aspect_bit(aspect_bit, image, aspects) {
1007 uint32_t plane =
1008 anv_image_aspect_to_plane(image->aspects, 1UL << aspect_bit);
1009 anv_image_bind_memory_plane(device, image, plane,
1010 mem, bind_info->memoryOffset);
1011 }
1012 }
1013
1014 return VK_SUCCESS;
1015 }
1016
1017 void anv_GetImageSubresourceLayout(
1018 VkDevice device,
1019 VkImage _image,
1020 const VkImageSubresource* subresource,
1021 VkSubresourceLayout* layout)
1022 {
1023 ANV_FROM_HANDLE(anv_image, image, _image);
1024
1025 const struct anv_surface *surface;
1026 if (subresource->aspectMask == VK_IMAGE_ASPECT_PLANE_1_BIT &&
1027 image->drm_format_mod != DRM_FORMAT_MOD_INVALID &&
1028 isl_drm_modifier_has_aux(image->drm_format_mod))
1029 surface = &image->planes[0].aux_surface;
1030 else
1031 surface = get_surface(image, subresource->aspectMask);
1032
1033 assert(__builtin_popcount(subresource->aspectMask) == 1);
1034
1035 layout->offset = surface->offset;
1036 layout->rowPitch = surface->isl.row_pitch_B;
1037 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
1038 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
1039
1040 if (subresource->mipLevel > 0 || subresource->arrayLayer > 0) {
1041 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1042
1043 uint32_t offset_B;
1044 isl_surf_get_image_offset_B_tile_sa(&surface->isl,
1045 subresource->mipLevel,
1046 subresource->arrayLayer,
1047 0 /* logical_z_offset_px */,
1048 &offset_B, NULL, NULL);
1049 layout->offset += offset_B;
1050 layout->size = layout->rowPitch * anv_minify(image->extent.height,
1051 subresource->mipLevel);
1052 } else {
1053 layout->size = surface->isl.size_B;
1054 }
1055 }
1056
1057 /**
1058 * This function determines the optimal buffer to use for a given
1059 * VkImageLayout and other pieces of information needed to make that
1060 * determination. This does not determine the optimal buffer to use
1061 * during a resolve operation.
1062 *
1063 * @param devinfo The device information of the Intel GPU.
1064 * @param image The image that may contain a collection of buffers.
1065 * @param aspect The aspect of the image to be accessed.
1066 * @param layout The current layout of the image aspect(s).
1067 *
1068 * @return The primary buffer that should be used for the given layout.
1069 */
1070 enum isl_aux_usage
1071 anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
1072 const struct anv_image * const image,
1073 const VkImageAspectFlagBits aspect,
1074 const VkImageLayout layout)
1075 {
1076 /* Validate the inputs. */
1077
1078 /* The devinfo is needed as the optimal buffer varies across generations. */
1079 assert(devinfo != NULL);
1080
1081 /* The layout of a NULL image is not properly defined. */
1082 assert(image != NULL);
1083
1084 /* The aspect must be exactly one of the image aspects. */
1085 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));
1086
1087 /* Determine the optimal buffer. */
1088
1089 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1090
1091 /* If there is no auxiliary surface allocated, we must use the one and only
1092 * main buffer.
1093 */
1094 if (image->planes[plane].aux_surface.isl.size_B == 0)
1095 return ISL_AUX_USAGE_NONE;
1096
1097 /* All images that use an auxiliary surface are required to be tiled. */
1098 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
1099
1100 /* Stencil has no aux */
1101 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
1102
1103 switch (layout) {
1104
1105 /* Invalid Layouts */
1106 case VK_IMAGE_LAYOUT_RANGE_SIZE:
1107 case VK_IMAGE_LAYOUT_MAX_ENUM:
1108 unreachable("Invalid image layout.");
1109
1110 /* Undefined layouts
1111 *
1112 * The pre-initialized layout is equivalent to the undefined layout for
1113 * optimally-tiled images. We can only do color compression (CCS or HiZ)
1114 * on tiled images.
1115 */
1116 case VK_IMAGE_LAYOUT_UNDEFINED:
1117 case VK_IMAGE_LAYOUT_PREINITIALIZED:
1118 return ISL_AUX_USAGE_NONE;
1119
1120
1121 /* Transfer Layouts
1122 */
1123 case VK_IMAGE_LAYOUT_GENERAL:
1124 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
1125 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
1126 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1127 /* This buffer could be a depth buffer used in a transfer operation.
1128 * BLORP currently doesn't use HiZ for transfer operations so we must
1129 * use the main buffer for this layout. TODO: Enable HiZ in BLORP.
1130 */
1131 assert(image->planes[plane].aux_usage == ISL_AUX_USAGE_HIZ);
1132 return ISL_AUX_USAGE_NONE;
1133 } else {
1134 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1135 return image->planes[plane].aux_usage;
1136 }
1137
1138
1139 /* Sampling Layouts */
1140 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
1141 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL:
1142 assert((image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1143 /* Fall-through */
1144 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
1145 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1146 if (anv_can_sample_with_hiz(devinfo, image))
1147 return ISL_AUX_USAGE_HIZ;
1148 else
1149 return ISL_AUX_USAGE_NONE;
1150 } else {
1151 return image->planes[plane].aux_usage;
1152 }
1153
1154
1155 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
1156 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1157
1158 /* When handing the image off to the presentation engine, we need to
1159 * ensure that things are properly resolved. For images with no
1160 * modifier, we assume that they follow the old rules and always need
1161 * a full resolve because the PE doesn't understand any form of
1162 * compression. For images with modifiers, we use the aux usage from
1163 * the modifier.
1164 */
1165 const struct isl_drm_modifier_info *mod_info =
1166 isl_drm_modifier_get_info(image->drm_format_mod);
1167 return mod_info ? mod_info->aux_usage : ISL_AUX_USAGE_NONE;
1168 }
1169
1170
1171 /* Rendering Layouts */
1172 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
1173 assert(aspect & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1174 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_NONE) {
1175 assert(image->samples == 1);
1176 return ISL_AUX_USAGE_CCS_D;
1177 } else {
1178 assert(image->planes[plane].aux_usage != ISL_AUX_USAGE_CCS_D);
1179 return image->planes[plane].aux_usage;
1180 }
1181
1182 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
1183 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL:
1184 assert(aspect == VK_IMAGE_ASPECT_DEPTH_BIT);
1185 return ISL_AUX_USAGE_HIZ;
1186
1187 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR:
1188 unreachable("VK_KHR_shared_presentable_image is unsupported");
1189
1190 case VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT:
1191 unreachable("VK_EXT_fragment_density_map is unsupported");
1192
1193 case VK_IMAGE_LAYOUT_SHADING_RATE_OPTIMAL_NV:
1194 unreachable("VK_NV_shading_rate_image is unsupported");
1195 }
1196
1197 /* If the layout isn't recognized in the exhaustive switch above, the
1198 * VkImageLayout value is not defined in vulkan.h.
1199 */
1200 unreachable("layout is not a VkImageLayout enumeration member.");
1201 }
1202
1203 /**
1204 * This function returns the level of unresolved fast-clear support of the
1205 * given image in the given VkImageLayout.
1206 *
1207 * @param devinfo The device information of the Intel GPU.
1208 * @param image The image that may contain a collection of buffers.
1209 * @param aspect The aspect of the image to be accessed.
1210 * @param layout The current layout of the image aspect(s).
1211 */
1212 enum anv_fast_clear_type
1213 anv_layout_to_fast_clear_type(const struct gen_device_info * const devinfo,
1214 const struct anv_image * const image,
1215 const VkImageAspectFlagBits aspect,
1216 const VkImageLayout layout)
1217 {
1218 if (INTEL_DEBUG & DEBUG_NO_FAST_CLEAR)
1219 return ANV_FAST_CLEAR_NONE;
1220
1221 /* The aspect must be exactly one of the image aspects. */
1222 assert(util_bitcount(aspect) == 1 && (aspect & image->aspects));
1223
1224 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1225
1226 /* If there is no auxiliary surface allocated, there are no fast-clears */
1227 if (image->planes[plane].aux_surface.isl.size_B == 0)
1228 return ANV_FAST_CLEAR_NONE;
1229
1230 /* All images that use an auxiliary surface are required to be tiled. */
1231 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
1232
1233 /* Stencil has no aux */
1234 assert(aspect != VK_IMAGE_ASPECT_STENCIL_BIT);
1235
1236 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
1237 /* For depth images (with HiZ), the layout supports fast-clears if and
1238 * only if it supports HiZ. However, we only support fast-clears to the
1239 * default depth value.
1240 */
1241 enum isl_aux_usage aux_usage =
1242 anv_layout_to_aux_usage(devinfo, image, aspect, layout);
1243 return aux_usage == ISL_AUX_USAGE_HIZ ?
1244 ANV_FAST_CLEAR_DEFAULT_VALUE : ANV_FAST_CLEAR_NONE;
1245 }
1246
1247 assert(image->aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV);
1248
1249 /* We don't support MSAA fast-clears on Ivybridge or Bay Trail because they
1250 * lack the MI ALU which we need to determine the predicates.
1251 */
1252 if (devinfo->gen == 7 && !devinfo->is_haswell && image->samples > 1)
1253 return ANV_FAST_CLEAR_NONE;
1254
1255 switch (layout) {
1256 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
1257 return ANV_FAST_CLEAR_ANY;
1258
1259 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR: {
1260 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1261 #ifndef NDEBUG
1262 /* We do not yet support any modifiers which support clear color so we
1263 * just always return NONE. One day, this will change.
1264 */
1265 const struct isl_drm_modifier_info *mod_info =
1266 isl_drm_modifier_get_info(image->drm_format_mod);
1267 assert(!mod_info || !mod_info->supports_clear_color);
1268 #endif
1269 return ANV_FAST_CLEAR_NONE;
1270 }
1271
1272 default:
1273 /* If the image has MCS or CCS_E enabled all the time then we can use
1274 * fast-clear as long as the clear color is the default value of zero
1275 * since this is the default value we program into every surface state
1276 * used for texturing.
1277 */
1278 if (image->planes[plane].aux_usage == ISL_AUX_USAGE_MCS ||
1279 image->planes[plane].aux_usage == ISL_AUX_USAGE_CCS_E)
1280 return ANV_FAST_CLEAR_DEFAULT_VALUE;
1281 else
1282 return ANV_FAST_CLEAR_NONE;
1283 }
1284 }
1285
1286
1287 static struct anv_state
1288 alloc_surface_state(struct anv_device *device)
1289 {
1290 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
1291 }
1292
1293 static enum isl_channel_select
1294 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
1295 struct isl_swizzle format_swizzle)
1296 {
1297 if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
1298 swizzle = component;
1299
1300 switch (swizzle) {
1301 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO;
1302 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE;
1303 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r;
1304 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g;
1305 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b;
1306 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a;
1307 default:
1308 unreachable("Invalid swizzle");
1309 }
1310 }
1311
1312 void
1313 anv_image_fill_surface_state(struct anv_device *device,
1314 const struct anv_image *image,
1315 VkImageAspectFlagBits aspect,
1316 const struct isl_view *view_in,
1317 isl_surf_usage_flags_t view_usage,
1318 enum isl_aux_usage aux_usage,
1319 const union isl_color_value *clear_color,
1320 enum anv_image_view_state_flags flags,
1321 struct anv_surface_state *state_inout,
1322 struct brw_image_param *image_param_out)
1323 {
1324 uint32_t plane = anv_image_aspect_to_plane(image->aspects, aspect);
1325
1326 const struct anv_surface *surface = &image->planes[plane].surface,
1327 *aux_surface = &image->planes[plane].aux_surface;
1328
1329 struct isl_view view = *view_in;
1330 view.usage |= view_usage;
1331
1332 /* For texturing with VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL from a
1333 * compressed surface with a shadow surface, we use the shadow instead of
1334 * the primary surface. The shadow surface will be tiled, unlike the main
1335 * surface, so it should get significantly better performance.
1336 */
1337 if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
1338 isl_format_is_compressed(view.format) &&
1339 (flags & ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL)) {
1340 assert(isl_format_is_compressed(surface->isl.format));
1341 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1342 assert(image->planes[plane].shadow_surface.isl.tiling != ISL_TILING_LINEAR);
1343 surface = &image->planes[plane].shadow_surface;
1344 }
1345
1346 /* For texturing from stencil on gen7, we have to sample from a shadow
1347 * surface because we don't support W-tiling in the sampler.
1348 */
1349 if (image->planes[plane].shadow_surface.isl.size_B > 0 &&
1350 aspect == VK_IMAGE_ASPECT_STENCIL_BIT) {
1351 assert(device->info.gen == 7);
1352 assert(view_usage & ISL_SURF_USAGE_TEXTURE_BIT);
1353 surface = &image->planes[plane].shadow_surface;
1354 }
1355
1356 if (view_usage == ISL_SURF_USAGE_RENDER_TARGET_BIT)
1357 view.swizzle = anv_swizzle_for_render(view.swizzle);
1358
1359 /* On Ivy Bridge and Bay Trail we do the swizzle in the shader */
1360 if (device->info.gen == 7 && !device->info.is_haswell)
1361 view.swizzle = ISL_SWIZZLE_IDENTITY;
1362
1363 /* If this is a HiZ buffer we can sample from with a programmable clear
1364 * value (SKL+), define the clear value to the optimal constant.
1365 */
1366 union isl_color_value default_clear_color = { .u32 = { 0, } };
1367 if (device->info.gen >= 9 && aux_usage == ISL_AUX_USAGE_HIZ)
1368 default_clear_color.f32[0] = ANV_HZ_FC_VAL;
1369 if (!clear_color)
1370 clear_color = &default_clear_color;
1371
1372 const struct anv_address address =
1373 anv_address_add(image->planes[plane].address, surface->offset);
1374
1375 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
1376 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY) &&
1377 !isl_has_matching_typed_storage_image_format(&device->info,
1378 view.format)) {
1379 /* In this case, we are a writeable storage buffer which needs to be
1380 * lowered to linear. All tiling and offset calculations will be done in
1381 * the shader.
1382 */
1383 assert(aux_usage == ISL_AUX_USAGE_NONE);
1384 isl_buffer_fill_state(&device->isl_dev, state_inout->state.map,
1385 .address = anv_address_physical(address),
1386 .size_B = surface->isl.size_B,
1387 .format = ISL_FORMAT_RAW,
1388 .swizzle = ISL_SWIZZLE_IDENTITY,
1389 .stride_B = 1,
1390 .mocs = anv_mocs_for_bo(device, address.bo));
1391 state_inout->address = address,
1392 state_inout->aux_address = ANV_NULL_ADDRESS;
1393 state_inout->clear_address = ANV_NULL_ADDRESS;
1394 } else {
1395 if (view_usage == ISL_SURF_USAGE_STORAGE_BIT &&
1396 !(flags & ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY)) {
1397 /* Typed surface reads support a very limited subset of the shader
1398 * image formats. Translate it into the closest format the hardware
1399 * supports.
1400 */
1401 assert(aux_usage == ISL_AUX_USAGE_NONE);
1402 view.format = isl_lower_storage_image_format(&device->info,
1403 view.format);
1404 }
1405
1406 const struct isl_surf *isl_surf = &surface->isl;
1407
1408 struct isl_surf tmp_surf;
1409 uint32_t offset_B = 0, tile_x_sa = 0, tile_y_sa = 0;
1410 if (isl_format_is_compressed(surface->isl.format) &&
1411 !isl_format_is_compressed(view.format)) {
1412 /* We're creating an uncompressed view of a compressed surface. This
1413 * is allowed but only for a single level/layer.
1414 */
1415 assert(surface->isl.samples == 1);
1416 assert(view.levels == 1);
1417 assert(view.array_len == 1);
1418
1419 isl_surf_get_image_surf(&device->isl_dev, isl_surf,
1420 view.base_level,
1421 surface->isl.dim == ISL_SURF_DIM_3D ?
1422 0 : view.base_array_layer,
1423 surface->isl.dim == ISL_SURF_DIM_3D ?
1424 view.base_array_layer : 0,
1425 &tmp_surf,
1426 &offset_B, &tile_x_sa, &tile_y_sa);
1427
1428 /* The newly created image represents the one subimage we're
1429 * referencing with this view so it only has one array slice and
1430 * miplevel.
1431 */
1432 view.base_array_layer = 0;
1433 view.base_level = 0;
1434
1435 /* We're making an uncompressed view here. The image dimensions need
1436 * to be scaled down by the block size.
1437 */
1438 const struct isl_format_layout *fmtl =
1439 isl_format_get_layout(surface->isl.format);
1440 tmp_surf.logical_level0_px =
1441 isl_surf_get_logical_level0_el(&tmp_surf);
1442 tmp_surf.phys_level0_sa = isl_surf_get_phys_level0_el(&tmp_surf);
1443 tmp_surf.format = view.format;
1444 tile_x_sa /= fmtl->bw;
1445 tile_y_sa /= fmtl->bh;
1446
1447 isl_surf = &tmp_surf;
1448
1449 if (device->info.gen <= 8) {
1450 assert(surface->isl.tiling == ISL_TILING_LINEAR);
1451 assert(tile_x_sa == 0);
1452 assert(tile_y_sa == 0);
1453 }
1454 }
1455
1456 state_inout->address = anv_address_add(address, offset_B);
1457
1458 struct anv_address aux_address = ANV_NULL_ADDRESS;
1459 if (aux_usage != ISL_AUX_USAGE_NONE) {
1460 aux_address = anv_address_add(image->planes[plane].address,
1461 aux_surface->offset);
1462 }
1463 state_inout->aux_address = aux_address;
1464
1465 struct anv_address clear_address = ANV_NULL_ADDRESS;
1466 if (device->info.gen >= 10 && aux_usage != ISL_AUX_USAGE_NONE) {
1467 if (aux_usage == ISL_AUX_USAGE_HIZ) {
1468 clear_address = (struct anv_address) {
1469 .bo = &device->hiz_clear_bo,
1470 .offset = 0,
1471 };
1472 } else {
1473 clear_address = anv_image_get_clear_color_addr(device, image, aspect);
1474 }
1475 }
1476 state_inout->clear_address = clear_address;
1477
1478 isl_surf_fill_state(&device->isl_dev, state_inout->state.map,
1479 .surf = isl_surf,
1480 .view = &view,
1481 .address = anv_address_physical(state_inout->address),
1482 .clear_color = *clear_color,
1483 .aux_surf = &aux_surface->isl,
1484 .aux_usage = aux_usage,
1485 .aux_address = anv_address_physical(aux_address),
1486 .clear_address = anv_address_physical(clear_address),
1487 .use_clear_address = !anv_address_is_null(clear_address),
1488 .mocs = anv_mocs_for_bo(device,
1489 state_inout->address.bo),
1490 .x_offset_sa = tile_x_sa,
1491 .y_offset_sa = tile_y_sa);
1492
1493 /* With the exception of gen8, the bottom 12 bits of the MCS base address
1494 * are used to store other information. This should be ok, however,
1495 * because the surface buffer addresses are always 4K page aligned.
1496 */
1497 uint32_t *aux_addr_dw = state_inout->state.map +
1498 device->isl_dev.ss.aux_addr_offset;
1499 assert((aux_address.offset & 0xfff) == 0);
1500 state_inout->aux_address.offset |= *aux_addr_dw & 0xfff;
1501
1502 if (device->info.gen >= 10 && clear_address.bo) {
1503 uint32_t *clear_addr_dw = state_inout->state.map +
1504 device->isl_dev.ss.clear_color_state_offset;
1505 assert((clear_address.offset & 0x3f) == 0);
1506 state_inout->clear_address.offset |= *clear_addr_dw & 0x3f;
1507 }
1508 }
1509
1510 if (image_param_out) {
1511 assert(view_usage == ISL_SURF_USAGE_STORAGE_BIT);
1512 isl_surf_fill_image_param(&device->isl_dev, image_param_out,
1513 &surface->isl, &view);
1514 }
1515 }
1516
1517 static VkImageAspectFlags
1518 remap_aspect_flags(VkImageAspectFlags view_aspects)
1519 {
1520 if (view_aspects & VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) {
1521 if (util_bitcount(view_aspects) == 1)
1522 return VK_IMAGE_ASPECT_COLOR_BIT;
1523
1524 VkImageAspectFlags color_aspects = 0;
1525 for (uint32_t i = 0; i < util_bitcount(view_aspects); i++)
1526 color_aspects |= VK_IMAGE_ASPECT_PLANE_0_BIT << i;
1527 return color_aspects;
1528 }
1529 /* No special remapping needed for depth & stencil aspects. */
1530 return view_aspects;
1531 }
1532
1533 static uint32_t
1534 anv_image_aspect_get_planes(VkImageAspectFlags aspect_mask)
1535 {
1536 uint32_t planes = 0;
1537
1538 if (aspect_mask & (VK_IMAGE_ASPECT_COLOR_BIT |
1539 VK_IMAGE_ASPECT_DEPTH_BIT |
1540 VK_IMAGE_ASPECT_STENCIL_BIT |
1541 VK_IMAGE_ASPECT_PLANE_0_BIT))
1542 planes++;
1543 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_1_BIT)
1544 planes++;
1545 if (aspect_mask & VK_IMAGE_ASPECT_PLANE_2_BIT)
1546 planes++;
1547
1548 if ((aspect_mask & VK_IMAGE_ASPECT_DEPTH_BIT) != 0 &&
1549 (aspect_mask & VK_IMAGE_ASPECT_STENCIL_BIT) != 0)
1550 planes++;
1551
1552 return planes;
1553 }
1554
1555 VkResult
1556 anv_CreateImageView(VkDevice _device,
1557 const VkImageViewCreateInfo *pCreateInfo,
1558 const VkAllocationCallbacks *pAllocator,
1559 VkImageView *pView)
1560 {
1561 ANV_FROM_HANDLE(anv_device, device, _device);
1562 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
1563 struct anv_image_view *iview;
1564
1565 iview = vk_zalloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
1566 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1567 if (iview == NULL)
1568 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1569
1570 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
1571
1572 assert(range->layerCount > 0);
1573 assert(range->baseMipLevel < image->levels);
1574
1575 /* Check if a conversion info was passed. */
1576 const struct anv_format *conv_format = NULL;
1577 const struct VkSamplerYcbcrConversionInfo *conv_info =
1578 vk_find_struct_const(pCreateInfo->pNext, SAMPLER_YCBCR_CONVERSION_INFO);
1579
1580 /* If image has an external format, the pNext chain must contain an instance of
1581 * VKSamplerYcbcrConversionInfo with a conversion object created with the same
1582 * external format as image."
1583 */
1584 assert(!image->external_format || conv_info);
1585
1586 if (conv_info) {
1587 ANV_FROM_HANDLE(anv_ycbcr_conversion, conversion, conv_info->conversion);
1588 conv_format = conversion->format;
1589 }
1590
1591 VkImageUsageFlags image_usage = 0;
1592 if (range->aspectMask & ~VK_IMAGE_ASPECT_STENCIL_BIT)
1593 image_usage |= image->usage;
1594 if (range->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT)
1595 image_usage |= image->stencil_usage;
1596
1597 const VkImageViewUsageCreateInfo *usage_info =
1598 vk_find_struct_const(pCreateInfo, IMAGE_VIEW_USAGE_CREATE_INFO);
1599 VkImageUsageFlags view_usage = usage_info ? usage_info->usage : image_usage;
1600
1601 /* View usage should be a subset of image usage */
1602 assert((view_usage & ~image_usage) == 0);
1603 assert(view_usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
1604 VK_IMAGE_USAGE_STORAGE_BIT |
1605 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
1606 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT |
1607 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
1608
1609 switch (image->type) {
1610 default:
1611 unreachable("bad VkImageType");
1612 case VK_IMAGE_TYPE_1D:
1613 case VK_IMAGE_TYPE_2D:
1614 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);
1615 break;
1616 case VK_IMAGE_TYPE_3D:
1617 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1
1618 <= anv_minify(image->extent.depth, range->baseMipLevel));
1619 break;
1620 }
1621
1622 /* First expand aspects to the image's ones (for example
1623 * VK_IMAGE_ASPECT_COLOR_BIT will be converted to
1624 * VK_IMAGE_ASPECT_PLANE_0_BIT | VK_IMAGE_ASPECT_PLANE_1_BIT |
1625 * VK_IMAGE_ASPECT_PLANE_2_BIT for an image of format
1626 * VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.
1627 */
1628 VkImageAspectFlags expanded_aspects =
1629 anv_image_expand_aspects(image, range->aspectMask);
1630
1631 iview->image = image;
1632
1633 /* Remap the expanded aspects for the image view. For example if only
1634 * VK_IMAGE_ASPECT_PLANE_1_BIT was given in range->aspectMask, we will
1635 * convert it to VK_IMAGE_ASPECT_COLOR_BIT since from the point of view of
1636 * the image view, it only has a single plane.
1637 */
1638 iview->aspect_mask = remap_aspect_flags(expanded_aspects);
1639 iview->n_planes = anv_image_aspect_get_planes(iview->aspect_mask);
1640 iview->vk_format = pCreateInfo->format;
1641
1642 /* "If image has an external format, format must be VK_FORMAT_UNDEFINED." */
1643 assert(!image->external_format || pCreateInfo->format == VK_FORMAT_UNDEFINED);
1644
1645 /* Format is undefined, this can happen when using external formats. Set
1646 * view format from the passed conversion info.
1647 */
1648 if (iview->vk_format == VK_FORMAT_UNDEFINED && conv_format)
1649 iview->vk_format = conv_format->vk_format;
1650
1651 iview->extent = (VkExtent3D) {
1652 .width = anv_minify(image->extent.width , range->baseMipLevel),
1653 .height = anv_minify(image->extent.height, range->baseMipLevel),
1654 .depth = anv_minify(image->extent.depth , range->baseMipLevel),
1655 };
1656
1657 /* Now go through the underlying image selected planes (computed in
1658 * expanded_aspects) and map them to planes in the image view.
1659 */
1660 uint32_t iaspect_bit, vplane = 0;
1661 anv_foreach_image_aspect_bit(iaspect_bit, image, expanded_aspects) {
1662 uint32_t iplane =
1663 anv_image_aspect_to_plane(image->aspects, 1UL << iaspect_bit);
1664 VkImageAspectFlags vplane_aspect =
1665 anv_plane_to_aspect(iview->aspect_mask, vplane);
1666 struct anv_format_plane format =
1667 anv_get_format_plane(&device->info, iview->vk_format,
1668 vplane_aspect, image->tiling);
1669
1670 iview->planes[vplane].image_plane = iplane;
1671
1672 iview->planes[vplane].isl = (struct isl_view) {
1673 .format = format.isl_format,
1674 .base_level = range->baseMipLevel,
1675 .levels = anv_get_levelCount(image, range),
1676 .base_array_layer = range->baseArrayLayer,
1677 .array_len = anv_get_layerCount(image, range),
1678 .swizzle = {
1679 .r = remap_swizzle(pCreateInfo->components.r,
1680 VK_COMPONENT_SWIZZLE_R, format.swizzle),
1681 .g = remap_swizzle(pCreateInfo->components.g,
1682 VK_COMPONENT_SWIZZLE_G, format.swizzle),
1683 .b = remap_swizzle(pCreateInfo->components.b,
1684 VK_COMPONENT_SWIZZLE_B, format.swizzle),
1685 .a = remap_swizzle(pCreateInfo->components.a,
1686 VK_COMPONENT_SWIZZLE_A, format.swizzle),
1687 },
1688 };
1689
1690 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
1691 iview->planes[vplane].isl.base_array_layer = 0;
1692 iview->planes[vplane].isl.array_len = iview->extent.depth;
1693 }
1694
1695 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
1696 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
1697 iview->planes[vplane].isl.usage = ISL_SURF_USAGE_CUBE_BIT;
1698 } else {
1699 iview->planes[vplane].isl.usage = 0;
1700 }
1701
1702 if (view_usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
1703 (view_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
1704 !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
1705 iview->planes[vplane].optimal_sampler_surface_state.state = alloc_surface_state(device);
1706 iview->planes[vplane].general_sampler_surface_state.state = alloc_surface_state(device);
1707
1708 enum isl_aux_usage general_aux_usage =
1709 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,
1710 VK_IMAGE_LAYOUT_GENERAL);
1711 enum isl_aux_usage optimal_aux_usage =
1712 anv_layout_to_aux_usage(&device->info, image, 1UL << iaspect_bit,
1713 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
1714
1715 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1716 &iview->planes[vplane].isl,
1717 ISL_SURF_USAGE_TEXTURE_BIT,
1718 optimal_aux_usage, NULL,
1719 ANV_IMAGE_VIEW_STATE_TEXTURE_OPTIMAL,
1720 &iview->planes[vplane].optimal_sampler_surface_state,
1721 NULL);
1722
1723 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1724 &iview->planes[vplane].isl,
1725 ISL_SURF_USAGE_TEXTURE_BIT,
1726 general_aux_usage, NULL,
1727 0,
1728 &iview->planes[vplane].general_sampler_surface_state,
1729 NULL);
1730 }
1731
1732 /* NOTE: This one needs to go last since it may stomp isl_view.format */
1733 if (view_usage & VK_IMAGE_USAGE_STORAGE_BIT) {
1734 iview->planes[vplane].storage_surface_state.state = alloc_surface_state(device);
1735 iview->planes[vplane].writeonly_storage_surface_state.state = alloc_surface_state(device);
1736
1737 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1738 &iview->planes[vplane].isl,
1739 ISL_SURF_USAGE_STORAGE_BIT,
1740 ISL_AUX_USAGE_NONE, NULL,
1741 0,
1742 &iview->planes[vplane].storage_surface_state,
1743 &iview->planes[vplane].storage_image_param);
1744
1745 anv_image_fill_surface_state(device, image, 1ULL << iaspect_bit,
1746 &iview->planes[vplane].isl,
1747 ISL_SURF_USAGE_STORAGE_BIT,
1748 ISL_AUX_USAGE_NONE, NULL,
1749 ANV_IMAGE_VIEW_STATE_STORAGE_WRITE_ONLY,
1750 &iview->planes[vplane].writeonly_storage_surface_state,
1751 NULL);
1752 }
1753
1754 vplane++;
1755 }
1756
1757 *pView = anv_image_view_to_handle(iview);
1758
1759 return VK_SUCCESS;
1760 }
1761
1762 void
1763 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
1764 const VkAllocationCallbacks *pAllocator)
1765 {
1766 ANV_FROM_HANDLE(anv_device, device, _device);
1767 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
1768
1769 if (!iview)
1770 return;
1771
1772 for (uint32_t plane = 0; plane < iview->n_planes; plane++) {
1773 if (iview->planes[plane].optimal_sampler_surface_state.state.alloc_size > 0) {
1774 anv_state_pool_free(&device->surface_state_pool,
1775 iview->planes[plane].optimal_sampler_surface_state.state);
1776 }
1777
1778 if (iview->planes[plane].general_sampler_surface_state.state.alloc_size > 0) {
1779 anv_state_pool_free(&device->surface_state_pool,
1780 iview->planes[plane].general_sampler_surface_state.state);
1781 }
1782
1783 if (iview->planes[plane].storage_surface_state.state.alloc_size > 0) {
1784 anv_state_pool_free(&device->surface_state_pool,
1785 iview->planes[plane].storage_surface_state.state);
1786 }
1787
1788 if (iview->planes[plane].writeonly_storage_surface_state.state.alloc_size > 0) {
1789 anv_state_pool_free(&device->surface_state_pool,
1790 iview->planes[plane].writeonly_storage_surface_state.state);
1791 }
1792 }
1793
1794 vk_free2(&device->alloc, pAllocator, iview);
1795 }
1796
1797
1798 VkResult
1799 anv_CreateBufferView(VkDevice _device,
1800 const VkBufferViewCreateInfo *pCreateInfo,
1801 const VkAllocationCallbacks *pAllocator,
1802 VkBufferView *pView)
1803 {
1804 ANV_FROM_HANDLE(anv_device, device, _device);
1805 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
1806 struct anv_buffer_view *view;
1807
1808 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
1809 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1810 if (!view)
1811 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
1812
1813 /* TODO: Handle the format swizzle? */
1814
1815 view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
1816 VK_IMAGE_ASPECT_COLOR_BIT,
1817 VK_IMAGE_TILING_LINEAR);
1818 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;
1819 view->range = anv_buffer_get_range(buffer, pCreateInfo->offset,
1820 pCreateInfo->range);
1821 view->range = align_down_npot_u32(view->range, format_bs);
1822
1823 view->address = anv_address_add(buffer->address, pCreateInfo->offset);
1824
1825 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
1826 view->surface_state = alloc_surface_state(device);
1827
1828 anv_fill_buffer_surface_state(device, view->surface_state,
1829 view->format,
1830 view->address, view->range, format_bs);
1831 } else {
1832 view->surface_state = (struct anv_state){ 0 };
1833 }
1834
1835 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
1836 view->storage_surface_state = alloc_surface_state(device);
1837 view->writeonly_storage_surface_state = alloc_surface_state(device);
1838
1839 enum isl_format storage_format =
1840 isl_has_matching_typed_storage_image_format(&device->info,
1841 view->format) ?
1842 isl_lower_storage_image_format(&device->info, view->format) :
1843 ISL_FORMAT_RAW;
1844
1845 anv_fill_buffer_surface_state(device, view->storage_surface_state,
1846 storage_format,
1847 view->address, view->range,
1848 (storage_format == ISL_FORMAT_RAW ? 1 :
1849 isl_format_get_layout(storage_format)->bpb / 8));
1850
1851 /* Write-only accesses should use the original format. */
1852 anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state,
1853 view->format,
1854 view->address, view->range,
1855 isl_format_get_layout(view->format)->bpb / 8);
1856
1857 isl_buffer_fill_image_param(&device->isl_dev,
1858 &view->storage_image_param,
1859 view->format, view->range);
1860 } else {
1861 view->storage_surface_state = (struct anv_state){ 0 };
1862 view->writeonly_storage_surface_state = (struct anv_state){ 0 };
1863 }
1864
1865 *pView = anv_buffer_view_to_handle(view);
1866
1867 return VK_SUCCESS;
1868 }
1869
1870 void
1871 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
1872 const VkAllocationCallbacks *pAllocator)
1873 {
1874 ANV_FROM_HANDLE(anv_device, device, _device);
1875 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
1876
1877 if (!view)
1878 return;
1879
1880 if (view->surface_state.alloc_size > 0)
1881 anv_state_pool_free(&device->surface_state_pool,
1882 view->surface_state);
1883
1884 if (view->storage_surface_state.alloc_size > 0)
1885 anv_state_pool_free(&device->surface_state_pool,
1886 view->storage_surface_state);
1887
1888 if (view->writeonly_storage_surface_state.alloc_size > 0)
1889 anv_state_pool_free(&device->surface_state_pool,
1890 view->writeonly_storage_surface_state);
1891
1892 vk_free2(&device->alloc, pAllocator, view);
1893 }
1894
1895 const struct anv_surface *
1896 anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
1897 VkImageAspectFlags aspect_mask)
1898 {
1899 VkImageAspectFlags sanitized_mask;
1900
1901 switch (aspect_mask) {
1902 case VK_IMAGE_ASPECT_COLOR_BIT:
1903 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
1904 sanitized_mask = VK_IMAGE_ASPECT_COLOR_BIT;
1905 break;
1906 case VK_IMAGE_ASPECT_DEPTH_BIT:
1907 assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
1908 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
1909 break;
1910 case VK_IMAGE_ASPECT_STENCIL_BIT:
1911 assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
1912 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
1913 break;
1914 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
1915 /* FINISHME: The Vulkan spec (git a511ba2) requires support for
1916 * combined depth stencil formats. Specifically, it states:
1917 *
1918 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
1919 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
1920 *
1921 * Image views with both depth and stencil aspects are only valid for
1922 * render target attachments, in which case
1923 * cmd_buffer_emit_depth_stencil() will pick out both the depth and
1924 * stencil surfaces from the underlying surface.
1925 */
1926 if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
1927 sanitized_mask = VK_IMAGE_ASPECT_DEPTH_BIT;
1928 } else {
1929 assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
1930 sanitized_mask = VK_IMAGE_ASPECT_STENCIL_BIT;
1931 }
1932 break;
1933 case VK_IMAGE_ASPECT_PLANE_0_BIT:
1934 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1935 sanitized_mask = VK_IMAGE_ASPECT_PLANE_0_BIT;
1936 break;
1937 case VK_IMAGE_ASPECT_PLANE_1_BIT:
1938 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1939 sanitized_mask = VK_IMAGE_ASPECT_PLANE_1_BIT;
1940 break;
1941 case VK_IMAGE_ASPECT_PLANE_2_BIT:
1942 assert((image->aspects & ~VK_IMAGE_ASPECT_ANY_COLOR_BIT_ANV) == 0);
1943 sanitized_mask = VK_IMAGE_ASPECT_PLANE_2_BIT;
1944 break;
1945 default:
1946 unreachable("image does not have aspect");
1947 return NULL;
1948 }
1949
1950 uint32_t plane = anv_image_aspect_to_plane(image->aspects, sanitized_mask);
1951 return &image->planes[plane].surface;
1952 }