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