anv/image: Use isl to calculate surface layout
[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 isl_tiling_flags_t
88 choose_isl_tiling_flags(const struct anv_image_create_info *anv_info)
89 {
90 const VkImageCreateInfo *vk_info = anv_info->vk_info;
91
92 if (anv_info->force_tiling) {
93 return 1u << anv_info->tiling;
94 } else if (vk_info->tiling == VK_IMAGE_TILING_LINEAR) {
95 return ISL_TILING_LINEAR_BIT;
96 } else if (vk_info->tiling == VK_IMAGE_TILING_OPTIMAL) {
97 return ISL_TILING_ANY_MASK;
98 } else {
99 unreachable("bad anv_image_create_info");
100 return 0;
101 }
102 }
103
104 /**
105 * The \a format argument is required and overrides any format found in struct
106 * anv_image_create_info.
107 */
108 static isl_surf_usage_flags_t
109 choose_isl_surf_usage(const struct anv_image_create_info *info,
110 const struct anv_format *format)
111 {
112 const VkImageCreateInfo *vk_info = info->vk_info;
113 isl_surf_usage_flags_t isl_flags = 0;
114
115 /* FINISHME: Support aux surfaces */
116 isl_flags |= ISL_SURF_USAGE_DISABLE_AUX_BIT;
117
118 if (vk_info->usage & VK_IMAGE_USAGE_SAMPLED_BIT)
119 isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
120
121 if (vk_info->usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT)
122 isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
123
124 if (vk_info->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT)
125 isl_flags |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
126
127 if (vk_info->flags & VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT)
128 isl_flags |= ISL_SURF_USAGE_CUBE_BIT;
129
130 if (vk_info->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
131 assert((format->depth_format != 0) ^ format->has_stencil);
132
133 if (format->depth_format) {
134 isl_flags |= ISL_SURF_USAGE_DEPTH_BIT;
135 } else if (format->has_stencil) {
136 isl_flags |= ISL_SURF_USAGE_STENCIL_BIT;
137 }
138 }
139
140 if (vk_info->usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
141 /* Meta implements transfers by sampling from the source image. */
142 isl_flags |= ISL_SURF_USAGE_TEXTURE_BIT;
143 }
144
145 if (vk_info->usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
146 /* Meta implements transfers by rendering into the destination image. */
147 isl_flags |= ISL_SURF_USAGE_RENDER_TARGET_BIT;
148 }
149
150 return isl_flags;
151 }
152
153 /**
154 * The \a format argument is required and overrides any format in
155 * struct anv_image_create_info.
156 */
157 static VkResult
158 anv_image_make_surface(const struct anv_device *dev,
159 const struct anv_image_create_info *anv_info,
160 const struct anv_format *format,
161 uint64_t *inout_image_size,
162 uint32_t *inout_image_alignment,
163 struct anv_surface *out_surface)
164 {
165 const VkImageCreateInfo *vk_info = anv_info->vk_info;
166
167 static const enum isl_surf_dim vk_to_isl_surf_dim[] = {
168 [VK_IMAGE_TYPE_1D] = ISL_SURF_DIM_1D,
169 [VK_IMAGE_TYPE_2D] = ISL_SURF_DIM_2D,
170 [VK_IMAGE_TYPE_3D] = ISL_SURF_DIM_3D,
171 };
172
173 struct isl_surf isl_surf;
174 isl_surf_init(&dev->isl_dev, &isl_surf,
175 .dim = vk_to_isl_surf_dim[vk_info->imageType],
176 .format = format->surface_format,
177 .width = vk_info->extent.width,
178 .height = vk_info->extent.height,
179 .depth = vk_info->extent.depth,
180 .levels = vk_info->mipLevels,
181 .array_len = vk_info->arrayLayers,
182 .samples = vk_info->samples,
183 .min_alignment = 0,
184 .min_pitch = 0,
185 .usage = choose_isl_surf_usage(anv_info, format),
186 .tiling_flags = choose_isl_tiling_flags(anv_info));
187
188 *out_surface = (struct anv_surface) {
189 .offset = align_u32(*inout_image_size, isl_surf.alignment),
190 .stride = isl_surf.row_pitch,
191 .tiling = isl_surf.tiling,
192 .qpitch = isl_surf_get_array_pitch_sa_rows(&isl_surf),
193 .h_align = isl_surf_get_lod_alignment_sa(&isl_surf).width,
194 .v_align = isl_surf_get_lod_alignment_sa(&isl_surf).height,
195 };
196
197 *inout_image_size = out_surface->offset + isl_surf.size;
198 *inout_image_alignment = MAX(*inout_image_alignment, isl_surf.alignment);
199
200 return VK_SUCCESS;
201 }
202
203 static VkImageUsageFlags
204 anv_image_get_full_usage(const VkImageCreateInfo *info)
205 {
206 VkImageUsageFlags usage = info->usage;
207
208 if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
209 /* Meta will transfer from the image by binding it as a texture. */
210 usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
211 }
212
213 if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
214 /* Meta will transfer to the image by binding it as a color attachment,
215 * even if the image format is not a color format.
216 */
217 usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
218 }
219
220 return usage;
221 }
222
223 VkResult
224 anv_image_create(VkDevice _device,
225 const struct anv_image_create_info *create_info,
226 const VkAllocationCallbacks* alloc,
227 VkImage *pImage)
228 {
229 ANV_FROM_HANDLE(anv_device, device, _device);
230 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
231 const VkExtent3D *restrict extent = &pCreateInfo->extent;
232 struct anv_image *image = NULL;
233 VkResult r;
234
235 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
236
237 anv_assert(pCreateInfo->mipLevels > 0);
238 anv_assert(pCreateInfo->arrayLayers > 0);
239 anv_assert(pCreateInfo->samples == VK_SAMPLE_COUNT_1_BIT);
240 anv_assert(pCreateInfo->extent.width > 0);
241 anv_assert(pCreateInfo->extent.height > 0);
242 anv_assert(pCreateInfo->extent.depth > 0);
243
244 /* TODO(chadv): How should we validate inputs? */
245 const uint8_t surf_type =
246 anv_surf_type_from_image_type[pCreateInfo->imageType];
247
248 const struct anv_surf_type_limits *limits =
249 &anv_surf_type_limits[surf_type];
250
251 /* Errors should be caught by VkImageFormatProperties. */
252 assert(extent->width <= limits->width);
253 assert(extent->height <= limits->height);
254 assert(extent->depth <= limits->depth);
255
256 image = anv_alloc2(&device->alloc, alloc, sizeof(*image), 8,
257 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
258 if (!image)
259 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
260
261 memset(image, 0, sizeof(*image));
262 image->type = pCreateInfo->imageType;
263 image->extent = pCreateInfo->extent;
264 image->format = anv_format_for_vk_format(pCreateInfo->format);
265 image->levels = pCreateInfo->mipLevels;
266 image->array_size = pCreateInfo->arrayLayers;
267 image->usage = anv_image_get_full_usage(pCreateInfo);
268 image->surface_type = surf_type;
269
270 if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
271 VK_IMAGE_USAGE_STORAGE_BIT)) {
272 image->needs_nonrt_surface_state = true;
273 }
274
275 if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
276 image->needs_color_rt_surface_state = true;
277 }
278
279 if (likely(anv_format_is_color(image->format))) {
280 r = anv_image_make_surface(device, create_info, image->format,
281 &image->size, &image->alignment,
282 &image->color_surface);
283 if (r != VK_SUCCESS)
284 goto fail;
285 } else {
286 if (image->format->depth_format) {
287 r = anv_image_make_surface(device, create_info, image->format,
288 &image->size, &image->alignment,
289 &image->depth_surface);
290 if (r != VK_SUCCESS)
291 goto fail;
292 }
293
294 if (image->format->has_stencil) {
295 r = anv_image_make_surface(device, create_info, anv_format_s8_uint,
296 &image->size, &image->alignment,
297 &image->stencil_surface);
298 if (r != VK_SUCCESS)
299 goto fail;
300 }
301 }
302
303 *pImage = anv_image_to_handle(image);
304
305 return VK_SUCCESS;
306
307 fail:
308 if (image)
309 anv_free2(&device->alloc, alloc, image);
310
311 return r;
312 }
313
314 VkResult
315 anv_CreateImage(VkDevice device,
316 const VkImageCreateInfo *pCreateInfo,
317 const VkAllocationCallbacks *pAllocator,
318 VkImage *pImage)
319 {
320 return anv_image_create(device,
321 &(struct anv_image_create_info) {
322 .vk_info = pCreateInfo,
323 },
324 pAllocator,
325 pImage);
326 }
327
328 void
329 anv_DestroyImage(VkDevice _device, VkImage _image,
330 const VkAllocationCallbacks *pAllocator)
331 {
332 ANV_FROM_HANDLE(anv_device, device, _device);
333
334 anv_free2(&device->alloc, pAllocator, anv_image_from_handle(_image));
335 }
336
337 static void
338 anv_surface_get_subresource_layout(struct anv_image *image,
339 struct anv_surface *surface,
340 const VkImageSubresource *subresource,
341 VkSubresourceLayout *layout)
342 {
343 /* If we are on a non-zero mip level or array slice, we need to
344 * calculate a real offset.
345 */
346 anv_assert(subresource->mipLevel == 0);
347 anv_assert(subresource->arrayLayer == 0);
348
349 layout->offset = surface->offset;
350 layout->rowPitch = surface->stride;
351
352 /* Anvil's qpitch is in units of rows. Vulkan's depthPitch is in bytes. */
353 layout->depthPitch = surface->qpitch * surface->stride;
354
355 /* FINISHME: We really shouldn't be doing this calculation here */
356 if (image->array_size > 1)
357 layout->size = surface->qpitch * image->array_size;
358 else
359 layout->size = surface->stride * image->extent.height;
360 }
361
362 void anv_GetImageSubresourceLayout(
363 VkDevice device,
364 VkImage _image,
365 const VkImageSubresource* pSubresource,
366 VkSubresourceLayout* pLayout)
367 {
368 ANV_FROM_HANDLE(anv_image, image, _image);
369
370 assert(__builtin_popcount(pSubresource->aspectMask) == 1);
371
372 switch (pSubresource->aspectMask) {
373 case VK_IMAGE_ASPECT_COLOR_BIT:
374 anv_surface_get_subresource_layout(image, &image->color_surface,
375 pSubresource, pLayout);
376 break;
377 case VK_IMAGE_ASPECT_DEPTH_BIT:
378 anv_surface_get_subresource_layout(image, &image->depth_surface,
379 pSubresource, pLayout);
380 break;
381 case VK_IMAGE_ASPECT_STENCIL_BIT:
382 anv_surface_get_subresource_layout(image, &image->stencil_surface,
383 pSubresource, pLayout);
384 break;
385 default:
386 assert(!"Invalid image aspect");
387 }
388 }
389
390 VkResult
391 anv_validate_CreateImageView(VkDevice _device,
392 const VkImageViewCreateInfo *pCreateInfo,
393 const VkAllocationCallbacks *pAllocator,
394 VkImageView *pView)
395 {
396 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
397 const VkImageSubresourceRange *subresource;
398 const struct anv_image_view_info *view_info;
399 const struct anv_format *view_format_info;
400
401 /* Validate structure type before dereferencing it. */
402 assert(pCreateInfo);
403 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
404 subresource = &pCreateInfo->subresourceRange;
405
406 /* Validate viewType is in range before using it. */
407 assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
408 assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
409 view_info = &anv_image_view_info_table[pCreateInfo->viewType];
410
411 /* Validate format is in range before using it. */
412 assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
413 assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
414 view_format_info = anv_format_for_vk_format(pCreateInfo->format);
415
416 /* Validate channel swizzles. */
417 assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
418 assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
419 assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
420 assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
421 assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
422 assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
423 assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
424 assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
425
426 /* Validate subresource. */
427 assert(subresource->aspectMask != 0);
428 assert(subresource->levelCount > 0);
429 assert(subresource->layerCount > 0);
430 assert(subresource->baseMipLevel < image->levels);
431 assert(subresource->baseMipLevel + subresource->levelCount <= image->levels);
432 assert(subresource->baseArrayLayer < image->array_size);
433 assert(subresource->baseArrayLayer + subresource->layerCount <= image->array_size);
434 assert(pView);
435
436 if (view_info->is_cube) {
437 assert(subresource->baseArrayLayer % 6 == 0);
438 assert(subresource->layerCount % 6 == 0);
439 }
440
441 const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
442 | VK_IMAGE_ASPECT_STENCIL_BIT;
443
444 /* Validate format. */
445 if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
446 assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
447 assert(!image->format->depth_format);
448 assert(!image->format->has_stencil);
449 assert(!view_format_info->depth_format);
450 assert(!view_format_info->has_stencil);
451 assert(view_format_info->isl_layout->bs ==
452 image->format->isl_layout->bs);
453 } else if (subresource->aspectMask & ds_flags) {
454 assert((subresource->aspectMask & ~ds_flags) == 0);
455
456 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
457 assert(image->format->depth_format);
458 assert(view_format_info->depth_format);
459 assert(view_format_info->isl_layout->bs ==
460 image->format->isl_layout->bs);
461 }
462
463 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
464 /* FINISHME: Is it legal to have an R8 view of S8? */
465 assert(image->format->has_stencil);
466 assert(view_format_info->has_stencil);
467 }
468 } else {
469 assert(!"bad VkImageSubresourceRange::aspectFlags");
470 }
471
472 return anv_CreateImageView(_device, pCreateInfo, pAllocator, pView);
473 }
474
475 void
476 anv_image_view_init(struct anv_image_view *iview,
477 struct anv_device *device,
478 const VkImageViewCreateInfo* pCreateInfo,
479 struct anv_cmd_buffer *cmd_buffer)
480 {
481 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
482 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
483
484 assert(range->layerCount > 0);
485 assert(range->baseMipLevel < image->levels);
486 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
487 VK_IMAGE_USAGE_STORAGE_BIT |
488 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
489 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
490
491 switch (image->type) {
492 default:
493 unreachable("bad VkImageType");
494 case VK_IMAGE_TYPE_1D:
495 case VK_IMAGE_TYPE_2D:
496 assert(range->baseArrayLayer + range->layerCount - 1 <= image->array_size);
497 break;
498 case VK_IMAGE_TYPE_3D:
499 assert(range->baseArrayLayer + range->layerCount - 1
500 <= anv_minify(image->extent.depth, range->baseMipLevel));
501 break;
502 }
503
504 switch (device->info.gen) {
505 case 7:
506 if (device->info.is_haswell)
507 gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
508 else
509 gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
510 break;
511 case 8:
512 gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
513 break;
514 case 9:
515 gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
516 break;
517 default:
518 unreachable("unsupported gen\n");
519 }
520 }
521
522 VkResult
523 anv_CreateImageView(VkDevice _device,
524 const VkImageViewCreateInfo *pCreateInfo,
525 const VkAllocationCallbacks *pAllocator,
526 VkImageView *pView)
527 {
528 ANV_FROM_HANDLE(anv_device, device, _device);
529 struct anv_image_view *view;
530
531 view = anv_alloc2(&device->alloc, pAllocator, sizeof(*view), 8,
532 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
533 if (view == NULL)
534 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
535
536 anv_image_view_init(view, device, pCreateInfo, NULL);
537
538 *pView = anv_image_view_to_handle(view);
539
540 return VK_SUCCESS;
541 }
542
543 void
544 anv_DestroyImageView(VkDevice _device, VkImageView _iview,
545 const VkAllocationCallbacks *pAllocator)
546 {
547 ANV_FROM_HANDLE(anv_device, device, _device);
548 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
549
550 if (iview->image->needs_color_rt_surface_state) {
551 anv_state_pool_free(&device->surface_state_pool,
552 iview->color_rt_surface_state);
553 }
554
555 if (iview->image->needs_nonrt_surface_state) {
556 anv_state_pool_free(&device->surface_state_pool,
557 iview->nonrt_surface_state);
558 }
559
560 anv_free2(&device->alloc, pAllocator, iview);
561 }
562
563 struct anv_surface *
564 anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
565 {
566 switch (aspect_mask) {
567 case VK_IMAGE_ASPECT_COLOR_BIT:
568 /* Dragons will eat you.
569 *
570 * Meta attaches all destination surfaces as color render targets. Guess
571 * what surface the Meta Dragons really want.
572 */
573 if (image->format->depth_format && image->format->has_stencil) {
574 anv_finishme("combined depth stencil formats");
575 return &image->depth_surface;
576 } else if (image->format->depth_format) {
577 return &image->depth_surface;
578 } else if (image->format->has_stencil) {
579 return &image->stencil_surface;
580 } else {
581 return &image->color_surface;
582 }
583 break;
584 case VK_IMAGE_ASPECT_DEPTH_BIT:
585 assert(image->format->depth_format);
586 return &image->depth_surface;
587 case VK_IMAGE_ASPECT_STENCIL_BIT:
588 assert(image->format->has_stencil);
589 return &image->stencil_surface;
590 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
591 if (image->format->depth_format && image->format->has_stencil) {
592 /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
593 * depth stencil formats. Specifically, it states:
594 *
595 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
596 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
597 */
598 anv_finishme("combined depthstencil aspect");
599 return &image->depth_surface;
600 } else if (image->format->depth_format) {
601 return &image->depth_surface;
602 } else if (image->format->has_stencil) {
603 return &image->stencil_surface;
604 }
605 /* fallthrough */
606 default:
607 unreachable("image does not have aspect");
608 return NULL;
609 }
610 }
611
612 #if 0
613 VkImageAspectFlags aspect_mask = 0;
614 if (format->depth_format)
615 aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
616 if (format->has_stencil)
617 aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
618 if (!aspect_mask)
619 aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
620
621 anv_image_view_init(iview, device,
622 &(VkImageViewCreateInfo) {
623 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
624 .image = info->image,
625 .viewType = VK_IMAGE_VIEW_TYPE_2D,
626 .format = info->format,
627 .channels = {
628 .r = VK_CHANNEL_SWIZZLE_R,
629 .g = VK_CHANNEL_SWIZZLE_G,
630 .b = VK_CHANNEL_SWIZZLE_B,
631 .a = VK_CHANNEL_SWIZZLE_A,
632 },
633 .subresourceRange = {
634 .aspectMask = aspect_mask,
635 .baseMipLevel = info->mipLevel,
636 .mipLevels = 1,
637 .baseArrayLayer = info->baseArraySlice,
638 .arraySize = info->arraySize,
639 },
640 },
641 NULL);
642 #endif