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 static const uint8_t anv_halign
[] = {
38 static const uint8_t anv_valign
[] = {
44 static const uint8_t anv_surf_type_from_image_type
[] = {
45 [VK_IMAGE_TYPE_1D
] = SURFTYPE_1D
,
46 [VK_IMAGE_TYPE_2D
] = SURFTYPE_2D
,
47 [VK_IMAGE_TYPE_3D
] = SURFTYPE_3D
,
51 static const struct anv_image_view_info
52 anv_image_view_info_table
[] = {
53 #define INFO(s, ...) { .surface_type = s, __VA_ARGS__ }
54 [VK_IMAGE_VIEW_TYPE_1D
] = INFO(SURFTYPE_1D
),
55 [VK_IMAGE_VIEW_TYPE_2D
] = INFO(SURFTYPE_2D
),
56 [VK_IMAGE_VIEW_TYPE_3D
] = INFO(SURFTYPE_3D
),
57 [VK_IMAGE_VIEW_TYPE_CUBE
] = INFO(SURFTYPE_CUBE
, .is_cube
= 1),
58 [VK_IMAGE_VIEW_TYPE_1D_ARRAY
] = INFO(SURFTYPE_1D
, .is_array
= 1),
59 [VK_IMAGE_VIEW_TYPE_2D_ARRAY
] = INFO(SURFTYPE_2D
, .is_array
= 1),
60 [VK_IMAGE_VIEW_TYPE_CUBE_ARRAY
] = INFO(SURFTYPE_CUBE
, .is_array
= 1, .is_cube
= 1),
64 const struct anv_image_view_info
*
65 anv_image_view_info_for_vk_image_view_type(VkImageViewType type
)
67 return &anv_image_view_info_table
[type
];
70 static const struct anv_surf_type_limits
{
74 } anv_surf_type_limits
[] = {
75 [SURFTYPE_1D
] = {16384, 1, 2048},
76 [SURFTYPE_2D
] = {16384, 16384, 2048},
77 [SURFTYPE_3D
] = {2048, 2048, 2048},
78 [SURFTYPE_CUBE
] = {16384, 16384, 340},
79 [SURFTYPE_BUFFER
] = {128, 16384, 64},
80 [SURFTYPE_STRBUF
] = {128, 16384, 64},
83 static const struct anv_tile_info
{
88 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
90 * To simplify calculations, the alignments defined in the table are
91 * sometimes larger than required. For example, Skylake requires that X and
92 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
93 * alignment. We choose 4K to accomodate both chipsets. The alignment of
94 * a linear buffer depends on its element type and usage. Linear depth
95 * buffers have the largest alignment, 64B, so we choose that for all linear
98 uint32_t surface_alignment
;
99 } anv_tile_info_table
[] = {
100 [LINEAR
] = { 1, 1, 64 },
101 [XMAJOR
] = { 512, 8, 4096 },
102 [YMAJOR
] = { 128, 32, 4096 },
103 [WMAJOR
] = { 128, 32, 4096 },
107 * Return -1 on failure.
110 anv_image_choose_tile_mode(const struct anv_image_create_info
*anv_info
)
112 if (anv_info
->force_tile_mode
)
113 return anv_info
->tile_mode
;
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 if (unlikely(anv_info
->vk_info
->format
== VK_FORMAT_S8_UINT
)) {
126 case VK_IMAGE_TILING_OPTIMAL
:
127 if (unlikely(anv_info
->vk_info
->format
== VK_FORMAT_S8_UINT
)) {
133 assert(!"bad VKImageTiling");
140 * The \a format argument is required and overrides any format in
141 * struct anv_image_create_info.
144 anv_image_make_surface(const struct anv_image_create_info
*create_info
,
145 const struct anv_format
*format
,
146 uint64_t *inout_image_size
,
147 uint32_t *inout_image_alignment
,
148 struct anv_surface
*out_surface
)
150 /* See RENDER_SURFACE_STATE.SurfaceQPitch */
151 static const uint16_t min_qpitch UNUSED
= 0x4;
152 static const uint16_t max_qpitch UNUSED
= 0x1ffc;
154 const VkExtent3D
*restrict extent
= &create_info
->vk_info
->extent
;
155 const uint32_t levels
= create_info
->vk_info
->mipLevels
;
156 const uint32_t array_size
= create_info
->vk_info
->arraySize
;
158 const int8_t tile_mode
= anv_image_choose_tile_mode(create_info
);
160 return vk_error(VK_ERROR_INVALID_IMAGE
);
162 const struct anv_tile_info
*tile_info
=
163 &anv_tile_info_table
[tile_mode
];
165 const uint32_t i
= 4; /* FINISHME: Stop hardcoding subimage alignment */
166 const uint32_t j
= 4; /* FINISHME: Stop hardcoding subimage alignment */
168 uint16_t qpitch
= min_qpitch
;
169 uint32_t mt_width
= 0;
170 uint32_t mt_height
= 0;
172 switch (create_info
->vk_info
->imageType
) {
173 case VK_IMAGE_TYPE_1D
:
174 /* From the Broadwell PRM >> Memory Views >> Common Surface Formats >>
175 * Surface Layout >> 1D Surfaces:
177 * One-dimensional surfaces are identical to 2D surfaces with height of one.
181 case VK_IMAGE_TYPE_2D
: {
182 const uint32_t w0
= align_u32(extent
->width
, i
);
183 const uint32_t h0
= align_u32(extent
->height
, j
);
185 if (levels
== 1 && array_size
== 1) {
190 uint32_t w1
= align_u32(anv_minify(extent
->width
, 1), i
);
191 uint32_t h1
= align_u32(anv_minify(extent
->height
, 1), j
);
192 uint32_t w2
= align_u32(anv_minify(extent
->width
, 2), i
);
194 /* The QPitch equation is found in the Broadwell PRM >> Volume 5: Memory
195 * Views >> Common Surface Formats >> Surface Layout >> 2D Surfaces >>
196 * Surface Arrays >> For All Surface Other Than Separate Stencil Buffer:
198 qpitch
= h0
+ h1
+ 11 * j
;
199 mt_width
= MAX(w0
, w1
+ w2
);
200 mt_height
= array_size
* qpitch
;
204 case VK_IMAGE_TYPE_3D
:
205 /* The layout of 3D surfaces is described by the Broadwell PRM >>
206 * Volume 5: Memory Views >> Common Surface Formats >> Surface Layout >>
209 for (uint32_t l
= 0; l
< levels
; ++l
) {
210 const uint32_t w_l
= align_u32(anv_minify(extent
->width
, l
), i
);
211 const uint32_t h_l
= align_u32(anv_minify(extent
->height
, l
), j
);
212 const uint32_t d_l
= anv_minify(extent
->depth
, l
);
214 const uint32_t max_layers_horiz
= MIN(d_l
, 1u << l
);
215 const uint32_t max_layers_vert
= align_u32(d_l
, 1u << l
) / (1u << l
);
217 mt_width
= MAX(mt_width
, w_l
* max_layers_horiz
);
218 mt_height
+= h_l
* max_layers_vert
;
222 unreachable(!"bad VkImageType");
225 assert(qpitch
>= min_qpitch
);
226 if (qpitch
> max_qpitch
) {
227 anv_loge("image qpitch > 0x%x\n", max_qpitch
);
228 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY
);
231 /* From the Broadwell PRM, RENDER_SURFACE_STATE.SurfaceQpitch:
233 * This field must be set an integer multiple of the Surface Vertical
236 assert(anv_is_aligned(qpitch
, j
));
238 uint32_t stride
= align_u32(mt_width
* format
->cpp
, tile_info
->width
);
239 if (create_info
->stride
> 0)
240 stride
= create_info
->stride
;
242 const uint32_t size
= stride
* align_u32(mt_height
, tile_info
->height
);
243 const uint32_t offset
= align_u32(*inout_image_size
,
244 tile_info
->surface_alignment
);
246 *inout_image_size
= offset
+ size
;
247 *inout_image_alignment
= MAX(*inout_image_alignment
,
248 tile_info
->surface_alignment
);
250 *out_surface
= (struct anv_surface
) {
253 .tile_mode
= tile_mode
,
263 anv_image_create(VkDevice _device
,
264 const struct anv_image_create_info
*create_info
,
267 ANV_FROM_HANDLE(anv_device
, device
, _device
);
268 const VkImageCreateInfo
*pCreateInfo
= create_info
->vk_info
;
269 const VkExtent3D
*restrict extent
= &pCreateInfo
->extent
;
270 struct anv_image
*image
= NULL
;
273 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO
);
275 anv_assert(pCreateInfo
->mipLevels
> 0);
276 anv_assert(pCreateInfo
->arraySize
> 0);
277 anv_assert(pCreateInfo
->samples
== 1);
278 anv_assert(pCreateInfo
->extent
.width
> 0);
279 anv_assert(pCreateInfo
->extent
.height
> 0);
280 anv_assert(pCreateInfo
->extent
.depth
> 0);
282 /* TODO(chadv): How should we validate inputs? */
283 const uint8_t surf_type
=
284 anv_surf_type_from_image_type
[pCreateInfo
->imageType
];
286 const struct anv_surf_type_limits
*limits
=
287 &anv_surf_type_limits
[surf_type
];
289 if (extent
->width
> limits
->width
||
290 extent
->height
> limits
->height
||
291 extent
->depth
> limits
->depth
) {
292 /* TODO(chadv): What is the correct error? */
293 return vk_errorf(VK_ERROR_INVALID_MEMORY_SIZE
, "image extent is too large");
296 image
= anv_device_alloc(device
, sizeof(*image
), 8,
297 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
299 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
301 memset(image
, 0, sizeof(*image
));
302 image
->type
= pCreateInfo
->imageType
;
303 image
->extent
= pCreateInfo
->extent
;
304 image
->format
= anv_format_for_vk_format(pCreateInfo
->format
);
305 image
->levels
= pCreateInfo
->mipLevels
;
306 image
->array_size
= pCreateInfo
->arraySize
;
307 image
->surf_type
= surf_type
;
309 if (likely(anv_format_is_color(image
->format
))) {
310 r
= anv_image_make_surface(create_info
, image
->format
,
311 &image
->size
, &image
->alignment
,
312 &image
->color_surface
);
316 if (image
->format
->depth_format
) {
317 r
= anv_image_make_surface(create_info
, image
->format
,
318 &image
->size
, &image
->alignment
,
319 &image
->depth_surface
);
324 if (image
->format
->has_stencil
) {
325 r
= anv_image_make_surface(create_info
, anv_format_s8_uint
,
326 &image
->size
, &image
->alignment
,
327 &image
->stencil_surface
);
333 *pImage
= anv_image_to_handle(image
);
339 anv_device_free(device
, image
);
345 anv_CreateImage(VkDevice device
,
346 const VkImageCreateInfo
*pCreateInfo
,
349 return anv_image_create(device
,
350 &(struct anv_image_create_info
) {
351 .vk_info
= pCreateInfo
,
357 anv_DestroyImage(VkDevice _device
, VkImage _image
)
359 ANV_FROM_HANDLE(anv_device
, device
, _device
);
361 anv_device_free(device
, anv_image_from_handle(_image
));
366 VkResult
anv_GetImageSubresourceLayout(
369 const VkImageSubresource
* pSubresource
,
370 VkSubresourceLayout
* pLayout
)
372 stub_return(VK_UNSUPPORTED
);
376 anv_surface_view_fini(struct anv_device
*device
,
377 struct anv_surface_view
*view
)
379 anv_state_pool_free(&device
->surface_state_pool
, view
->surface_state
);
383 anv_validate_CreateImageView(VkDevice _device
,
384 const VkImageViewCreateInfo
*pCreateInfo
,
387 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
388 const VkImageSubresourceRange
*subresource
;
389 const struct anv_image_view_info
*view_info
;
390 const struct anv_format
*view_format_info
;
392 /* Validate structure type before dereferencing it. */
394 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO
);
395 subresource
= &pCreateInfo
->subresourceRange
;
397 /* Validate viewType is in range before using it. */
398 assert(pCreateInfo
->viewType
>= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE
);
399 assert(pCreateInfo
->viewType
<= VK_IMAGE_VIEW_TYPE_END_RANGE
);
400 view_info
= &anv_image_view_info_table
[pCreateInfo
->viewType
];
402 /* Validate format is in range before using it. */
403 assert(pCreateInfo
->format
>= VK_FORMAT_BEGIN_RANGE
);
404 assert(pCreateInfo
->format
<= VK_FORMAT_END_RANGE
);
405 view_format_info
= anv_format_for_vk_format(pCreateInfo
->format
);
407 /* Validate channel swizzles. */
408 assert(pCreateInfo
->channels
.r
>= VK_CHANNEL_SWIZZLE_BEGIN_RANGE
);
409 assert(pCreateInfo
->channels
.r
<= VK_CHANNEL_SWIZZLE_END_RANGE
);
410 assert(pCreateInfo
->channels
.g
>= VK_CHANNEL_SWIZZLE_BEGIN_RANGE
);
411 assert(pCreateInfo
->channels
.g
<= VK_CHANNEL_SWIZZLE_END_RANGE
);
412 assert(pCreateInfo
->channels
.b
>= VK_CHANNEL_SWIZZLE_BEGIN_RANGE
);
413 assert(pCreateInfo
->channels
.b
<= VK_CHANNEL_SWIZZLE_END_RANGE
);
414 assert(pCreateInfo
->channels
.a
>= VK_CHANNEL_SWIZZLE_BEGIN_RANGE
);
415 assert(pCreateInfo
->channels
.a
<= VK_CHANNEL_SWIZZLE_END_RANGE
);
417 /* Validate subresource. */
418 assert(subresource
->aspect
>= VK_IMAGE_ASPECT_BEGIN_RANGE
);
419 assert(subresource
->aspect
<= VK_IMAGE_ASPECT_END_RANGE
);
420 assert(subresource
->mipLevels
> 0);
421 assert(subresource
->arraySize
> 0);
422 assert(subresource
->baseMipLevel
< image
->levels
);
423 assert(subresource
->baseMipLevel
+ subresource
->mipLevels
<= image
->levels
);
424 assert(subresource
->baseArraySlice
< image
->array_size
);
425 assert(subresource
->baseArraySlice
+ subresource
->arraySize
<= image
->array_size
);
428 if (view_info
->is_cube
) {
429 assert(subresource
->baseArraySlice
% 6 == 0);
430 assert(subresource
->arraySize
% 6 == 0);
433 /* Validate format. */
434 switch (subresource
->aspect
) {
435 case VK_IMAGE_ASPECT_COLOR
:
436 assert(!image
->format
->depth_format
);
437 assert(!image
->format
->has_stencil
);
438 assert(!view_format_info
->depth_format
);
439 assert(!view_format_info
->has_stencil
);
440 assert(view_format_info
->cpp
== image
->format
->cpp
);
442 case VK_IMAGE_ASPECT_DEPTH
:
443 assert(image
->format
->depth_format
);
444 assert(view_format_info
->depth_format
);
445 assert(view_format_info
->cpp
== image
->format
->cpp
);
447 case VK_IMAGE_ASPECT_STENCIL
:
448 /* FINISHME: Is it legal to have an R8 view of S8? */
449 assert(image
->format
->has_stencil
);
450 assert(view_format_info
->has_stencil
);
453 assert(!"bad VkImageAspect");
457 return anv_CreateImageView(_device
, pCreateInfo
, pView
);
461 anv_image_view_init(struct anv_image_view
*iview
,
462 struct anv_device
*device
,
463 const VkImageViewCreateInfo
* pCreateInfo
,
464 struct anv_cmd_buffer
*cmd_buffer
)
466 switch (device
->info
.gen
) {
468 gen7_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
471 gen8_image_view_init(iview
, device
, pCreateInfo
, cmd_buffer
);
474 unreachable("unsupported gen\n");
479 anv_CreateImageView(VkDevice _device
,
480 const VkImageViewCreateInfo
*pCreateInfo
,
483 ANV_FROM_HANDLE(anv_device
, device
, _device
);
484 struct anv_image_view
*view
;
486 view
= anv_device_alloc(device
, sizeof(*view
), 8,
487 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
489 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
491 anv_image_view_init(view
, device
, pCreateInfo
, NULL
);
493 *pView
= anv_image_view_to_handle(view
);
499 anv_DestroyImageView(VkDevice _device
, VkImageView _iview
)
501 ANV_FROM_HANDLE(anv_device
, device
, _device
);
502 ANV_FROM_HANDLE(anv_image_view
, iview
, _iview
);
504 anv_surface_view_fini(device
, &iview
->view
);
505 anv_device_free(device
, iview
);
511 anv_depth_stencil_view_init(struct anv_depth_stencil_view
*view
,
512 const VkAttachmentViewCreateInfo
*pCreateInfo
)
514 ANV_FROM_HANDLE(anv_image
, image
, pCreateInfo
->image
);
516 view
->base
.attachment_type
= ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL
;
518 /* XXX: We don't handle any of these */
519 anv_assert(pCreateInfo
->mipLevel
== 0);
520 anv_assert(pCreateInfo
->baseArraySlice
== 0);
521 anv_assert(pCreateInfo
->arraySize
== 1);
524 view
->format
= anv_format_for_vk_format(pCreateInfo
->format
);
526 assert(anv_format_is_depth_or_stencil(image
->format
));
527 assert(anv_format_is_depth_or_stencil(view
->format
));
531 anv_image_get_surface_for_aspect(struct anv_image
*image
, VkImageAspect aspect
)
534 case VK_IMAGE_ASPECT_COLOR
:
535 assert(anv_format_is_color(image
->format
));
536 return &image
->color_surface
;
537 case VK_IMAGE_ASPECT_DEPTH
:
538 assert(image
->format
->depth_format
);
539 return &image
->depth_surface
;
540 case VK_IMAGE_ASPECT_STENCIL
:
541 assert(image
->format
->has_stencil
);
542 anv_finishme("stencil image views");
543 return &image
->stencil_surface
;
545 unreachable("image does not have aspect");
550 /** The attachment may be a color view into a non-color image. */
552 anv_image_get_surface_for_color_attachment(struct anv_image
*image
)
554 if (anv_format_is_color(image
->format
)) {
555 return &image
->color_surface
;
556 } else if (image
->format
->depth_format
) {
557 return &image
->depth_surface
;
558 } else if (image
->format
->has_stencil
) {
559 return &image
->stencil_surface
;
561 unreachable("image has bad format");
567 anv_color_attachment_view_init(struct anv_color_attachment_view
*aview
,
568 struct anv_device
*device
,
569 const VkAttachmentViewCreateInfo
* pCreateInfo
,
570 struct anv_cmd_buffer
*cmd_buffer
)
572 switch (device
->info
.gen
) {
574 gen7_color_attachment_view_init(aview
, device
, pCreateInfo
, cmd_buffer
);
577 gen8_color_attachment_view_init(aview
, device
, pCreateInfo
, cmd_buffer
);
580 unreachable("unsupported gen\n");
585 anv_CreateAttachmentView(VkDevice _device
,
586 const VkAttachmentViewCreateInfo
*pCreateInfo
,
587 VkAttachmentView
*pView
)
589 ANV_FROM_HANDLE(anv_device
, device
, _device
);
591 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO
);
593 const struct anv_format
*format
=
594 anv_format_for_vk_format(pCreateInfo
->format
);
596 if (anv_format_is_depth_or_stencil(format
)) {
597 struct anv_depth_stencil_view
*view
=
598 anv_device_alloc(device
, sizeof(*view
), 8,
599 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
601 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
603 anv_depth_stencil_view_init(view
, pCreateInfo
);
605 *pView
= anv_attachment_view_to_handle(&view
->base
);
607 struct anv_color_attachment_view
*view
=
608 anv_device_alloc(device
, sizeof(*view
), 8,
609 VK_SYSTEM_ALLOC_TYPE_API_OBJECT
);
611 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY
);
613 anv_color_attachment_view_init(view
, device
, pCreateInfo
, NULL
);
615 *pView
= anv_attachment_view_to_handle(&view
->base
);
622 anv_DestroyAttachmentView(VkDevice _device
, VkAttachmentView _view
)
624 ANV_FROM_HANDLE(anv_device
, device
, _device
);
625 ANV_FROM_HANDLE(anv_attachment_view
, view
, _view
);
627 if (view
->attachment_type
== ANV_ATTACHMENT_VIEW_TYPE_COLOR
) {
628 struct anv_color_attachment_view
*aview
=
629 (struct anv_color_attachment_view
*)view
;
631 anv_surface_view_fini(device
, &aview
->view
);
634 anv_device_free(device
, view
);