blob: 973e8bd609a17192aa864daf64ec9f26b5d37754 [file] [log] [blame]
Kristian Høgsberg769785c2015-05-08 22:32:37 -07001/*
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
Chad Versace2c2233e2015-07-17 15:04:27 -070030#include "anv_private.h"
Kristian Høgsberg769785c2015-05-08 22:32:37 -070031
Jason Ekstrandde54b4b2015-11-16 12:29:07 -080032/* 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
Chad Versacee6162c22015-06-09 12:11:46 -070037static const uint8_t anv_halign[] = {
38 [4] = HALIGN4,
39 [8] = HALIGN8,
40 [16] = HALIGN16,
41};
42
43static const uint8_t anv_valign[] = {
44 [4] = VALIGN4,
45 [8] = VALIGN8,
46 [16] = VALIGN16,
47};
48
Chad Versacecb30aca2015-05-28 07:37:59 -070049static 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
Chad Versace69e11ad2015-07-06 16:25:59 -070055static const struct anv_image_view_info
56anv_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
Chad Versacecb30aca2015-05-28 07:37:59 -070066};
67
Chad Versace8bf021c2015-10-05 13:22:44 -070068struct anv_image_view_info
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -070069anv_image_view_info_for_vk_image_view_type(VkImageViewType type)
70{
Chad Versace8bf021c2015-10-05 13:22:44 -070071 return anv_image_view_info_table[type];
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -070072}
73
Chad Versacefa352962015-05-28 07:40:22 -070074static const struct anv_surf_type_limits {
75 int32_t width;
76 int32_t height;
77 int32_t depth;
78} anv_surf_type_limits[] = {
Chad Versace622a3172015-09-14 14:37:09 -070079 [SURFTYPE_1D] = {16384, 1, 2048},
Chad Versacefa352962015-05-28 07:40:22 -070080 [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
Chad Versacee6bd5682015-06-09 13:29:08 -070087static const struct anv_tile_info {
Chad Versacee6bd5682015-06-09 13:29:08 -070088 /**
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[] = {
Chad Versaceba467462015-11-13 10:24:57 -0800101 [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 },
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700107};
108
Chad Versaceba467462015-11-13 10:24:57 -0800109static enum isl_tiling
110anv_image_choose_tiling(const struct anv_image_create_info *anv_info)
Chad Versacef1db3b32015-06-09 14:33:05 -0700111{
Chad Versaceba467462015-11-13 10:24:57 -0800112 if (anv_info->force_tiling)
113 return anv_info->tiling;
Chad Versacef1db3b32015-06-09 14:33:05 -0700114
Chad Versace053d32d2015-08-28 08:04:59 -0700115 /* The Sandybridge PRM says that the stencil buffer "is supported
116 * only in Tile W memory".
117 */
Chad Versacec6e76ae2015-06-26 18:48:34 -0700118
Chad Versacefdcd71f2015-06-26 20:06:08 -0700119 switch (anv_info->vk_info->tiling) {
Chad Versacef1db3b32015-06-09 14:33:05 -0700120 case VK_IMAGE_TILING_LINEAR:
Chad Versacef9c948e2015-10-07 11:36:51 -0700121 assert(anv_info->vk_info->format != VK_FORMAT_S8_UINT);
Chad Versaceba467462015-11-13 10:24:57 -0800122 return ISL_TILING_LINEAR;
Chad Versacef1db3b32015-06-09 14:33:05 -0700123 case VK_IMAGE_TILING_OPTIMAL:
Chad Versace053d32d2015-08-28 08:04:59 -0700124 if (unlikely(anv_info->vk_info->format == VK_FORMAT_S8_UINT)) {
Chad Versaceba467462015-11-13 10:24:57 -0800125 return ISL_TILING_W;
Chad Versace053d32d2015-08-28 08:04:59 -0700126 } else {
Chad Versaceba467462015-11-13 10:24:57 -0800127 return ISL_TILING_Y;
Chad Versace053d32d2015-08-28 08:04:59 -0700128 }
Chad Versacef1db3b32015-06-09 14:33:05 -0700129 default:
130 assert(!"bad VKImageTiling");
Chad Versaceba467462015-11-13 10:24:57 -0800131 return ISL_TILING_LINEAR;
Chad Versacef1db3b32015-06-09 14:33:05 -0700132 }
133}
134
Chad Versace5a6b2e62015-08-17 13:50:43 -0700135
136/**
137 * The \a format argument is required and overrides any format in
138 * struct anv_image_create_info.
139 */
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700140static VkResult
Chad Versaceba467462015-11-13 10:24:57 -0800141anv_image_make_surface(const struct anv_device *dev,
142 const struct anv_image_create_info *create_info,
Chad Versace5a6b2e62015-08-17 13:50:43 -0700143 const struct anv_format *format,
Chad Versacec6e76ae2015-06-26 18:48:34 -0700144 uint64_t *inout_image_size,
145 uint32_t *inout_image_alignment,
146 struct anv_surface *out_surface)
147{
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700148 /* See RENDER_SURFACE_STATE.SurfaceQPitch */
149 static const uint16_t min_qpitch UNUSED = 0x4;
150 static const uint16_t max_qpitch UNUSED = 0x1ffc;
151
Chad Versacec6e76ae2015-06-26 18:48:34 -0700152 const VkExtent3D *restrict extent = &create_info->vk_info->extent;
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700153 const uint32_t levels = create_info->vk_info->mipLevels;
154 const uint32_t array_size = create_info->vk_info->arraySize;
Chad Versaceba467462015-11-13 10:24:57 -0800155 const enum isl_tiling tiling = anv_image_choose_tiling(create_info);
Chad Versacec6e76ae2015-06-26 18:48:34 -0700156
157 const struct anv_tile_info *tile_info =
Chad Versaceba467462015-11-13 10:24:57 -0800158 &anv_tile_info_table[tiling];
Chad Versacec6e76ae2015-06-26 18:48:34 -0700159
Chad Versaceaddc2a92015-11-12 12:14:43 -0800160 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
Chad Versaceba467462015-11-13 10:24:57 -0800164 struct isl_extent2d tile_extent;
165 isl_tiling_get_extent(&dev->isl_dev, tiling, bs, &tile_extent);
166
Chad Versaceaddc2a92015-11-12 12:14:43 -0800167 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 */
Nanley Chery41cf35d2015-10-02 16:11:24 -0700169 assert(i == 4 || i == 8 || i == 16);
170 assert(j == 4 || j == 8 || j == 16);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700171
Chad Versacee01d5a02015-09-14 10:58:43 -0700172 uint16_t qpitch = min_qpitch;
173 uint32_t mt_width = 0;
174 uint32_t mt_height = 0;
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700175
Chad Versacee01d5a02015-09-14 10:58:43 -0700176 switch (create_info->vk_info->imageType) {
177 case VK_IMAGE_TYPE_1D:
Chad Versace622a3172015-09-14 14:37:09 -0700178 /* 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 */
Chad Versacee01d5a02015-09-14 10:58:43 -0700185 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);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700188
Chad Versacee01d5a02015-09-14 10:58:43 -0700189 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 */
Chad Versaceaddc2a92015-11-12 12:14:43 -0800202 assert(bh ==1 || bh == 4);
203 qpitch = (h0 + h1 + 11 * j) / bh;
Chad Versacee01d5a02015-09-14 10:58:43 -0700204 mt_width = MAX(w0, w1 + w2);
205 mt_height = array_size * qpitch;
206 }
207 break;
208 }
209 case VK_IMAGE_TYPE_3D:
Chad Versaceeed74e32015-09-14 11:04:08 -0700210 /* 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 }
Chad Versacee01d5a02015-09-14 10:58:43 -0700225 break;
226 default:
227 unreachable(!"bad VkImageType");
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700228 }
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
Chad Versaceba467462015-11-13 10:24:57 -0800243 uint32_t stride = align_u32(mt_width * bs / bw, tile_extent.width);
Kristian Høgsberg Kristensen6d09d062015-08-14 10:02:19 -0700244 if (create_info->stride > 0)
245 stride = create_info->stride;
246
Nanley Chery381f6022015-10-05 17:27:32 -0700247 /* 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 */
Chad Versaceaddc2a92015-11-12 12:14:43 -0800251 const uint32_t mem_rows = align_u32(mt_height / bh, 2 * bh);
Chad Versaceba467462015-11-13 10:24:57 -0800252 const uint32_t size = stride * align_u32(mem_rows, tile_extent.height);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700253 const uint32_t offset = align_u32(*inout_image_size,
254 tile_info->surface_alignment);
Chad Versacec6e76ae2015-06-26 18:48:34 -0700255
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,
Chad Versaceba467462015-11-13 10:24:57 -0800263 .tiling = tiling,
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700264 .qpitch = qpitch,
265 .h_align = i,
266 .v_align = j,
Chad Versacec6e76ae2015-06-26 18:48:34 -0700267 };
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700268
269 return VK_SUCCESS;
Chad Versacec6e76ae2015-06-26 18:48:34 -0700270}
271
Chad Versace24de3d42015-10-06 19:11:58 -0700272static VkImageUsageFlags
273anv_image_get_full_usage(const VkImageCreateInfo *info)
274{
275 VkImageUsageFlags usage = info->usage;
276
Jason Ekstrand6a8a5422015-11-30 11:12:44 -0800277 if (usage & VK_IMAGE_USAGE_TRANSFER_SRC_BIT) {
Chad Versace24de3d42015-10-06 19:11:58 -0700278 /* Meta will transfer from the image by binding it as a texture. */
279 usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
280 }
281
Jason Ekstrand6a8a5422015-11-30 11:12:44 -0800282 if (usage & VK_IMAGE_USAGE_TRANSFER_DST_BIT) {
Chad Versace24de3d42015-10-06 19:11:58 -0700283 /* 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
Chad Versace127cb3f2015-06-26 20:12:42 -0700292VkResult
293anv_image_create(VkDevice _device,
294 const struct anv_image_create_info *create_info,
295 VkImage *pImage)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700296{
Jason Ekstranda52e2082015-07-09 20:24:07 -0700297 ANV_FROM_HANDLE(anv_device, device, _device);
Chad Versacefdcd71f2015-06-26 20:06:08 -0700298 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
Chad Versace67a76592015-06-26 09:17:52 -0700299 const VkExtent3D *restrict extent = &pCreateInfo->extent;
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700300 struct anv_image *image = NULL;
301 VkResult r;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700302
303 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
304
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700305 anv_assert(pCreateInfo->mipLevels > 0);
306 anv_assert(pCreateInfo->arraySize > 0);
Jason Ekstrand2a3c2962015-06-10 21:04:51 -0700307 anv_assert(pCreateInfo->samples == 1);
Chad Versace5d7103e2015-06-26 09:05:46 -0700308 anv_assert(pCreateInfo->extent.width > 0);
309 anv_assert(pCreateInfo->extent.height > 0);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700310 anv_assert(pCreateInfo->extent.depth > 0);
Jason Ekstrand2a3c2962015-06-10 21:04:51 -0700311
Chad Versace7ea12162015-05-28 07:45:31 -0700312 /* TODO(chadv): How should we validate inputs? */
Chad Versace67a76592015-06-26 09:17:52 -0700313 const uint8_t surf_type =
314 anv_surf_type_from_image_type[pCreateInfo->imageType];
Chad Versace7ea12162015-05-28 07:45:31 -0700315
Chad Versacefa352962015-05-28 07:40:22 -0700316 const struct anv_surf_type_limits *limits =
Chad Versace67a76592015-06-26 09:17:52 -0700317 &anv_surf_type_limits[surf_type];
Chad Versacefa352962015-05-28 07:40:22 -0700318
Chad Versacef9c948e2015-10-07 11:36:51 -0700319 /* Errors should be caught by VkImageFormatProperties. */
320 assert(extent->width <= limits->width);
321 assert(extent->height <= limits->height);
322 assert(extent->depth <= limits->depth);
Chad Versacefa352962015-05-28 07:40:22 -0700323
Chad Versacec6e76ae2015-06-26 18:48:34 -0700324 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);
Chad Versace67a76592015-06-26 09:17:52 -0700328
Chad Versacec6e76ae2015-06-26 18:48:34 -0700329 memset(image, 0, sizeof(*image));
330 image->type = pCreateInfo->imageType;
331 image->extent = pCreateInfo->extent;
Chad Versaceded736f2015-08-17 13:10:40 -0700332 image->format = anv_format_for_vk_format(pCreateInfo->format);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700333 image->levels = pCreateInfo->mipLevels;
334 image->array_size = pCreateInfo->arraySize;
Chad Versace24de3d42015-10-06 19:11:58 -0700335 image->usage = anv_image_get_full_usage(pCreateInfo);
336 image->surface_type = surf_type;
Chad Versace67a76592015-06-26 09:17:52 -0700337
Chad Versace24de3d42015-10-06 19:11:58 -0700338 if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
339 VK_IMAGE_USAGE_STORAGE_BIT)) {
340 image->needs_nonrt_surface_state = true;
Chad Versace44143a12015-10-06 18:17:09 -0700341 }
342
Chad Versace24de3d42015-10-06 19:11:58 -0700343 if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
344 image->needs_color_rt_surface_state = true;
Chad Versace44143a12015-10-06 18:17:09 -0700345 }
346
Chad Versace941b48e2015-08-28 07:08:58 -0700347 if (likely(anv_format_is_color(image->format))) {
Chad Versaceba467462015-11-13 10:24:57 -0800348 r = anv_image_make_surface(device, create_info, image->format,
Chad Versace5a6b2e62015-08-17 13:50:43 -0700349 &image->size, &image->alignment,
Chad Versace941b48e2015-08-28 07:08:58 -0700350 &image->color_surface);
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700351 if (r != VK_SUCCESS)
352 goto fail;
Chad Versace941b48e2015-08-28 07:08:58 -0700353 } else {
354 if (image->format->depth_format) {
Chad Versaceba467462015-11-13 10:24:57 -0800355 r = anv_image_make_surface(device, create_info, image->format,
Chad Versace941b48e2015-08-28 07:08:58 -0700356 &image->size, &image->alignment,
357 &image->depth_surface);
358 if (r != VK_SUCCESS)
359 goto fail;
360 }
Kristian Høgsberg37743f92015-05-22 22:59:12 -0700361
Chad Versace941b48e2015-08-28 07:08:58 -0700362 if (image->format->has_stencil) {
Chad Versaceba467462015-11-13 10:24:57 -0800363 r = anv_image_make_surface(device, create_info, anv_format_s8_uint,
Chad Versace941b48e2015-08-28 07:08:58 -0700364 &image->size, &image->alignment,
365 &image->stencil_surface);
366 if (r != VK_SUCCESS)
367 goto fail;
368 }
Kristian Høgsberg37743f92015-05-22 22:59:12 -0700369 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700370
Jason Ekstranda52e2082015-07-09 20:24:07 -0700371 *pImage = anv_image_to_handle(image);
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700372
373 return VK_SUCCESS;
Chad Versace5b3a1ce2015-06-26 21:27:54 -0700374
375fail:
376 if (image)
377 anv_device_free(device, image);
378
379 return r;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700380}
381
Chad Versace127cb3f2015-06-26 20:12:42 -0700382VkResult
383anv_CreateImage(VkDevice device,
384 const VkImageCreateInfo *pCreateInfo,
385 VkImage *pImage)
Kristian Høgsberga29df712015-05-15 22:04:52 -0700386{
Chad Versacefdcd71f2015-06-26 20:06:08 -0700387 return anv_image_create(device,
388 &(struct anv_image_create_info) {
389 .vk_info = pCreateInfo,
390 },
391 pImage);
Kristian Høgsberga29df712015-05-15 22:04:52 -0700392}
393
Jason Ekstrand05a26a62015-10-05 20:50:51 -0700394void
Jason Ekstrand8b342b32015-07-10 12:30:58 -0700395anv_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));
Jason Ekstrand8b342b32015-07-10 12:30:58 -0700400}
401
Jason Ekstranddb5a5fc2015-10-13 15:50:02 -0700402static void
403anv_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
Jason Ekstranddb24afe2015-07-07 18:20:18 -0700425VkResult anv_GetImageSubresourceLayout(
426 VkDevice device,
Jason Ekstranddb5a5fc2015-10-13 15:50:02 -0700427 VkImage _image,
Jason Ekstranddb24afe2015-07-07 18:20:18 -0700428 const VkImageSubresource* pSubresource,
429 VkSubresourceLayout* pLayout)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700430{
Jason Ekstranddb5a5fc2015-10-13 15:50:02 -0700431 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 return vk_error(VK_UNSUPPORTED);
448 }
449
450 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700451}
452
Chad Versace127cb3f2015-06-26 20:12:42 -0700453VkResult
Chad Versace5b04db72015-07-06 16:24:28 -0700454anv_validate_CreateImageView(VkDevice _device,
455 const VkImageViewCreateInfo *pCreateInfo,
456 VkImageView *pView)
457{
Jason Ekstranda52e2082015-07-09 20:24:07 -0700458 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
Chad Versace23075bc2015-07-06 17:04:13 -0700459 const VkImageSubresourceRange *subresource;
460 const struct anv_image_view_info *view_info;
461 const struct anv_format *view_format_info;
Chad Versace5b04db72015-07-06 16:24:28 -0700462
Chad Versace23075bc2015-07-06 17:04:13 -0700463 /* Validate structure type before dereferencing it. */
Chad Versace5b04db72015-07-06 16:24:28 -0700464 assert(pCreateInfo);
465 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
Chad Versace23075bc2015-07-06 17:04:13 -0700466 subresource = &pCreateInfo->subresourceRange;
467
Chad Versace23075bc2015-07-06 17:04:13 -0700468 /* Validate viewType is in range before using it. */
469 assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
470 assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
471 view_info = &anv_image_view_info_table[pCreateInfo->viewType];
472
473 /* Validate format is in range before using it. */
474 assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
475 assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
Chad Versace23075bc2015-07-06 17:04:13 -0700476 view_format_info = anv_format_for_vk_format(pCreateInfo->format);
477
478 /* Validate channel swizzles. */
479 assert(pCreateInfo->channels.r >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
480 assert(pCreateInfo->channels.r <= VK_CHANNEL_SWIZZLE_END_RANGE);
481 assert(pCreateInfo->channels.g >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
482 assert(pCreateInfo->channels.g <= VK_CHANNEL_SWIZZLE_END_RANGE);
483 assert(pCreateInfo->channels.b >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
484 assert(pCreateInfo->channels.b <= VK_CHANNEL_SWIZZLE_END_RANGE);
485 assert(pCreateInfo->channels.a >= VK_CHANNEL_SWIZZLE_BEGIN_RANGE);
486 assert(pCreateInfo->channels.a <= VK_CHANNEL_SWIZZLE_END_RANGE);
487
488 /* Validate subresource. */
Chad Versace7a089bd2015-10-05 06:48:14 -0700489 assert(subresource->aspectMask != 0);
Chad Versace23075bc2015-07-06 17:04:13 -0700490 assert(subresource->mipLevels > 0);
491 assert(subresource->arraySize > 0);
492 assert(subresource->baseMipLevel < image->levels);
493 assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
Jason Ekstrand1e4263b2015-10-06 10:27:50 -0700494 assert(subresource->baseArrayLayer < image->array_size);
495 assert(subresource->baseArrayLayer + subresource->arraySize <= image->array_size);
Chad Versace5b04db72015-07-06 16:24:28 -0700496 assert(pView);
497
Chad Versace23075bc2015-07-06 17:04:13 -0700498 if (view_info->is_cube) {
Jason Ekstrand1e4263b2015-10-06 10:27:50 -0700499 assert(subresource->baseArrayLayer % 6 == 0);
Chad Versace23075bc2015-07-06 17:04:13 -0700500 assert(subresource->arraySize % 6 == 0);
501 }
Chad Versace5b04db72015-07-06 16:24:28 -0700502
Chad Versace7a089bd2015-10-05 06:48:14 -0700503 const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
504 | VK_IMAGE_ASPECT_STENCIL_BIT;
505
Chad Versace23075bc2015-07-06 17:04:13 -0700506 /* Validate format. */
Chad Versace7a089bd2015-10-05 06:48:14 -0700507 if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
508 assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
Chad Versaceded736f2015-08-17 13:10:40 -0700509 assert(!image->format->depth_format);
510 assert(!image->format->has_stencil);
Chad Versace23075bc2015-07-06 17:04:13 -0700511 assert(!view_format_info->depth_format);
512 assert(!view_format_info->has_stencil);
Chad Versaceaddc2a92015-11-12 12:14:43 -0800513 assert(view_format_info->isl_layout->bs ==
514 image->format->isl_layout->bs);
Chad Versace7a089bd2015-10-05 06:48:14 -0700515 } else if (subresource->aspectMask & ds_flags) {
516 assert((subresource->aspectMask & ~ds_flags) == 0);
517
518 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
519 assert(image->format->depth_format);
520 assert(view_format_info->depth_format);
Chad Versaceaddc2a92015-11-12 12:14:43 -0800521 assert(view_format_info->isl_layout->bs ==
522 image->format->isl_layout->bs);
Chad Versace7a089bd2015-10-05 06:48:14 -0700523 }
524
525 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL) {
526 /* FINISHME: Is it legal to have an R8 view of S8? */
527 assert(image->format->has_stencil);
528 assert(view_format_info->has_stencil);
529 }
530 } else {
531 assert(!"bad VkImageSubresourceRange::aspectFlags");
Chad Versace23075bc2015-07-06 17:04:13 -0700532 }
Chad Versace5b04db72015-07-06 16:24:28 -0700533
534 return anv_CreateImageView(_device, pCreateInfo, pView);
535}
536
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700537void
538anv_image_view_init(struct anv_image_view *iview,
539 struct anv_device *device,
540 const VkImageViewCreateInfo* pCreateInfo,
541 struct anv_cmd_buffer *cmd_buffer)
542{
Chad Versace44143a12015-10-06 18:17:09 -0700543 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
Chad Versace24de3d42015-10-06 19:11:58 -0700544 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
Chad Versace44143a12015-10-06 18:17:09 -0700545
Chad Versace24de3d42015-10-06 19:11:58 -0700546 assert(range->arraySize > 0);
547 assert(range->baseMipLevel < image->levels);
Chad Versace44143a12015-10-06 18:17:09 -0700548 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
Chad Versace24de3d42015-10-06 19:11:58 -0700549 VK_IMAGE_USAGE_STORAGE_BIT |
550 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
Chad Versace0ca3c842015-10-07 11:39:49 -0700551 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
Chad Versace24de3d42015-10-06 19:11:58 -0700552
553 switch (image->type) {
554 default:
555 unreachable("bad VkImageType");
556 case VK_IMAGE_TYPE_1D:
557 case VK_IMAGE_TYPE_2D:
558 assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
559 break;
560 case VK_IMAGE_TYPE_3D:
561 assert(range->baseArrayLayer + range->arraySize - 1
562 <= anv_minify(image->extent.depth, range->baseMipLevel));
563 break;
564 }
Chad Versace44143a12015-10-06 18:17:09 -0700565
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700566 switch (device->info.gen) {
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700567 case 7:
Jason Ekstrandf0390bc2015-11-17 07:07:02 -0800568 if (device->info.is_haswell)
569 gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
570 else
571 gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700572 break;
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700573 case 8:
574 gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
575 break;
Kristian Høgsberg Kristensencd4721c2015-11-25 22:27:01 -0800576 case 9:
577 gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
578 break;
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700579 default:
580 unreachable("unsupported gen\n");
581 }
582}
583
Chad Versace5b04db72015-07-06 16:24:28 -0700584VkResult
Chad Versace127cb3f2015-06-26 20:12:42 -0700585anv_CreateImageView(VkDevice _device,
586 const VkImageViewCreateInfo *pCreateInfo,
587 VkImageView *pView)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700588{
Jason Ekstranda52e2082015-07-09 20:24:07 -0700589 ANV_FROM_HANDLE(anv_device, device, _device);
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700590 struct anv_image_view *view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700591
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700592 view = anv_device_alloc(device, sizeof(*view), 8,
593 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
594 if (view == NULL)
595 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
596
597 anv_image_view_init(view, device, pCreateInfo, NULL);
598
599 *pView = anv_image_view_to_handle(view);
600
601 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700602}
603
Chad Versace24de3d42015-10-06 19:11:58 -0700604static void
605anv_image_view_destroy(struct anv_device *device,
606 struct anv_image_view *iview)
607{
608 if (iview->image->needs_color_rt_surface_state) {
609 anv_state_pool_free(&device->surface_state_pool,
610 iview->color_rt_surface_state);
611 }
612
613 if (iview->image->needs_nonrt_surface_state) {
614 anv_state_pool_free(&device->surface_state_pool,
615 iview->nonrt_surface_state);
616 }
617
618 anv_device_free(device, iview);
619}
620
Jason Ekstrand05a26a62015-10-05 20:50:51 -0700621void
Chad Versace8213be72015-07-15 12:00:27 -0700622anv_DestroyImageView(VkDevice _device, VkImageView _iview)
Jason Ekstrandb94b8df2015-07-10 12:25:30 -0700623{
624 ANV_FROM_HANDLE(anv_device, device, _device);
Chad Versace8213be72015-07-15 12:00:27 -0700625 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
Jason Ekstrandb94b8df2015-07-10 12:25:30 -0700626
Chad Versace24de3d42015-10-06 19:11:58 -0700627 anv_image_view_destroy(device, iview);
Jason Ekstrand84783502015-07-10 20:18:52 -0700628}
Kristian Høgsberg37743f92015-05-22 22:59:12 -0700629
Chad Versace941b48e2015-08-28 07:08:58 -0700630struct anv_surface *
Chad Versace7a089bd2015-10-05 06:48:14 -0700631anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
Chad Versace941b48e2015-08-28 07:08:58 -0700632{
Chad Versace7a089bd2015-10-05 06:48:14 -0700633 switch (aspect_mask) {
634 case VK_IMAGE_ASPECT_COLOR_BIT:
Chad Versace24de3d42015-10-06 19:11:58 -0700635 /* Dragons will eat you.
636 *
637 * Meta attaches all destination surfaces as color render targets. Guess
638 * what surface the Meta Dragons really want.
639 */
640 if (image->format->depth_format && image->format->has_stencil) {
641 anv_finishme("combined depth stencil formats");
642 return &image->depth_surface;
643 } else if (image->format->depth_format) {
644 return &image->depth_surface;
645 } else if (image->format->has_stencil) {
646 return &image->stencil_surface;
647 } else {
648 return &image->color_surface;
649 }
650 break;
Chad Versace7a089bd2015-10-05 06:48:14 -0700651 case VK_IMAGE_ASPECT_DEPTH_BIT:
Chad Versace941b48e2015-08-28 07:08:58 -0700652 assert(image->format->depth_format);
653 return &image->depth_surface;
Chad Versace7a089bd2015-10-05 06:48:14 -0700654 case VK_IMAGE_ASPECT_STENCIL_BIT:
Chad Versace941b48e2015-08-28 07:08:58 -0700655 assert(image->format->has_stencil);
Chad Versace941b48e2015-08-28 07:08:58 -0700656 return &image->stencil_surface;
Chad Versace7a089bd2015-10-05 06:48:14 -0700657 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
Chad Versace03dd7222015-10-07 09:03:47 -0700658 if (image->format->depth_format && image->format->has_stencil) {
659 /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
660 * depth stencil formats. Specifically, it states:
661 *
662 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
663 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
664 */
665 anv_finishme("combined depthstencil aspect");
666 return &image->depth_surface;
667 } else if (image->format->depth_format) {
668 return &image->depth_surface;
669 } else if (image->format->has_stencil) {
670 return &image->stencil_surface;
671 }
672 /* fallthrough */
Chad Versace941b48e2015-08-28 07:08:58 -0700673 default:
674 unreachable("image does not have aspect");
675 return NULL;
676 }
677}
678
Chad Versace6dea1a92015-10-07 07:30:52 -0700679#if 0
Chad Versace24de3d42015-10-06 19:11:58 -0700680 VkImageAspectFlags aspect_mask = 0;
681 if (format->depth_format)
682 aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
683 if (format->has_stencil)
684 aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
685 if (!aspect_mask)
686 aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
687
688 anv_image_view_init(iview, device,
689 &(VkImageViewCreateInfo) {
690 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
691 .image = info->image,
692 .viewType = VK_IMAGE_VIEW_TYPE_2D,
693 .format = info->format,
694 .channels = {
695 .r = VK_CHANNEL_SWIZZLE_R,
696 .g = VK_CHANNEL_SWIZZLE_G,
697 .b = VK_CHANNEL_SWIZZLE_B,
698 .a = VK_CHANNEL_SWIZZLE_A,
699 },
700 .subresourceRange = {
701 .aspectMask = aspect_mask,
702 .baseMipLevel = info->mipLevel,
703 .mipLevels = 1,
704 .baseArrayLayer = info->baseArraySlice,
705 .arraySize = info->arraySize,
706 },
707 },
708 NULL);
Chad Versace6dea1a92015-10-07 07:30:52 -0700709#endif