0fe2df10a7a66d5d329b71818c04ee357a478fb4
[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->arraySize;
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 VkImage *pImage)
296 {
297 ANV_FROM_HANDLE(anv_device, device, _device);
298 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
299 const VkExtent3D *restrict extent = &pCreateInfo->extent;
300 struct anv_image *image = NULL;
301 VkResult r;
302
303 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
304
305 anv_assert(pCreateInfo->mipLevels > 0);
306 anv_assert(pCreateInfo->arraySize > 0);
307 anv_assert(pCreateInfo->samples == 1);
308 anv_assert(pCreateInfo->extent.width > 0);
309 anv_assert(pCreateInfo->extent.height > 0);
310 anv_assert(pCreateInfo->extent.depth > 0);
311
312 /* TODO(chadv): How should we validate inputs? */
313 const uint8_t surf_type =
314 anv_surf_type_from_image_type[pCreateInfo->imageType];
315
316 const struct anv_surf_type_limits *limits =
317 &anv_surf_type_limits[surf_type];
318
319 /* Errors should be caught by VkImageFormatProperties. */
320 assert(extent->width <= limits->width);
321 assert(extent->height <= limits->height);
322 assert(extent->depth <= limits->depth);
323
324 image = anv_device_alloc(device, sizeof(*image), 8,
325 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
326 if (!image)
327 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
328
329 memset(image, 0, sizeof(*image));
330 image->type = pCreateInfo->imageType;
331 image->extent = pCreateInfo->extent;
332 image->format = anv_format_for_vk_format(pCreateInfo->format);
333 image->levels = pCreateInfo->mipLevels;
334 image->array_size = pCreateInfo->arraySize;
335 image->usage = anv_image_get_full_usage(pCreateInfo);
336 image->surface_type = surf_type;
337
338 if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
339 VK_IMAGE_USAGE_STORAGE_BIT)) {
340 image->needs_nonrt_surface_state = true;
341 }
342
343 if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
344 image->needs_color_rt_surface_state = true;
345 }
346
347 if (likely(anv_format_is_color(image->format))) {
348 r = anv_image_make_surface(device, create_info, image->format,
349 &image->size, &image->alignment,
350 &image->color_surface);
351 if (r != VK_SUCCESS)
352 goto fail;
353 } else {
354 if (image->format->depth_format) {
355 r = anv_image_make_surface(device, create_info, image->format,
356 &image->size, &image->alignment,
357 &image->depth_surface);
358 if (r != VK_SUCCESS)
359 goto fail;
360 }
361
362 if (image->format->has_stencil) {
363 r = anv_image_make_surface(device, create_info, anv_format_s8_uint,
364 &image->size, &image->alignment,
365 &image->stencil_surface);
366 if (r != VK_SUCCESS)
367 goto fail;
368 }
369 }
370
371 *pImage = anv_image_to_handle(image);
372
373 return VK_SUCCESS;
374
375 fail:
376 if (image)
377 anv_device_free(device, image);
378
379 return r;
380 }
381
382 VkResult
383 anv_CreateImage(VkDevice device,
384 const VkImageCreateInfo *pCreateInfo,
385 VkImage *pImage)
386 {
387 return anv_image_create(device,
388 &(struct anv_image_create_info) {
389 .vk_info = pCreateInfo,
390 },
391 pImage);
392 }
393
394 void
395 anv_DestroyImage(VkDevice _device, VkImage _image)
396 {
397 ANV_FROM_HANDLE(anv_device, device, _device);
398
399 anv_device_free(device, anv_image_from_handle(_image));
400 }
401
402 static void
403 anv_surface_get_subresource_layout(struct anv_image *image,
404 struct anv_surface *surface,
405 const VkImageSubresource *subresource,
406 VkSubresourceLayout *layout)
407 {
408 /* If we are on a non-zero mip level or array slice, we need to
409 * calculate a real offset.
410 */
411 anv_assert(subresource->mipLevel == 0);
412 anv_assert(subresource->arrayLayer == 0);
413
414 layout->offset = surface->offset;
415 layout->rowPitch = surface->stride;
416 layout->depthPitch = surface->qpitch;
417
418 /* FINISHME: We really shouldn't be doing this calculation here */
419 if (image->array_size > 1)
420 layout->size = surface->qpitch * image->array_size;
421 else
422 layout->size = surface->stride * image->extent.height;
423 }
424
425 void anv_GetImageSubresourceLayout(
426 VkDevice device,
427 VkImage _image,
428 const VkImageSubresource* pSubresource,
429 VkSubresourceLayout* pLayout)
430 {
431 ANV_FROM_HANDLE(anv_image, image, _image);
432
433 switch (pSubresource->aspect) {
434 case VK_IMAGE_ASPECT_COLOR:
435 anv_surface_get_subresource_layout(image, &image->color_surface,
436 pSubresource, pLayout);
437 break;
438 case VK_IMAGE_ASPECT_DEPTH:
439 anv_surface_get_subresource_layout(image, &image->depth_surface,
440 pSubresource, pLayout);
441 break;
442 case VK_IMAGE_ASPECT_STENCIL:
443 anv_surface_get_subresource_layout(image, &image->stencil_surface,
444 pSubresource, pLayout);
445 break;
446 default:
447 assert(!"Invalid image aspect");
448 }
449 }
450
451 VkResult
452 anv_validate_CreateImageView(VkDevice _device,
453 const VkImageViewCreateInfo *pCreateInfo,
454 VkImageView *pView)
455 {
456 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
457 const VkImageSubresourceRange *subresource;
458 const struct anv_image_view_info *view_info;
459 const struct anv_format *view_format_info;
460
461 /* Validate structure type before dereferencing it. */
462 assert(pCreateInfo);
463 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
464 subresource = &pCreateInfo->subresourceRange;
465
466 /* Validate viewType is in range before using it. */
467 assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
468 assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
469 view_info = &anv_image_view_info_table[pCreateInfo->viewType];
470
471 /* Validate format is in range before using it. */
472 assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
473 assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
474 view_format_info = anv_format_for_vk_format(pCreateInfo->format);
475
476 /* Validate channel swizzles. */
477 assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
478 assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
479 assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
480 assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
481 assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
482 assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
483 assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
484 assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
485
486 /* Validate subresource. */
487 assert(subresource->aspectMask != 0);
488 assert(subresource->mipLevels > 0);
489 assert(subresource->arraySize > 0);
490 assert(subresource->baseMipLevel < image->levels);
491 assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
492 assert(subresource->baseArrayLayer < image->array_size);
493 assert(subresource->baseArrayLayer + subresource->arraySize <= image->array_size);
494 assert(pView);
495
496 if (view_info->is_cube) {
497 assert(subresource->baseArrayLayer % 6 == 0);
498 assert(subresource->arraySize % 6 == 0);
499 }
500
501 const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
502 | VK_IMAGE_ASPECT_STENCIL_BIT;
503
504 /* Validate format. */
505 if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
506 assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
507 assert(!image->format->depth_format);
508 assert(!image->format->has_stencil);
509 assert(!view_format_info->depth_format);
510 assert(!view_format_info->has_stencil);
511 assert(view_format_info->isl_layout->bs ==
512 image->format->isl_layout->bs);
513 } else if (subresource->aspectMask & ds_flags) {
514 assert((subresource->aspectMask & ~ds_flags) == 0);
515
516 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
517 assert(image->format->depth_format);
518 assert(view_format_info->depth_format);
519 assert(view_format_info->isl_layout->bs ==
520 image->format->isl_layout->bs);
521 }
522
523 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL) {
524 /* FINISHME: Is it legal to have an R8 view of S8? */
525 assert(image->format->has_stencil);
526 assert(view_format_info->has_stencil);
527 }
528 } else {
529 assert(!"bad VkImageSubresourceRange::aspectFlags");
530 }
531
532 return anv_CreateImageView(_device, pCreateInfo, pView);
533 }
534
535 void
536 anv_image_view_init(struct anv_image_view *iview,
537 struct anv_device *device,
538 const VkImageViewCreateInfo* pCreateInfo,
539 struct anv_cmd_buffer *cmd_buffer)
540 {
541 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
542 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
543
544 assert(range->arraySize > 0);
545 assert(range->baseMipLevel < image->levels);
546 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
547 VK_IMAGE_USAGE_STORAGE_BIT |
548 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
549 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
550
551 switch (image->type) {
552 default:
553 unreachable("bad VkImageType");
554 case VK_IMAGE_TYPE_1D:
555 case VK_IMAGE_TYPE_2D:
556 assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
557 break;
558 case VK_IMAGE_TYPE_3D:
559 assert(range->baseArrayLayer + range->arraySize - 1
560 <= anv_minify(image->extent.depth, range->baseMipLevel));
561 break;
562 }
563
564 switch (device->info.gen) {
565 case 7:
566 if (device->info.is_haswell)
567 gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
568 else
569 gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
570 break;
571 case 8:
572 gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
573 break;
574 case 9:
575 gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
576 break;
577 default:
578 unreachable("unsupported gen\n");
579 }
580 }
581
582 VkResult
583 anv_CreateImageView(VkDevice _device,
584 const VkImageViewCreateInfo *pCreateInfo,
585 VkImageView *pView)
586 {
587 ANV_FROM_HANDLE(anv_device, device, _device);
588 struct anv_image_view *view;
589
590 view = anv_device_alloc(device, sizeof(*view), 8,
591 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
592 if (view == NULL)
593 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
594
595 anv_image_view_init(view, device, pCreateInfo, NULL);
596
597 *pView = anv_image_view_to_handle(view);
598
599 return VK_SUCCESS;
600 }
601
602 static void
603 anv_image_view_destroy(struct anv_device *device,
604 struct anv_image_view *iview)
605 {
606 if (iview->image->needs_color_rt_surface_state) {
607 anv_state_pool_free(&device->surface_state_pool,
608 iview->color_rt_surface_state);
609 }
610
611 if (iview->image->needs_nonrt_surface_state) {
612 anv_state_pool_free(&device->surface_state_pool,
613 iview->nonrt_surface_state);
614 }
615
616 anv_device_free(device, iview);
617 }
618
619 void
620 anv_DestroyImageView(VkDevice _device, VkImageView _iview)
621 {
622 ANV_FROM_HANDLE(anv_device, device, _device);
623 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
624
625 anv_image_view_destroy(device, iview);
626 }
627
628 struct anv_surface *
629 anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
630 {
631 switch (aspect_mask) {
632 case VK_IMAGE_ASPECT_COLOR_BIT:
633 /* Dragons will eat you.
634 *
635 * Meta attaches all destination surfaces as color render targets. Guess
636 * what surface the Meta Dragons really want.
637 */
638 if (image->format->depth_format && image->format->has_stencil) {
639 anv_finishme("combined depth stencil formats");
640 return &image->depth_surface;
641 } else if (image->format->depth_format) {
642 return &image->depth_surface;
643 } else if (image->format->has_stencil) {
644 return &image->stencil_surface;
645 } else {
646 return &image->color_surface;
647 }
648 break;
649 case VK_IMAGE_ASPECT_DEPTH_BIT:
650 assert(image->format->depth_format);
651 return &image->depth_surface;
652 case VK_IMAGE_ASPECT_STENCIL_BIT:
653 assert(image->format->has_stencil);
654 return &image->stencil_surface;
655 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
656 if (image->format->depth_format && image->format->has_stencil) {
657 /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
658 * depth stencil formats. Specifically, it states:
659 *
660 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
661 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
662 */
663 anv_finishme("combined depthstencil aspect");
664 return &image->depth_surface;
665 } else if (image->format->depth_format) {
666 return &image->depth_surface;
667 } else if (image->format->has_stencil) {
668 return &image->stencil_surface;
669 }
670 /* fallthrough */
671 default:
672 unreachable("image does not have aspect");
673 return NULL;
674 }
675 }
676
677 #if 0
678 VkImageAspectFlags aspect_mask = 0;
679 if (format->depth_format)
680 aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
681 if (format->has_stencil)
682 aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
683 if (!aspect_mask)
684 aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
685
686 anv_image_view_init(iview, device,
687 &(VkImageViewCreateInfo) {
688 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
689 .image = info->image,
690 .viewType = VK_IMAGE_VIEW_TYPE_2D,
691 .format = info->format,
692 .channels = {
693 .r = VK_CHANNEL_SWIZZLE_R,
694 .g = VK_CHANNEL_SWIZZLE_G,
695 .b = VK_CHANNEL_SWIZZLE_B,
696 .a = VK_CHANNEL_SWIZZLE_A,
697 },
698 .subresourceRange = {
699 .aspectMask = aspect_mask,
700 .baseMipLevel = info->mipLevel,
701 .mipLevels = 1,
702 .baseArrayLayer = info->baseArraySlice,
703 .arraySize = info->arraySize,
704 },
705 },
706 NULL);
707 #endif