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