anv/image: Vulkan's depthPitch is in bytes, not rows
[mesa.git] / src / 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
30 #include "anv_private.h"
31
32 /* FIXME: We shouldn't be using the actual hardware enum values here. They
33 * change across gens. Once we get that fixed, this include needs to go.
34 */
35 #include "gen8_pack.h"
36
37 static const uint8_t anv_halign[] = {
38 [4] = HALIGN4,
39 [8] = HALIGN8,
40 [16] = HALIGN16,
41 };
42
43 static const uint8_t anv_valign[] = {
44 [4] = VALIGN4,
45 [8] = VALIGN8,
46 [16] = VALIGN16,
47 };
48
49 static const uint8_t anv_surf_type_from_image_type[] = {
50 [VK_IMAGE_TYPE_1D] = SURFTYPE_1D,
51 [VK_IMAGE_TYPE_2D] = SURFTYPE_2D,
52 [VK_IMAGE_TYPE_3D] = SURFTYPE_3D,
53 };
54
55 static const struct anv_image_view_info
56 anv_image_view_info_table[] = {
57 #define INFO(s, ...) { .surface_type = s, __VA_ARGS__ }
58 [VK_IMAGE_VIEW_TYPE_1D] = INFO(SURFTYPE_1D),
59 [VK_IMAGE_VIEW_TYPE_2D] = INFO(SURFTYPE_2D),
60 [VK_IMAGE_VIEW_TYPE_3D] = INFO(SURFTYPE_3D),
61 [VK_IMAGE_VIEW_TYPE_CUBE] = INFO(SURFTYPE_CUBE, .is_cube = 1),
62 [VK_IMAGE_VIEW_TYPE_1D_ARRAY] = INFO(SURFTYPE_1D, .is_array = 1),
63 [VK_IMAGE_VIEW_TYPE_2D_ARRAY] = INFO(SURFTYPE_2D, .is_array = 1),
64 [VK_IMAGE_VIEW_TYPE_CUBE_ARRAY] = INFO(SURFTYPE_CUBE, .is_array = 1, .is_cube = 1),
65 #undef INFO
66 };
67
68 struct anv_image_view_info
69 anv_image_view_info_for_vk_image_view_type(VkImageViewType type)
70 {
71 return anv_image_view_info_table[type];
72 }
73
74 static const struct anv_surf_type_limits {
75 int32_t width;
76 int32_t height;
77 int32_t depth;
78 } anv_surf_type_limits[] = {
79 [SURFTYPE_1D] = {16384, 1, 2048},
80 [SURFTYPE_2D] = {16384, 16384, 2048},
81 [SURFTYPE_3D] = {2048, 2048, 2048},
82 [SURFTYPE_CUBE] = {16384, 16384, 340},
83 [SURFTYPE_BUFFER] = {128, 16384, 64},
84 [SURFTYPE_STRBUF] = {128, 16384, 64},
85 };
86
87 static const struct anv_tile_info {
88 /**
89 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
90 *
91 * To simplify calculations, the alignments defined in the table are
92 * sometimes larger than required. For example, Skylake requires that X and
93 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
94 * alignment. We choose 4K to accomodate both chipsets. The alignment of
95 * a linear buffer depends on its element type and usage. Linear depth
96 * buffers have the largest alignment, 64B, so we choose that for all linear
97 * buffers.
98 */
99 uint32_t surface_alignment;
100 } anv_tile_info_table[] = {
101 [ISL_TILING_LINEAR] = { 64 },
102 [ISL_TILING_X] = { 4096 },
103 [ISL_TILING_Y] = { 4096 },
104 [ISL_TILING_Yf] = { 4096 },
105 [ISL_TILING_Ys] = { 4096 },
106 [ISL_TILING_W] = { 4096 },
107 };
108
109 static enum isl_tiling
110 anv_image_choose_tiling(const struct anv_image_create_info *anv_info)
111 {
112 if (anv_info->force_tiling)
113 return anv_info->tiling;
114
115 /* The Sandybridge PRM says that the stencil buffer "is supported
116 * only in Tile W memory".
117 */
118
119 switch (anv_info->vk_info->tiling) {
120 case VK_IMAGE_TILING_LINEAR:
121 assert(anv_info->vk_info->format != VK_FORMAT_S8_UINT);
122 return ISL_TILING_LINEAR;
123 case VK_IMAGE_TILING_OPTIMAL:
124 if (unlikely(anv_info->vk_info->format == VK_FORMAT_S8_UINT)) {
125 return ISL_TILING_W;
126 } else {
127 return ISL_TILING_Y;
128 }
129 default:
130 assert(!"bad VKImageTiling");
131 return ISL_TILING_LINEAR;
132 }
133 }
134
135
136 /**
137 * The \a format argument is required and overrides any format in
138 * struct anv_image_create_info.
139 */
140 static VkResult
141 anv_image_make_surface(const struct anv_device *dev,
142 const struct anv_image_create_info *create_info,
143 const struct anv_format *format,
144 uint64_t *inout_image_size,
145 uint32_t *inout_image_alignment,
146 struct anv_surface *out_surface)
147 {
148 /* See RENDER_SURFACE_STATE.SurfaceQPitch */
149 static const uint16_t min_qpitch UNUSED = 0x4;
150 static const uint16_t max_qpitch UNUSED = 0x1ffc;
151
152 const VkExtent3D *restrict extent = &create_info->vk_info->extent;
153 const uint32_t levels = create_info->vk_info->mipLevels;
154 const uint32_t array_size = create_info->vk_info->arrayLayers;
155 const enum isl_tiling tiling = anv_image_choose_tiling(create_info);
156
157 const struct anv_tile_info *tile_info =
158 &anv_tile_info_table[tiling];
159
160 const uint32_t bs = format->isl_layout->bs;
161 const uint32_t bw = format->isl_layout->bw;
162 const uint32_t bh = format->isl_layout->bh;
163
164 struct isl_extent2d tile_extent;
165 isl_tiling_get_extent(&dev->isl_dev, tiling, bs, &tile_extent);
166
167 const uint32_t i = MAX(4, bw); /* FINISHME: Stop hardcoding subimage alignment */
168 const uint32_t j = MAX(4, bh); /* FINISHME: Stop hardcoding subimage alignment */
169 assert(i == 4 || i == 8 || i == 16);
170 assert(j == 4 || j == 8 || j == 16);
171
172 uint16_t qpitch = min_qpitch;
173 uint32_t mt_width = 0;
174 uint32_t mt_height = 0;
175
176 switch (create_info->vk_info->imageType) {
177 case VK_IMAGE_TYPE_1D:
178 /* From the Broadwell PRM >> Memory Views >> Common Surface Formats >>
179 * Surface Layout >> 1D Surfaces:
180 *
181 * One-dimensional surfaces are identical to 2D surfaces with height of one.
182 *
183 * So fallthrough...
184 */
185 case VK_IMAGE_TYPE_2D: {
186 const uint32_t w0 = align_u32(extent->width, i);
187 const uint32_t h0 = align_u32(extent->height, j);
188
189 if (levels == 1 && array_size == 1) {
190 qpitch = min_qpitch;
191 mt_width = w0;
192 mt_height = h0;
193 } else {
194 uint32_t w1 = align_u32(anv_minify(extent->width, 1), i);
195 uint32_t h1 = align_u32(anv_minify(extent->height, 1), j);
196 uint32_t w2 = align_u32(anv_minify(extent->width, 2), i);
197
198 /* The QPitch equation is found in the Broadwell PRM >> Volume 5: Memory
199 * Views >> Common Surface Formats >> Surface Layout >> 2D Surfaces >>
200 * Surface Arrays >> For All Surface Other Than Separate Stencil Buffer:
201 */
202 assert(bh ==1 || bh == 4);
203 qpitch = (h0 + h1 + 11 * j) / bh;
204 mt_width = MAX(w0, w1 + w2);
205 mt_height = array_size * qpitch;
206 }
207 break;
208 }
209 case VK_IMAGE_TYPE_3D:
210 /* The layout of 3D surfaces is described by the Broadwell PRM >>
211 * Volume 5: Memory Views >> Common Surface Formats >> Surface Layout >>
212 * 3D Surfaces.
213 */
214 for (uint32_t l = 0; l < levels; ++l) {
215 const uint32_t w_l = align_u32(anv_minify(extent->width, l), i);
216 const uint32_t h_l = align_u32(anv_minify(extent->height, l), j);
217 const uint32_t d_l = anv_minify(extent->depth, l);
218
219 const uint32_t max_layers_horiz = MIN(d_l, 1u << l);
220 const uint32_t max_layers_vert = align_u32(d_l, 1u << l) / (1u << l);
221
222 mt_width = MAX(mt_width, w_l * max_layers_horiz);
223 mt_height += h_l * max_layers_vert;
224 }
225 break;
226 default:
227 unreachable(!"bad VkImageType");
228 }
229
230 assert(qpitch >= min_qpitch);
231 if (qpitch > max_qpitch) {
232 anv_loge("image qpitch > 0x%x\n", max_qpitch);
233 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
234 }
235
236 /* From the Broadwell PRM, RENDER_SURFACE_STATE.SurfaceQpitch:
237 *
238 * This field must be set an integer multiple of the Surface Vertical
239 * Alignment.
240 */
241 assert(anv_is_aligned(qpitch, j));
242
243 uint32_t stride = align_u32(mt_width * bs / bw, tile_extent.width);
244 if (create_info->stride > 0)
245 stride = create_info->stride;
246
247 /* The padding requirement is found in the Broadwell PRM >> Volume 5: Memory
248 * Views >> Common Surface Formats >> Surface Padding Requirements >>
249 * Sampling Engine Surfaces >> Buffer Padding Requirements:
250 */
251 const uint32_t mem_rows = align_u32(mt_height / bh, 2 * bh);
252 const uint32_t size = stride * align_u32(mem_rows, tile_extent.height);
253 const uint32_t offset = align_u32(*inout_image_size,
254 tile_info->surface_alignment);
255
256 *inout_image_size = offset + size;
257 *inout_image_alignment = MAX(*inout_image_alignment,
258 tile_info->surface_alignment);
259
260 *out_surface = (struct anv_surface) {
261 .offset = offset,
262 .stride = stride,
263 .tiling = tiling,
264 .qpitch = qpitch,
265 .h_align = i,
266 .v_align = j,
267 };
268
269 return VK_SUCCESS;
270 }
271
272 static VkImageUsageFlags
273 anv_image_get_full_usage(const VkImageCreateInfo *info)
274 {
275 VkImageUsageFlags usage = info->usage;
276
277 if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
278 /* Meta will transfer from the image by binding it as a texture. */
279 usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
280 }
281
282 if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
283 /* Meta will transfer to the image by binding it as a color attachment,
284 * even if the image format is not a color format.
285 */
286 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
287 }
288
289 return usage;
290 }
291
292 VkResult
293 anv_image_create(VkDevice _device,
294 const struct anv_image_create_info *create_info,
295 const VkAllocationCallbacks* alloc,
296 VkImage *pImage)
297 {
298 ANV_FROM_HANDLE(anv_device, device, _device);
299 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
300 const VkExtent3D *restrict extent = &pCreateInfo->extent;
301 struct anv_image *image = NULL;
302 VkResult r;
303
304 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
305
306 anv_assert(pCreateInfo->mipLevels > 0);
307 anv_assert(pCreateInfo->arrayLayers > 0);
308 anv_assert(pCreateInfo->samples == VK_SAMPLE_COUNT_1_BIT);
309 anv_assert(pCreateInfo->extent.width > 0);
310 anv_assert(pCreateInfo->extent.height > 0);
311 anv_assert(pCreateInfo->extent.depth > 0);
312
313 /* TODO(chadv): How should we validate inputs? */
314 const uint8_t surf_type =
315 anv_surf_type_from_image_type[pCreateInfo->imageType];
316
317 const struct anv_surf_type_limits *limits =
318 &anv_surf_type_limits[surf_type];
319
320 /* Errors should be caught by VkImageFormatProperties. */
321 assert(extent->width <= limits->width);
322 assert(extent->height <= limits->height);
323 assert(extent->depth <= limits->depth);
324
325 image = anv_alloc2(&device->alloc, alloc, sizeof(*image), 8,
326 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
327 if (!image)
328 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
329
330 memset(image, 0, sizeof(*image));
331 image->type = pCreateInfo->imageType;
332 image->extent = pCreateInfo->extent;
333 image->format = anv_format_for_vk_format(pCreateInfo->format);
334 image->levels = pCreateInfo->mipLevels;
335 image->array_size = pCreateInfo->arrayLayers;
336 image->usage = anv_image_get_full_usage(pCreateInfo);
337 image->surface_type = surf_type;
338
339 if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
340 VK_IMAGE_USAGE_STORAGE_BIT)) {
341 image->needs_nonrt_surface_state = true;
342 }
343
344 if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
345 image->needs_color_rt_surface_state = true;
346 }
347
348 if (likely(anv_format_is_color(image->format))) {
349 r = anv_image_make_surface(device, create_info, image->format,
350 &image->size, &image->alignment,
351 &image->color_surface);
352 if (r != VK_SUCCESS)
353 goto fail;
354 } else {
355 if (image->format->depth_format) {
356 r = anv_image_make_surface(device, create_info, image->format,
357 &image->size, &image->alignment,
358 &image->depth_surface);
359 if (r != VK_SUCCESS)
360 goto fail;
361 }
362
363 if (image->format->has_stencil) {
364 r = anv_image_make_surface(device, create_info, anv_format_s8_uint,
365 &image->size, &image->alignment,
366 &image->stencil_surface);
367 if (r != VK_SUCCESS)
368 goto fail;
369 }
370 }
371
372 *pImage = anv_image_to_handle(image);
373
374 return VK_SUCCESS;
375
376 fail:
377 if (image)
378 anv_free2(&device->alloc, alloc, image);
379
380 return r;
381 }
382
383 VkResult
384 anv_CreateImage(VkDevice device,
385 const VkImageCreateInfo *pCreateInfo,
386 const VkAllocationCallbacks *pAllocator,
387 VkImage *pImage)
388 {
389 return anv_image_create(device,
390 &(struct anv_image_create_info) {
391 .vk_info = pCreateInfo,
392 },
393 pAllocator,
394 pImage);
395 }
396
397 void
398 anv_DestroyImage(VkDevice _device, VkImage _image,
399 const VkAllocationCallbacks *pAllocator)
400 {
401 ANV_FROM_HANDLE(anv_device, device, _device);
402
403 anv_free2(&device->alloc, pAllocator, anv_image_from_handle(_image));
404 }
405
406 static void
407 anv_surface_get_subresource_layout(struct anv_image *image,
408 struct anv_surface *surface,
409 const VkImageSubresource *subresource,
410 VkSubresourceLayout *layout)
411 {
412 /* If we are on a non-zero mip level or array slice, we need to
413 * calculate a real offset.
414 */
415 anv_assert(subresource->mipLevel == 0);
416 anv_assert(subresource->arrayLayer == 0);
417
418 layout->offset = surface->offset;
419 layout->rowPitch = surface->stride;
420
421 /* Anvil's qpitch is in units of rows. Vulkan's depthPitch is in bytes. */
422 layout->depthPitch = surface->qpitch * surface->stride;
423
424 /* FINISHME: We really shouldn't be doing this calculation here */
425 if (image->array_size > 1)
426 layout->size = surface->qpitch * image->array_size;
427 else
428 layout->size = surface->stride * image->extent.height;
429 }
430
431 void anv_GetImageSubresourceLayout(
432 VkDevice device,
433 VkImage _image,
434 const VkImageSubresource* pSubresource,
435 VkSubresourceLayout* pLayout)
436 {
437 ANV_FROM_HANDLE(anv_image, image, _image);
438
439 assert(__builtin_popcount(pSubresource->aspectMask) == 1);
440
441 switch (pSubresource->aspectMask) {
442 case VK_IMAGE_ASPECT_COLOR_BIT:
443 anv_surface_get_subresource_layout(image, &image->color_surface,
444 pSubresource, pLayout);
445 break;
446 case VK_IMAGE_ASPECT_DEPTH_BIT:
447 anv_surface_get_subresource_layout(image, &image->depth_surface,
448 pSubresource, pLayout);
449 break;
450 case VK_IMAGE_ASPECT_STENCIL_BIT:
451 anv_surface_get_subresource_layout(image, &image->stencil_surface,
452 pSubresource, pLayout);
453 break;
454 default:
455 assert(!"Invalid image aspect");
456 }
457 }
458
459 VkResult
460 anv_validate_CreateImageView(VkDevice _device,
461 const VkImageViewCreateInfo *pCreateInfo,
462 const VkAllocationCallbacks *pAllocator,
463 VkImageView *pView)
464 {
465 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
466 const VkImageSubresourceRange *subresource;
467 const struct anv_image_view_info *view_info;
468 const struct anv_format *view_format_info;
469
470 /* Validate structure type before dereferencing it. */
471 assert(pCreateInfo);
472 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
473 subresource = &pCreateInfo->subresourceRange;
474
475 /* Validate viewType is in range before using it. */
476 assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
477 assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
478 view_info = &anv_image_view_info_table[pCreateInfo->viewType];
479
480 /* Validate format is in range before using it. */
481 assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
482 assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
483 view_format_info = anv_format_for_vk_format(pCreateInfo->format);
484
485 /* Validate channel swizzles. */
486 assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
487 assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
488 assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
489 assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
490 assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
491 assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
492 assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
493 assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
494
495 /* Validate subresource. */
496 assert(subresource->aspectMask != 0);
497 assert(subresource->levelCount > 0);
498 assert(subresource->layerCount > 0);
499 assert(subresource->baseMipLevel < image->levels);
500 assert(subresource->baseMipLevel + subresource->levelCount <= image->levels);
501 assert(subresource->baseArrayLayer < image->array_size);
502 assert(subresource->baseArrayLayer + subresource->layerCount <= image->array_size);
503 assert(pView);
504
505 if (view_info->is_cube) {
506 assert(subresource->baseArrayLayer % 6 == 0);
507 assert(subresource->layerCount % 6 == 0);
508 }
509
510 const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
511 | VK_IMAGE_ASPECT_STENCIL_BIT;
512
513 /* Validate format. */
514 if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
515 assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
516 assert(!image->format->depth_format);
517 assert(!image->format->has_stencil);
518 assert(!view_format_info->depth_format);
519 assert(!view_format_info->has_stencil);
520 assert(view_format_info->isl_layout->bs ==
521 image->format->isl_layout->bs);
522 } else if (subresource->aspectMask & ds_flags) {
523 assert((subresource->aspectMask & ~ds_flags) == 0);
524
525 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
526 assert(image->format->depth_format);
527 assert(view_format_info->depth_format);
528 assert(view_format_info->isl_layout->bs ==
529 image->format->isl_layout->bs);
530 }
531
532 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
533 /* FINISHME: Is it legal to have an R8 view of S8? */
534 assert(image->format->has_stencil);
535 assert(view_format_info->has_stencil);
536 }
537 } else {
538 assert(!"bad VkImageSubresourceRange::aspectFlags");
539 }
540
541 return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView);
542 }
543
544 void
545 anv_image_view_init(struct anv_image_view *iview,
546 struct anv_device *device,
547 const VkImageViewCreateInfo* pCreateInfo,
548 struct anv_cmd_buffer *cmd_buffer)
549 {
550 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
551 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
552
553 assert(range->layerCount > 0);
554 assert(range->baseMipLevel < image->levels);
555 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
556 VK_IMAGE_USAGE_STORAGE_BIT |
557 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
558 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
559
560 switch (image->type) {
561 default:
562 unreachable("bad VkImageType");
563 case VK_IMAGE_TYPE_1D:
564 case VK_IMAGE_TYPE_2D:
565 assert(range->baseArrayLayer + range->layerCount - 1 <= image->array_size);
566 break;
567 case VK_IMAGE_TYPE_3D:
568 assert(range->baseArrayLayer + range->layerCount - 1
569 <= anv_minify(image->extent.depth, range->baseMipLevel));
570 break;
571 }
572
573 switch (device->info.gen) {
574 case 7:
575 if (device->info.is_haswell)
576 gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
577 else
578 gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
579 break;
580 case 8:
581 gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
582 break;
583 case 9:
584 gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
585 break;
586 default:
587 unreachable("unsupported gen\n");
588 }
589 }
590
591 VkResult
592 anv_CreateImageView(VkDevice _device,
593 const VkImageViewCreateInfo *pCreateInfo,
594 const VkAllocationCallbacks *pAllocator,
595 VkImageView *pView)
596 {
597 ANV_FROM_HANDLE(anv_device, device, _device);
598 struct anv_image_view *view;
599
600 view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
601 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
602 if (view == NULL)
603 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
604
605 anv_image_view_init(view, device, pCreateInfo, NULL);
606
607 *pView = anv_image_view_to_handle(view);
608
609 return VK_SUCCESS;
610 }
611
612 void
613 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
614 const VkAllocationCallbacks *pAllocator)
615 {
616 ANV_FROM_HANDLE(anv_device, device, _device);
617 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
618
619 if (iview->image->needs_color_rt_surface_state) {
620 anv_state_pool_free(&device->surface_state_pool,
621 iview->color_rt_surface_state);
622 }
623
624 if (iview->image->needs_nonrt_surface_state) {
625 anv_state_pool_free(&device->surface_state_pool,
626 iview->nonrt_surface_state);
627 }
628
629 anv_free2(&device->alloc, pAllocator, iview);
630 }
631
632 struct anv_surface *
633 anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
634 {
635 switch (aspect_mask) {
636 case VK_IMAGE_ASPECT_COLOR_BIT:
637 /* Dragons will eat you.
638 *
639 * Meta attaches all destination surfaces as color render targets. Guess
640 * what surface the Meta Dragons really want.
641 */
642 if (image->format->depth_format && image->format->has_stencil) {
643 anv_finishme("combined depth stencil formats");
644 return &image->depth_surface;
645 } else if (image->format->depth_format) {
646 return &image->depth_surface;
647 } else if (image->format->has_stencil) {
648 return &image->stencil_surface;
649 } else {
650 return &image->color_surface;
651 }
652 break;
653 case VK_IMAGE_ASPECT_DEPTH_BIT:
654 assert(image->format->depth_format);
655 return &image->depth_surface;
656 case VK_IMAGE_ASPECT_STENCIL_BIT:
657 assert(image->format->has_stencil);
658 return &image->stencil_surface;
659 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
660 if (image->format->depth_format && image->format->has_stencil) {
661 /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
662 * depth stencil formats. Specifically, it states:
663 *
664 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
665 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
666 */
667 anv_finishme("combined depthstencil aspect");
668 return &image->depth_surface;
669 } else if (image->format->depth_format) {
670 return &image->depth_surface;
671 } else if (image->format->has_stencil) {
672 return &image->stencil_surface;
673 }
674 /* fallthrough */
675 default:
676 unreachable("image does not have aspect");
677 return NULL;
678 }
679 }
680
681 #if 0
682 VkImageAspectFlags aspect_mask = 0;
683 if (format->depth_format)
684 aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
685 if (format->has_stencil)
686 aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
687 if (!aspect_mask)
688 aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
689
690 anv_image_view_init(iview, device,
691 &(VkImageViewCreateInfo) {
692 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
693 .image = info->image,
694 .viewType = VK_IMAGE_VIEW_TYPE_2D,
695 .format = info->format,
696 .channels = {
697 .r = VK_CHANNEL_SWIZZLE_R,
698 .g = VK_CHANNEL_SWIZZLE_G,
699 .b = VK_CHANNEL_SWIZZLE_B,
700 .a = VK_CHANNEL_SWIZZLE_A,
701 },
702 .subresourceRange = {
703 .aspectMask = aspect_mask,
704 .baseMipLevel = info->mipLevel,
705 .mipLevels = 1,
706 .baseArrayLayer = info->baseArraySlice,
707 .arraySize = info->arraySize,
708 },
709 },
710 NULL);
711 #endif