2 * Copyright © 2015 Intel Corporation
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:
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
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
30 #include "anv_private.h"
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.
35 #include "gen8_pack.h"
37 static const uint8_t anv_halign
[] = {
43 static const uint8_t anv_valign
[] = {
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
,
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),
68 struct anv_image_view_info
69 anv_image_view_info_for_vk_image_view_type(VkImageViewType type
)
71 return anv_image_view_info_table
[type
];
74 static const struct anv_surf_type_limits
{
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},
87 static const struct anv_tile_info
{
89 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
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
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 },
109 static enum isl_tiling
110 anv_image_choose_tiling(const struct anv_image_create_info
*anv_info
)
112 if (anv_info
->force_tiling
)
113 return anv_info
->tiling
;
115 /* The Sandybridge PRM says that the stencil buffer "is supported
116 * only in Tile W memory".
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
)) {
130 assert(!"bad VKImageTiling");
131 return ISL_TILING_LINEAR
;
137 * The \a format argument is required and overrides any format in
138 * struct anv_image_create_info.
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
)
148 /* See RENDER_SURFACE_STATE.SurfaceQPitch */
149 static const uint16_t min_qpitch UNUSED
= 0x4;
150 static const uint16_t max_qpitch UNUSED
= 0x1ffc;
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
);
157 const struct anv_tile_info
*tile_info
=
158 &anv_tile_info_table
[tiling
];
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
;
164 struct isl_extent2d tile_extent
;
165 isl_tiling_get_extent(&dev
->isl_dev
, tiling
, bs
, &tile_extent
);
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);
172 uint16_t qpitch
= min_qpitch
;
173 uint32_t mt_width
= 0;
174 uint32_t mt_height
= 0;
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:
181 * One-dimensional surfaces are identical to 2D surfaces with height of one.
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
);
189 if (levels
== 1 && array_size
== 1) {
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
);
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:
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
;
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 >>
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
);
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
);
222 mt_width
= MAX(mt_width
, w_l
* max_layers_horiz
);
223 mt_height
+= h_l
* max_layers_vert
;
227 unreachable(!"bad VkImageType");
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
);
236 /* From the Broadwell PRM, RENDER_SURFACE_STATE.SurfaceQpitch:
238 * This field must be set an integer multiple of the Surface Vertical
241 assert(anv_is_aligned(qpitch
, j
));
243 uint32_t stride
= align_u32(mt_width
* bs
/ bw
, tile_extent
.width
);
244 if (create_info
->stride
> 0)
245 stride
= create_info
->stride
;
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:
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
);
256 *inout_image_size
= offset
+ size
;
257 *inout_image_alignment
= MAX(*inout_image_alignment
,
258 tile_info
->surface_alignment
);
260 *out_surface
= (struct anv_surface
) {
272 static VkImageUsageFlags
273 anv_image_get_full_usage(const VkImageCreateInfo
*info
)
275 VkImageUsageFlags usage
= info
->usage
;
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
;
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.
286 usage
|= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
;
293 anv_image_create(VkDevice _device
,
294 const struct anv_image_create_info
*create_info
,
295 const VkAllocationCallbacks
* alloc
,
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
;
304 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
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);
313 /* TODO(chadv): How should we validate inputs? */
314 const uint8_t surf_type
=
315 anv_surf_type_from_image_type
[pCreateInfo
->imageType
];
317 const struct anv_surf_type_limits
*limits
=
318 &anv_surf_type_limits
[surf_type
];
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
);
325 image
= anv_alloc2(&device
->alloc
, alloc
, sizeof(*image
), 8,
326 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
328 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
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
;
339 if (image
->usage
& (VK_IMAGE_USAGE_SAMPLED_BIT
|
340 VK_IMAGE_USAGE_STORAGE_BIT
)) {
341 image
->needs_nonrt_surface_state
= true;
344 if (image
->usage
& VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
) {
345 image
->needs_color_rt_surface_state
= true;
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
);
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
);
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
);
372 *pImage
= anv_image_to_handle(image
);
378 anv_free2(&device
->alloc
, alloc
, image
);
384 anv_CreateImage(VkDevice device
,
385 const VkImageCreateInfo
*pCreateInfo
,
386 const VkAllocationCallbacks
*pAllocator
,
389 return anv_image_create(device
,
390 &(struct anv_image_create_info
) {
391 .vk_info
= pCreateInfo
,
398 anv_DestroyImage(VkDevice _device
, VkImage _image
,
399 const VkAllocationCallbacks
*pAllocator
)
401 ANV_FROM_HANDLE(anv_device
, device
, _device
);
403 anv_free2(&device
->alloc
, pAllocator
, anv_image_from_handle(_image
));
407 anv_surface_get_subresource_layout(struct anv_image
*image
,
408 struct anv_surface
*surface
,
409 const VkImageSubresource
*subresource
,
410 VkSubresourceLayout
*layout
)
412 /* If we are on a non-zero mip level or array slice, we need to
413 * calculate a real offset.
415 anv_assert(subresource
->mipLevel
== 0);
416 anv_assert(subresource
->arrayLayer
== 0);
418 layout
->offset
= surface
->offset
;
419 layout
->rowPitch
= surface
->stride
;
421 /* Anvil's qpitch is in units of rows. Vulkan's depthPitch is in bytes. */
422 layout
->depthPitch
= surface
->qpitch
* surface
->stride
;
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
;
428 layout
->size
= surface
->stride
* image
->extent
.height
;
431 void anv_GetImageSubresourceLayout(
434 const VkImageSubresource
* pSubresource
,
435 VkSubresourceLayout
* pLayout
)
437 ANV_FROM_HANDLE(anv_image
, image
, _image
);
439 assert(__builtin_popcount(pSubresource
->aspectMask
) == 1);
441 switch (pSubresource
->aspectMask
) {
442 case VK_IMAGE_ASPECT_COLOR_BIT
:
443 anv_surface_get_subresource_layout(image
, &image
->color_surface
,
444 pSubresource
, pLayout
);
446 case VK_IMAGE_ASPECT_DEPTH_BIT
:
447 anv_surface_get_subresource_layout(image
, &image
->depth_surface
,
448 pSubresource
, pLayout
);
450 case VK_IMAGE_ASPECT_STENCIL_BIT
:
451 anv_surface_get_subresource_layout(image
, &image
->stencil_surface
,
452 pSubresource
, pLayout
);
455 assert(!"Invalid image aspect");
460 anv_validate_CreateImageView(VkDevice _device
,
461 const VkImageViewCreateInfo
*pCreateInfo
,
462 const VkAllocationCallbacks
*pAllocator
,
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
;
470 /* Validate structure type before dereferencing it. */
472 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
473 subresource
= &pCreateInfo
->subresourceRange
;
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
];
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
);
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
);
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
);
505 if (view_info
->is_cube
) {
506 assert(subresource
->baseArrayLayer
% 6 == 0);
507 assert(subresource
->layerCount
% 6 == 0);
510 const VkImageAspectFlags ds_flags
= VK_IMAGE_ASPECT_DEPTH_BIT
511 | VK_IMAGE_ASPECT_STENCIL_BIT
;
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);
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
);
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
);
538 assert(!"bad VkImageSubresourceRange::aspectFlags");
541 return anv_CreateImageView(_device
, pCreateInfo
, pAllocator
, pView
);
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
)
550 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
551 const VkImageSubresourceRange
*range
= &pCreateInfo
->subresourceRange
;
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
));
560 switch (image
->type
) {
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
);
567 case VK_IMAGE_TYPE_3D
:
568 assert(range
->baseArrayLayer
+ range
->layerCount
- 1
569 <= anv_minify(image
->extent
.depth
, range
->baseMipLevel
));
573 switch (device
->info
.gen
) {
575 if (device
->info
.is_haswell
)
576 gen75_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
578 gen7_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
581 gen8_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
584 gen9_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
587 unreachable("unsupported gen\n");
592 anv_CreateImageView(VkDevice _device
,
593 const VkImageViewCreateInfo
*pCreateInfo
,
594 const VkAllocationCallbacks
*pAllocator
,
597 ANV_FROM_HANDLE(anv_device
, device
, _device
);
598 struct anv_image_view
*view
;
600 view
= anv_alloc2(&device
->alloc
, pAllocator
, sizeof(*view
), 8,
601 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
603 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
605 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
607 *pView
= anv_image_view_to_handle(view
);
613 anv_DestroyImageView(VkDevice _device
, VkImageView _iview
,
614 const VkAllocationCallbacks
*pAllocator
)
616 ANV_FROM_HANDLE(anv_device
, device
, _device
);
617 ANV_FROM_HANDLE(anv_image_view
, iview
, _iview
);
619 if (iview
->image
->needs_color_rt_surface_state
) {
620 anv_state_pool_free(&device
->surface_state_pool
,
621 iview
->color_rt_surface_state
);
624 if (iview
->image
->needs_nonrt_surface_state
) {
625 anv_state_pool_free(&device
->surface_state_pool
,
626 iview
->nonrt_surface_state
);
629 anv_free2(&device
->alloc
, pAllocator
, iview
);
633 anv_image_get_surface_for_aspect_mask(struct anv_image
*image
, VkImageAspectFlags aspect_mask
)
635 switch (aspect_mask
) {
636 case VK_IMAGE_ASPECT_COLOR_BIT
:
637 /* Dragons will eat you.
639 * Meta attaches all destination surfaces as color render targets. Guess
640 * what surface the Meta Dragons really want.
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
;
650 return &image
->color_surface
;
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:
664 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
665 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
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
;
676 unreachable("image does not have aspect");
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
;
688 aspect_mask
|= VK_IMAGE_ASPECT_COLOR_BIT
;
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
,
697 .r
= VK_CHANNEL_SWIZZLE_R
,
698 .g
= VK_CHANNEL_SWIZZLE_G
,
699 .b
= VK_CHANNEL_SWIZZLE_B
,
700 .a
= VK_CHANNEL_SWIZZLE_A
,
702 .subresourceRange
= {
703 .aspectMask
= aspect_mask
,
704 .baseMipLevel
= info
->mipLevel
,
706 .baseArrayLayer
= info
->baseArraySlice
,
707 .arraySize
= info
->arraySize
,