anv: fix anv_gem_mmap comment to not mention NULL
[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
31 #include "anv_private.h"
32 #include "util/debug.h"
33
34 #include "vk_format_info.h"
35
36 /**
37 * Exactly one bit must be set in \a aspect.
38 */
39 static isl_surf_usage_flags_t
40 choose_isl_surf_usage(VkImageUsageFlags vk_usage,
41 VkImageAspectFlags aspect)
42 {
43 isl_surf_usage_flags_t isl_usage = 0;
44
45 if (vk_usage & VK_IMAGE_USAGE_SAMPLED_BIT)
46 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
47
48 if (vk_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
49 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
50
51 if (vk_usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
52 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
53
54 if (vk_usage & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
55 isl_usage |= ISL_SURF_USAGE_CUBE_BIT;
56
57 /* Even if we're only using it for transfer operations, clears to depth and
58 * stencil images happen as depth and stencil so they need the right ISL
59 * usage bits or else things will fall apart.
60 */
61 switch (aspect) {
62 case VK_IMAGE_ASPECT_DEPTH_BIT:
63 isl_usage |= ISL_SURF_USAGE_DEPTH_BIT;
64 break;
65 case VK_IMAGE_ASPECT_STENCIL_BIT:
66 isl_usage |= ISL_SURF_USAGE_STENCIL_BIT;
67 break;
68 case VK_IMAGE_ASPECT_COLOR_BIT:
69 break;
70 default:
71 unreachable("bad VkImageAspect");
72 }
73
74 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
75 /* blorp implements transfers by sampling from the source image. */
76 isl_usage |= ISL_SURF_USAGE_TEXTURE_BIT;
77 }
78
79 if (vk_usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT &&
80 aspect == VK_IMAGE_ASPECT_COLOR_BIT) {
81 /* blorp implements transfers by rendering into the destination image.
82 * Only request this with color images, as we deal with depth/stencil
83 * formats differently. */
84 isl_usage |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
85 }
86
87 return isl_usage;
88 }
89
90 /**
91 * Exactly one bit must be set in \a aspect.
92 */
93 static struct anv_surface *
94 get_surface(struct anv_image *image, VkImageAspectFlags aspect)
95 {
96 switch (aspect) {
97 default:
98 unreachable("bad VkImageAspect");
99 case VK_IMAGE_ASPECT_COLOR_BIT:
100 return &image->color_surface;
101 case VK_IMAGE_ASPECT_DEPTH_BIT:
102 return &image->depth_surface;
103 case VK_IMAGE_ASPECT_STENCIL_BIT:
104 return &image->stencil_surface;
105 }
106 }
107
108 static void
109 add_surface(struct anv_image *image, struct anv_surface *surf)
110 {
111 assert(surf->isl.size > 0); /* isl surface must be initialized */
112
113 surf->offset = align_u32(image->size, surf->isl.alignment);
114 image->size = surf->offset + surf->isl.size;
115 image->alignment = MAX2(image->alignment, surf->isl.alignment);
116 }
117
118 /**
119 * Initialize the anv_image::*_surface selected by \a aspect. Then update the
120 * image's memory requirements (that is, the image's size and alignment).
121 *
122 * Exactly one bit must be set in \a aspect.
123 */
124 static VkResult
125 make_surface(const struct anv_device *dev,
126 struct anv_image *image,
127 const struct anv_image_create_info *anv_info,
128 VkImageAspectFlags aspect)
129 {
130 const VkImageCreateInfo *vk_info = anv_info->vk_info;
131 bool ok UNUSED;
132
133 static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
134 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
135 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
136 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
137 };
138
139 /* Translate the Vulkan tiling to an equivalent ISL tiling, then filter the
140 * result with an optionally provided ISL tiling argument.
141 */
142 isl_tiling_flags_t tiling_flags =
143 (vk_info->tiling == VK_IMAGE_TILING_LINEAR) ?
144 ISL_TILING_LINEAR_BIT : ISL_TILING_ANY_MASK;
145
146 if (anv_info->isl_tiling_flags)
147 tiling_flags &= anv_info->isl_tiling_flags;
148
149 assert(tiling_flags);
150
151 struct anv_surface *anv_surf = get_surface(image, aspect);
152
153 image->extent = anv_sanitize_image_extent(vk_info->imageType,
154 vk_info->extent);
155
156 enum isl_format format = anv_get_isl_format(&dev->info, vk_info->format,
157 aspect, vk_info->tiling);
158 assert(format != ISL_FORMAT_UNSUPPORTED);
159
160 ok = isl_surf_init(&dev->isl_dev, &anv_surf->isl,
161 .dim = vk_to_isl_surf_dim[vk_info->imageType],
162 .format = format,
163 .width = image->extent.width,
164 .height = image->extent.height,
165 .depth = image->extent.depth,
166 .levels = vk_info->mipLevels,
167 .array_len = vk_info->arrayLayers,
168 .samples = vk_info->samples,
169 .min_alignment = 0,
170 .row_pitch = anv_info->stride,
171 .usage = choose_isl_surf_usage(image->usage, aspect),
172 .tiling_flags = tiling_flags);
173
174 /* isl_surf_init() will fail only if provided invalid input. Invalid input
175 * is illegal in Vulkan.
176 */
177 assert(ok);
178
179 add_surface(image, anv_surf);
180
181 /* Add a HiZ surface to a depth buffer that will be used for rendering.
182 */
183 if (aspect == VK_IMAGE_ASPECT_DEPTH_BIT) {
184 /* We don't advertise that depth buffers could be used as storage
185 * images.
186 */
187 assert(!(image->usage & VK_IMAGE_USAGE_STORAGE_BIT));
188
189 /* Allow the user to control HiZ enabling. Disable by default on gen7
190 * because resolves are not currently implemented pre-BDW.
191 */
192 if (!(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT)) {
193 /* It will never be used as an attachment, HiZ is pointless. */
194 } else if (dev->info.gen == 7) {
195 anv_perf_warn("Implement gen7 HiZ");
196 } else if (vk_info->mipLevels > 1) {
197 anv_perf_warn("Enable multi-LOD HiZ");
198 } else if (vk_info->arrayLayers > 1) {
199 anv_perf_warn("Implement multi-arrayLayer HiZ clears and resolves");
200 } else if (dev->info.gen == 8 && vk_info->samples > 1) {
201 anv_perf_warn("Enable gen8 multisampled HiZ");
202 } else if (!unlikely(INTEL_DEBUG & DEBUG_NO_HIZ)) {
203 assert(image->aux_surface.isl.size == 0);
204 ok = isl_surf_get_hiz_surf(&dev->isl_dev, &image->depth_surface.isl,
205 &image->aux_surface.isl);
206 assert(ok);
207 add_surface(image, &image->aux_surface);
208 image->aux_usage = ISL_AUX_USAGE_HIZ;
209 }
210 } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples == 1) {
211 if (!unlikely(INTEL_DEBUG & DEBUG_NO_RBC)) {
212 assert(image->aux_surface.isl.size == 0);
213 ok = isl_surf_get_ccs_surf(&dev->isl_dev, &anv_surf->isl,
214 &image->aux_surface.isl);
215 if (ok) {
216 add_surface(image, &image->aux_surface);
217
218 /* For images created without MUTABLE_FORMAT_BIT set, we know that
219 * they will always be used with the original format. In
220 * particular, they will always be used with a format that
221 * supports color compression. If it's never used as a storage
222 * image, then it will only be used through the sampler or the as
223 * a render target. This means that it's safe to just leave
224 * compression on at all times for these formats.
225 */
226 if (!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT) &&
227 !(vk_info->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) &&
228 isl_format_supports_ccs_e(&dev->info, format)) {
229 image->aux_usage = ISL_AUX_USAGE_CCS_E;
230 }
231 }
232 }
233 } else if (aspect == VK_IMAGE_ASPECT_COLOR_BIT && vk_info->samples > 1) {
234 assert(image->aux_surface.isl.size == 0);
235 assert(!(vk_info->usage & VK_IMAGE_USAGE_STORAGE_BIT));
236 ok = isl_surf_get_mcs_surf(&dev->isl_dev, &anv_surf->isl,
237 &image->aux_surface.isl);
238 if (ok) {
239 add_surface(image, &image->aux_surface);
240 image->aux_usage = ISL_AUX_USAGE_MCS;
241 }
242 }
243
244 return VK_SUCCESS;
245 }
246
247 VkResult
248 anv_image_create(VkDevice _device,
249 const struct anv_image_create_info *create_info,
250 const VkAllocationCallbacks* alloc,
251 VkImage *pImage)
252 {
253 ANV_FROM_HANDLE(anv_device, device, _device);
254 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
255 struct anv_image *image = NULL;
256 VkResult r;
257
258 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
259
260 anv_assert(pCreateInfo->mipLevels > 0);
261 anv_assert(pCreateInfo->arrayLayers > 0);
262 anv_assert(pCreateInfo->samples > 0);
263 anv_assert(pCreateInfo->extent.width > 0);
264 anv_assert(pCreateInfo->extent.height > 0);
265 anv_assert(pCreateInfo->extent.depth > 0);
266
267 image = vk_alloc2(&device->alloc, alloc, sizeof(*image), 8,
268 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
269 if (!image)
270 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
271
272 memset(image, 0, sizeof(*image));
273 image->type = pCreateInfo->imageType;
274 image->extent = pCreateInfo->extent;
275 image->vk_format = pCreateInfo->format;
276 image->aspects = vk_format_aspects(image->vk_format);
277 image->levels = pCreateInfo->mipLevels;
278 image->array_size = pCreateInfo->arrayLayers;
279 image->samples = pCreateInfo->samples;
280 image->usage = pCreateInfo->usage;
281 image->tiling = pCreateInfo->tiling;
282 image->aux_usage = ISL_AUX_USAGE_NONE;
283
284 uint32_t b;
285 for_each_bit(b, image->aspects) {
286 r = make_surface(device, image, create_info, (1 << b));
287 if (r != VK_SUCCESS)
288 goto fail;
289 }
290
291 *pImage = anv_image_to_handle(image);
292
293 return VK_SUCCESS;
294
295 fail:
296 if (image)
297 vk_free2(&device->alloc, alloc, image);
298
299 return r;
300 }
301
302 VkResult
303 anv_CreateImage(VkDevice device,
304 const VkImageCreateInfo *pCreateInfo,
305 const VkAllocationCallbacks *pAllocator,
306 VkImage *pImage)
307 {
308 return anv_image_create(device,
309 &(struct anv_image_create_info) {
310 .vk_info = pCreateInfo,
311 },
312 pAllocator,
313 pImage);
314 }
315
316 void
317 anv_DestroyImage(VkDevice _device, VkImage _image,
318 const VkAllocationCallbacks *pAllocator)
319 {
320 ANV_FROM_HANDLE(anv_device, device, _device);
321 ANV_FROM_HANDLE(anv_image, image, _image);
322
323 if (!image)
324 return;
325
326 vk_free2(&device->alloc, pAllocator, image);
327 }
328
329 VkResult anv_BindImageMemory(
330 VkDevice _device,
331 VkImage _image,
332 VkDeviceMemory _memory,
333 VkDeviceSize memoryOffset)
334 {
335 ANV_FROM_HANDLE(anv_device, device, _device);
336 ANV_FROM_HANDLE(anv_device_memory, mem, _memory);
337 ANV_FROM_HANDLE(anv_image, image, _image);
338
339 if (mem == NULL) {
340 image->bo = NULL;
341 image->offset = 0;
342 return VK_SUCCESS;
343 }
344
345 image->bo = mem->bo;
346 image->offset = memoryOffset;
347
348 if (image->aux_surface.isl.size > 0) {
349
350 /* The offset and size must be a multiple of 4K or else the
351 * anv_gem_mmap call below will fail.
352 */
353 assert((image->offset + image->aux_surface.offset) % 4096 == 0);
354 assert(image->aux_surface.isl.size % 4096 == 0);
355
356 /* Auxiliary surfaces need to have their memory cleared to 0 before they
357 * can be used. For CCS surfaces, this puts them in the "resolved"
358 * state so they can be used with CCS enabled before we ever touch it
359 * from the GPU. For HiZ, we need something valid or else we may get
360 * GPU hangs on some hardware and 0 works fine.
361 */
362 void *map = anv_gem_mmap(device, image->bo->gem_handle,
363 image->offset + image->aux_surface.offset,
364 image->aux_surface.isl.size,
365 device->info.has_llc ? 0 : I915_MMAP_WC);
366
367 if (map == MAP_FAILED)
368 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
369
370 memset(map, 0, image->aux_surface.isl.size);
371
372 anv_gem_munmap(map, image->aux_surface.isl.size);
373 }
374
375 return VK_SUCCESS;
376 }
377
378 static void
379 anv_surface_get_subresource_layout(struct anv_image *image,
380 struct anv_surface *surface,
381 const VkImageSubresource *subresource,
382 VkSubresourceLayout *layout)
383 {
384 /* If we are on a non-zero mip level or array slice, we need to
385 * calculate a real offset.
386 */
387 anv_assert(subresource->mipLevel == 0);
388 anv_assert(subresource->arrayLayer == 0);
389
390 layout->offset = surface->offset;
391 layout->rowPitch = surface->isl.row_pitch;
392 layout->depthPitch = isl_surf_get_array_pitch(&surface->isl);
393 layout->arrayPitch = isl_surf_get_array_pitch(&surface->isl);
394 layout->size = surface->isl.size;
395 }
396
397 void anv_GetImageSubresourceLayout(
398 VkDevice device,
399 VkImage _image,
400 const VkImageSubresource* pSubresource,
401 VkSubresourceLayout* pLayout)
402 {
403 ANV_FROM_HANDLE(anv_image, image, _image);
404
405 assert(__builtin_popcount(pSubresource->aspectMask) == 1);
406
407 switch (pSubresource->aspectMask) {
408 case VK_IMAGE_ASPECT_COLOR_BIT:
409 anv_surface_get_subresource_layout(image, &image->color_surface,
410 pSubresource, pLayout);
411 break;
412 case VK_IMAGE_ASPECT_DEPTH_BIT:
413 anv_surface_get_subresource_layout(image, &image->depth_surface,
414 pSubresource, pLayout);
415 break;
416 case VK_IMAGE_ASPECT_STENCIL_BIT:
417 anv_surface_get_subresource_layout(image, &image->stencil_surface,
418 pSubresource, pLayout);
419 break;
420 default:
421 assert(!"Invalid image aspect");
422 }
423 }
424
425 /**
426 * This function determines the optimal buffer to use for device
427 * accesses given a VkImageLayout and other pieces of information needed to
428 * make that determination. This does not determine the optimal buffer to
429 * use during a resolve operation.
430 *
431 * NOTE: Some layouts do not support device access.
432 *
433 * @param devinfo The device information of the Intel GPU.
434 * @param image The image that may contain a collection of buffers.
435 * @param aspects The aspect(s) of the image to be accessed.
436 * @param layout The current layout of the image aspect(s).
437 *
438 * @return The primary buffer that should be used for the given layout.
439 */
440 enum isl_aux_usage
441 anv_layout_to_aux_usage(const struct gen_device_info * const devinfo,
442 const struct anv_image * const image,
443 const VkImageAspectFlags aspects,
444 const VkImageLayout layout)
445 {
446 /* Validate the inputs. */
447
448 /* The devinfo is needed as the optimal buffer varies across generations. */
449 assert(devinfo != NULL);
450
451 /* The layout of a NULL image is not properly defined. */
452 assert(image != NULL);
453
454 /* The aspects must be a subset of the image aspects. */
455 assert(aspects & image->aspects && aspects <= image->aspects);
456
457 /* Determine the optimal buffer. */
458
459 /* If there is no auxiliary surface allocated, we must use the one and only
460 * main buffer.
461 */
462 if (image->aux_surface.isl.size == 0)
463 return ISL_AUX_USAGE_NONE;
464
465 /* All images that use an auxiliary surface are required to be tiled. */
466 assert(image->tiling == VK_IMAGE_TILING_OPTIMAL);
467
468 /* On BDW+, when clearing the stencil aspect of a depth stencil image,
469 * the HiZ buffer allows us to record the clear with a relatively small
470 * number of packets. Prior to BDW, the HiZ buffer provides no known benefit
471 * to the stencil aspect.
472 */
473 if (devinfo->gen < 8 && aspects == VK_IMAGE_ASPECT_STENCIL_BIT)
474 return ISL_AUX_USAGE_NONE;
475
476 const bool color_aspect = aspects == VK_IMAGE_ASPECT_COLOR_BIT;
477
478 /* The following switch currently only handles depth stencil aspects.
479 * TODO: Handle the color aspect.
480 */
481 if (color_aspect)
482 return image->aux_usage;
483
484 switch (layout) {
485
486 /* Invalid Layouts */
487
488 /* According to the Vulkan Spec, the following layouts are valid only as
489 * initial layouts in a layout transition and don't support device access.
490 */
491 case VK_IMAGE_LAYOUT_UNDEFINED:
492 case VK_IMAGE_LAYOUT_PREINITIALIZED:
493 case VK_IMAGE_LAYOUT_RANGE_SIZE:
494 case VK_IMAGE_LAYOUT_MAX_ENUM:
495 unreachable("Invalid image layout for device access.");
496
497
498 /* Transfer Layouts
499 *
500 * This buffer could be a depth buffer used in a transfer operation. BLORP
501 * currently doesn't use HiZ for transfer operations so we must use the main
502 * buffer for this layout. TODO: Enable HiZ in BLORP.
503 */
504 case VK_IMAGE_LAYOUT_GENERAL:
505 case VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL:
506 case VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL:
507 return ISL_AUX_USAGE_NONE;
508
509
510 /* Sampling Layouts */
511 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL:
512 assert(!color_aspect);
513 /* Fall-through */
514 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL:
515 if (anv_can_sample_with_hiz(devinfo, aspects, image->samples))
516 return ISL_AUX_USAGE_HIZ;
517 else
518 return ISL_AUX_USAGE_NONE;
519
520 case VK_IMAGE_LAYOUT_PRESENT_SRC_KHR:
521 assert(color_aspect);
522
523 /* On SKL+, the render buffer can be decompressed by the presentation
524 * engine. Support for this feature has not yet landed in the wider
525 * ecosystem. TODO: Update this code when support lands.
526 *
527 * From the BDW PRM, Vol 7, Render Target Resolve:
528 *
529 * If the MCS is enabled on a non-multisampled render target, the
530 * render target must be resolved before being used for other
531 * purposes (display, texture, CPU lock) The clear value from
532 * SURFACE_STATE is written into pixels in the render target
533 * indicated as clear in the MCS.
534 *
535 * Pre-SKL, the render buffer must be resolved before being used for
536 * presentation. We can infer that the auxiliary buffer is not used.
537 */
538 return ISL_AUX_USAGE_NONE;
539
540
541 /* Rendering Layouts */
542 case VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL:
543 assert(color_aspect);
544 unreachable("Color images are not yet supported.");
545
546 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL:
547 assert(!color_aspect);
548 return ISL_AUX_USAGE_HIZ;
549 }
550
551 /* If the layout isn't recognized in the exhaustive switch above, the
552 * VkImageLayout value is not defined in vulkan.h.
553 */
554 unreachable("layout is not a VkImageLayout enumeration member.");
555 }
556
557
558 static struct anv_state
559 alloc_surface_state(struct anv_device *device)
560 {
561 return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
562 }
563
564 static enum isl_channel_select
565 remap_swizzle(VkComponentSwizzle swizzle, VkComponentSwizzle component,
566 struct isl_swizzle format_swizzle)
567 {
568 if (swizzle == VK_COMPONENT_SWIZZLE_IDENTITY)
569 swizzle = component;
570
571 switch (swizzle) {
572 case VK_COMPONENT_SWIZZLE_ZERO: return ISL_CHANNEL_SELECT_ZERO;
573 case VK_COMPONENT_SWIZZLE_ONE: return ISL_CHANNEL_SELECT_ONE;
574 case VK_COMPONENT_SWIZZLE_R: return format_swizzle.r;
575 case VK_COMPONENT_SWIZZLE_G: return format_swizzle.g;
576 case VK_COMPONENT_SWIZZLE_B: return format_swizzle.b;
577 case VK_COMPONENT_SWIZZLE_A: return format_swizzle.a;
578 default:
579 unreachable("Invalid swizzle");
580 }
581 }
582
583
584 VkResult
585 anv_CreateImageView(VkDevice _device,
586 const VkImageViewCreateInfo *pCreateInfo,
587 const VkAllocationCallbacks *pAllocator,
588 VkImageView *pView)
589 {
590 ANV_FROM_HANDLE(anv_device, device, _device);
591 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
592 struct anv_image_view *iview;
593
594 iview = vk_alloc2(&device->alloc, pAllocator, sizeof(*iview), 8,
595 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
596 if (iview == NULL)
597 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
598
599 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
600
601 assert(range->layerCount > 0);
602 assert(range->baseMipLevel < image->levels);
603 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
604 VK_IMAGE_USAGE_STORAGE_BIT |
605 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
606 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
607
608 switch (image->type) {
609 default:
610 unreachable("bad VkImageType");
611 case VK_IMAGE_TYPE_1D:
612 case VK_IMAGE_TYPE_2D:
613 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1 <= image->array_size);
614 break;
615 case VK_IMAGE_TYPE_3D:
616 assert(range->baseArrayLayer + anv_get_layerCount(image, range) - 1
617 <= anv_minify(image->extent.depth, range->baseMipLevel));
618 break;
619 }
620
621 const struct anv_surface *surface =
622 anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
623
624 iview->image = image;
625 iview->bo = image->bo;
626 iview->offset = image->offset + surface->offset;
627
628 iview->aspect_mask = pCreateInfo->subresourceRange.aspectMask;
629 iview->vk_format = pCreateInfo->format;
630
631 struct anv_format format = anv_get_format(&device->info, pCreateInfo->format,
632 range->aspectMask, image->tiling);
633
634 iview->isl = (struct isl_view) {
635 .format = format.isl_format,
636 .base_level = range->baseMipLevel,
637 .levels = anv_get_levelCount(image, range),
638 .base_array_layer = range->baseArrayLayer,
639 .array_len = anv_get_layerCount(image, range),
640 .swizzle = {
641 .r = remap_swizzle(pCreateInfo->components.r,
642 VK_COMPONENT_SWIZZLE_R, format.swizzle),
643 .g = remap_swizzle(pCreateInfo->components.g,
644 VK_COMPONENT_SWIZZLE_G, format.swizzle),
645 .b = remap_swizzle(pCreateInfo->components.b,
646 VK_COMPONENT_SWIZZLE_B, format.swizzle),
647 .a = remap_swizzle(pCreateInfo->components.a,
648 VK_COMPONENT_SWIZZLE_A, format.swizzle),
649 },
650 };
651
652 iview->extent = (VkExtent3D) {
653 .width = anv_minify(image->extent.width , range->baseMipLevel),
654 .height = anv_minify(image->extent.height, range->baseMipLevel),
655 .depth = anv_minify(image->extent.depth , range->baseMipLevel),
656 };
657
658 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_3D) {
659 iview->isl.base_array_layer = 0;
660 iview->isl.array_len = iview->extent.depth;
661 }
662
663 if (pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE ||
664 pCreateInfo->viewType == VK_IMAGE_VIEW_TYPE_CUBE_ARRAY) {
665 iview->isl.usage = ISL_SURF_USAGE_CUBE_BIT;
666 } else {
667 iview->isl.usage = 0;
668 }
669
670 /* Input attachment surfaces for color are allocated and filled
671 * out at BeginRenderPass time because they need compression information.
672 * Compression is not yet enabled for depth textures and stencil doesn't
673 * allow compression so we can just use the texture surface state from the
674 * view.
675 */
676 if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT ||
677 (image->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
678 !(iview->aspect_mask & VK_IMAGE_ASPECT_COLOR_BIT))) {
679 iview->sampler_surface_state = alloc_surface_state(device);
680 iview->no_aux_sampler_surface_state = alloc_surface_state(device);
681
682 /* Sampling is performed in one of two buffer configurations in anv: with
683 * an auxiliary buffer or without it. Sampler states aren't always needed
684 * for both configurations, but are currently created unconditionally for
685 * simplicity.
686 *
687 * TODO: Consider allocating each surface state only when necessary.
688 */
689
690 /* Create a sampler state with the optimal aux_usage for sampling. This
691 * may use the aux_buffer.
692 */
693 const enum isl_aux_usage surf_usage =
694 anv_layout_to_aux_usage(&device->info, image, iview->aspect_mask,
695 VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL);
696
697 /* If this is a HiZ buffer we can sample from with a programmable clear
698 * value (SKL+), define the clear value to the optimal constant.
699 */
700 const float red_clear_color = surf_usage == ISL_AUX_USAGE_HIZ &&
701 device->info.gen >= 9 ?
702 ANV_HZ_FC_VAL : 0.0f;
703
704 struct isl_view view = iview->isl;
705 view.usage |= ISL_SURF_USAGE_TEXTURE_BIT;
706 isl_surf_fill_state(&device->isl_dev,
707 iview->sampler_surface_state.map,
708 .surf = &surface->isl,
709 .view = &view,
710 .clear_color.f32 = { red_clear_color,},
711 .aux_surf = &image->aux_surface.isl,
712 .aux_usage = surf_usage,
713 .mocs = device->default_mocs);
714
715 /* Create a sampler state that only uses the main buffer. */
716 isl_surf_fill_state(&device->isl_dev,
717 iview->no_aux_sampler_surface_state.map,
718 .surf = &surface->isl,
719 .view = &view,
720 .mocs = device->default_mocs);
721
722 anv_state_flush(device, iview->sampler_surface_state);
723 anv_state_flush(device, iview->no_aux_sampler_surface_state);
724 } else {
725 iview->sampler_surface_state.alloc_size = 0;
726 iview->no_aux_sampler_surface_state.alloc_size = 0;
727 }
728
729 /* NOTE: This one needs to go last since it may stomp isl_view.format */
730 if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
731 iview->storage_surface_state = alloc_surface_state(device);
732 iview->writeonly_storage_surface_state = alloc_surface_state(device);
733
734 struct isl_view view = iview->isl;
735 view.usage |= ISL_SURF_USAGE_STORAGE_BIT;
736
737 /* Write-only accesses always used a typed write instruction and should
738 * therefore use the real format.
739 */
740 isl_surf_fill_state(&device->isl_dev,
741 iview->writeonly_storage_surface_state.map,
742 .surf = &surface->isl,
743 .view = &view,
744 .aux_surf = &image->aux_surface.isl,
745 .aux_usage = image->aux_usage,
746 .mocs = device->default_mocs);
747
748 if (isl_has_matching_typed_storage_image_format(&device->info,
749 format.isl_format)) {
750 /* Typed surface reads support a very limited subset of the shader
751 * image formats. Translate it into the closest format the hardware
752 * supports.
753 */
754 view.format = isl_lower_storage_image_format(&device->info,
755 format.isl_format);
756
757 isl_surf_fill_state(&device->isl_dev,
758 iview->storage_surface_state.map,
759 .surf = &surface->isl,
760 .view = &view,
761 .aux_surf = &image->aux_surface.isl,
762 .aux_usage = image->aux_usage,
763 .mocs = device->default_mocs);
764 } else {
765 anv_fill_buffer_surface_state(device, iview->storage_surface_state,
766 ISL_FORMAT_RAW,
767 iview->offset,
768 iview->bo->size - iview->offset, 1);
769 }
770
771 isl_surf_fill_image_param(&device->isl_dev,
772 &iview->storage_image_param,
773 &surface->isl, &iview->isl);
774
775 anv_state_flush(device, iview->storage_surface_state);
776 anv_state_flush(device, iview->writeonly_storage_surface_state);
777 } else {
778 iview->storage_surface_state.alloc_size = 0;
779 iview->writeonly_storage_surface_state.alloc_size = 0;
780 }
781
782 *pView = anv_image_view_to_handle(iview);
783
784 return VK_SUCCESS;
785 }
786
787 void
788 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
789 const VkAllocationCallbacks *pAllocator)
790 {
791 ANV_FROM_HANDLE(anv_device, device, _device);
792 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
793
794 if (!iview)
795 return;
796
797 if (iview->sampler_surface_state.alloc_size > 0) {
798 anv_state_pool_free(&device->surface_state_pool,
799 iview->sampler_surface_state);
800 }
801
802 if (iview->storage_surface_state.alloc_size > 0) {
803 anv_state_pool_free(&device->surface_state_pool,
804 iview->storage_surface_state);
805 }
806
807 if (iview->writeonly_storage_surface_state.alloc_size > 0) {
808 anv_state_pool_free(&device->surface_state_pool,
809 iview->writeonly_storage_surface_state);
810 }
811
812 vk_free2(&device->alloc, pAllocator, iview);
813 }
814
815
816 VkResult
817 anv_CreateBufferView(VkDevice _device,
818 const VkBufferViewCreateInfo *pCreateInfo,
819 const VkAllocationCallbacks *pAllocator,
820 VkBufferView *pView)
821 {
822 ANV_FROM_HANDLE(anv_device, device, _device);
823 ANV_FROM_HANDLE(anv_buffer, buffer, pCreateInfo->buffer);
824 struct anv_buffer_view *view;
825
826 view = vk_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
827 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
828 if (!view)
829 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
830
831 /* TODO: Handle the format swizzle? */
832
833 view->format = anv_get_isl_format(&device->info, pCreateInfo->format,
834 VK_IMAGE_ASPECT_COLOR_BIT,
835 VK_IMAGE_TILING_LINEAR);
836 const uint32_t format_bs = isl_format_get_layout(view->format)->bpb / 8;
837 view->bo = buffer->bo;
838 view->offset = buffer->offset + pCreateInfo->offset;
839 view->range = anv_buffer_get_range(buffer, pCreateInfo->offset,
840 pCreateInfo->range);
841 view->range = align_down_npot_u32(view->range, format_bs);
842
843 if (buffer->usage & VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT) {
844 view->surface_state = alloc_surface_state(device);
845
846 anv_fill_buffer_surface_state(device, view->surface_state,
847 view->format,
848 view->offset, view->range, format_bs);
849 } else {
850 view->surface_state = (struct anv_state){ 0 };
851 }
852
853 if (buffer->usage & VK_BUFFER_USAGE_STORAGE_TEXEL_BUFFER_BIT) {
854 view->storage_surface_state = alloc_surface_state(device);
855 view->writeonly_storage_surface_state = alloc_surface_state(device);
856
857 enum isl_format storage_format =
858 isl_has_matching_typed_storage_image_format(&device->info,
859 view->format) ?
860 isl_lower_storage_image_format(&device->info, view->format) :
861 ISL_FORMAT_RAW;
862
863 anv_fill_buffer_surface_state(device, view->storage_surface_state,
864 storage_format,
865 view->offset, view->range,
866 (storage_format == ISL_FORMAT_RAW ? 1 :
867 isl_format_get_layout(storage_format)->bpb / 8));
868
869 /* Write-only accesses should use the original format. */
870 anv_fill_buffer_surface_state(device, view->writeonly_storage_surface_state,
871 view->format,
872 view->offset, view->range,
873 isl_format_get_layout(view->format)->bpb / 8);
874
875 isl_buffer_fill_image_param(&device->isl_dev,
876 &view->storage_image_param,
877 view->format, view->range);
878 } else {
879 view->storage_surface_state = (struct anv_state){ 0 };
880 view->writeonly_storage_surface_state = (struct anv_state){ 0 };
881 }
882
883 *pView = anv_buffer_view_to_handle(view);
884
885 return VK_SUCCESS;
886 }
887
888 void
889 anv_DestroyBufferView(VkDevice _device, VkBufferView bufferView,
890 const VkAllocationCallbacks *pAllocator)
891 {
892 ANV_FROM_HANDLE(anv_device, device, _device);
893 ANV_FROM_HANDLE(anv_buffer_view, view, bufferView);
894
895 if (!view)
896 return;
897
898 if (view->surface_state.alloc_size > 0)
899 anv_state_pool_free(&device->surface_state_pool,
900 view->surface_state);
901
902 if (view->storage_surface_state.alloc_size > 0)
903 anv_state_pool_free(&device->surface_state_pool,
904 view->storage_surface_state);
905
906 if (view->writeonly_storage_surface_state.alloc_size > 0)
907 anv_state_pool_free(&device->surface_state_pool,
908 view->writeonly_storage_surface_state);
909
910 vk_free2(&device->alloc, pAllocator, view);
911 }
912
913 const struct anv_surface *
914 anv_image_get_surface_for_aspect_mask(const struct anv_image *image,
915 VkImageAspectFlags aspect_mask)
916 {
917 switch (aspect_mask) {
918 case VK_IMAGE_ASPECT_COLOR_BIT:
919 assert(image->aspects == VK_IMAGE_ASPECT_COLOR_BIT);
920 return &image->color_surface;
921 case VK_IMAGE_ASPECT_DEPTH_BIT:
922 assert(image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT);
923 return &image->depth_surface;
924 case VK_IMAGE_ASPECT_STENCIL_BIT:
925 assert(image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT);
926 return &image->stencil_surface;
927 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
928 /* FINISHME: The Vulkan spec (git a511ba2) requires support for
929 * combined depth stencil formats. Specifically, it states:
930 *
931 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
932 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
933 *
934 * Image views with both depth and stencil aspects are only valid for
935 * render target attachments, in which case
936 * cmd_buffer_emit_depth_stencil() will pick out both the depth and
937 * stencil surfaces from the underlying surface.
938 */
939 if (image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) {
940 return &image->depth_surface;
941 } else {
942 assert(image->aspects == VK_IMAGE_ASPECT_STENCIL_BIT);
943 return &image->stencil_surface;
944 }
945 default:
946 unreachable("image does not have aspect");
947 return NULL;
948 }
949 }