blob: 0fe2df10a7a66d5d329b71818c04ee357a478fb4 [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 Ekstrandf1a7c782015-11-30 12:21:19 -0800425void anv_GetImageSubresourceLayout(
Jason Ekstranddb24afe2015-07-07 18:20:18 -0700426 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:
Jason Ekstrandf1a7c782015-11-30 12:21:19 -0800447 assert(!"Invalid image aspect");
Jason Ekstranddb5a5fc2015-10-13 15:50:02 -0700448 }
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700449}
450
Chad Versace127cb3f2015-06-26 20:12:42 -0700451VkResult
Chad Versace5b04db72015-07-06 16:24:28 -0700452anv_validate_CreateImageView(VkDevice _device,
453 const VkImageViewCreateInfo *pCreateInfo,
454 VkImageView *pView)
455{
Jason Ekstranda52e2082015-07-09 20:24:07 -0700456 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
Chad Versace23075bc2015-07-06 17:04:13 -0700457 const VkImageSubresourceRange *subresource;
458 const struct anv_image_view_info *view_info;
459 const struct anv_format *view_format_info;
Chad Versace5b04db72015-07-06 16:24:28 -0700460
Chad Versace23075bc2015-07-06 17:04:13 -0700461 /* Validate structure type before dereferencing it. */
Chad Versace5b04db72015-07-06 16:24:28 -0700462 assert(pCreateInfo);
463 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
Chad Versace23075bc2015-07-06 17:04:13 -0700464 subresource = &pCreateInfo->subresourceRange;
465
Chad Versace23075bc2015-07-06 17:04:13 -0700466 /* Validate viewType is in range before using it. */
467 assert(pCreateInfo->viewType >= VK_IMAGE_VIEW_TYPE_BEGIN_RANGE);
468 assert(pCreateInfo->viewType <= VK_IMAGE_VIEW_TYPE_END_RANGE);
469 view_info = &anv_image_view_info_table[pCreateInfo->viewType];
470
471 /* Validate format is in range before using it. */
472 assert(pCreateInfo->format >= VK_FORMAT_BEGIN_RANGE);
473 assert(pCreateInfo->format <= VK_FORMAT_END_RANGE);
Chad Versace23075bc2015-07-06 17:04:13 -0700474 view_format_info = anv_format_for_vk_format(pCreateInfo->format);
475
476 /* Validate channel swizzles. */
Jason Ekstranda53f23d2015-11-30 13:06:12 -0800477 assert(pCreateInfo->components.r >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
478 assert(pCreateInfo->components.r <= VK_COMPONENT_SWIZZLE_END_RANGE);
479 assert(pCreateInfo->components.g >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
480 assert(pCreateInfo->components.g <= VK_COMPONENT_SWIZZLE_END_RANGE);
481 assert(pCreateInfo->components.b >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
482 assert(pCreateInfo->components.b <= VK_COMPONENT_SWIZZLE_END_RANGE);
483 assert(pCreateInfo->components.a >= VK_COMPONENT_SWIZZLE_BEGIN_RANGE);
484 assert(pCreateInfo->components.a <= VK_COMPONENT_SWIZZLE_END_RANGE);
Chad Versace23075bc2015-07-06 17:04:13 -0700485
486 /* Validate subresource. */
Chad Versace7a089bd2015-10-05 06:48:14 -0700487 assert(subresource->aspectMask != 0);
Chad Versace23075bc2015-07-06 17:04:13 -0700488 assert(subresource->mipLevels > 0);
489 assert(subresource->arraySize > 0);
490 assert(subresource->baseMipLevel < image->levels);
491 assert(subresource->baseMipLevel + subresource->mipLevels <= image->levels);
Jason Ekstrand1e4263b2015-10-06 10:27:50 -0700492 assert(subresource->baseArrayLayer < image->array_size);
493 assert(subresource->baseArrayLayer + subresource->arraySize <= image->array_size);
Chad Versace5b04db72015-07-06 16:24:28 -0700494 assert(pView);
495
Chad Versace23075bc2015-07-06 17:04:13 -0700496 if (view_info->is_cube) {
Jason Ekstrand1e4263b2015-10-06 10:27:50 -0700497 assert(subresource->baseArrayLayer % 6 == 0);
Chad Versace23075bc2015-07-06 17:04:13 -0700498 assert(subresource->arraySize % 6 == 0);
499 }
Chad Versace5b04db72015-07-06 16:24:28 -0700500
Chad Versace7a089bd2015-10-05 06:48:14 -0700501 const VkImageAspectFlags ds_flags = VK_IMAGE_ASPECT_DEPTH_BIT
502 | VK_IMAGE_ASPECT_STENCIL_BIT;
503
Chad Versace23075bc2015-07-06 17:04:13 -0700504 /* Validate format. */
Chad Versace7a089bd2015-10-05 06:48:14 -0700505 if (subresource->aspectMask & VK_IMAGE_ASPECT_COLOR_BIT) {
506 assert(subresource->aspectMask == VK_IMAGE_ASPECT_COLOR_BIT);
Chad Versaceded736f2015-08-17 13:10:40 -0700507 assert(!image->format->depth_format);
508 assert(!image->format->has_stencil);
Chad Versace23075bc2015-07-06 17:04:13 -0700509 assert(!view_format_info->depth_format);
510 assert(!view_format_info->has_stencil);
Chad Versaceaddc2a92015-11-12 12:14:43 -0800511 assert(view_format_info->isl_layout->bs ==
512 image->format->isl_layout->bs);
Chad Versace7a089bd2015-10-05 06:48:14 -0700513 } else if (subresource->aspectMask & ds_flags) {
514 assert((subresource->aspectMask & ~ds_flags) == 0);
515
516 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL_BIT) {
517 assert(image->format->depth_format);
518 assert(view_format_info->depth_format);
Chad Versaceaddc2a92015-11-12 12:14:43 -0800519 assert(view_format_info->isl_layout->bs ==
520 image->format->isl_layout->bs);
Chad Versace7a089bd2015-10-05 06:48:14 -0700521 }
522
523 if (subresource->aspectMask & VK_IMAGE_ASPECT_STENCIL) {
524 /* FINISHME: Is it legal to have an R8 view of S8? */
525 assert(image->format->has_stencil);
526 assert(view_format_info->has_stencil);
527 }
528 } else {
529 assert(!"bad VkImageSubresourceRange::aspectFlags");
Chad Versace23075bc2015-07-06 17:04:13 -0700530 }
Chad Versace5b04db72015-07-06 16:24:28 -0700531
532 return anv_CreateImageView(_device, pCreateInfo, pView);
533}
534
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700535void
536anv_image_view_init(struct anv_image_view *iview,
537 struct anv_device *device,
538 const VkImageViewCreateInfo* pCreateInfo,
539 struct anv_cmd_buffer *cmd_buffer)
540{
Chad Versace44143a12015-10-06 18:17:09 -0700541 ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
Chad Versace24de3d42015-10-06 19:11:58 -0700542 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
Chad Versace44143a12015-10-06 18:17:09 -0700543
Chad Versace24de3d42015-10-06 19:11:58 -0700544 assert(range->arraySize > 0);
545 assert(range->baseMipLevel < image->levels);
Chad Versace44143a12015-10-06 18:17:09 -0700546 assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
Chad Versace24de3d42015-10-06 19:11:58 -0700547 VK_IMAGE_USAGE_STORAGE_BIT |
548 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
Chad Versace0ca3c842015-10-07 11:39:49 -0700549 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT));
Chad Versace24de3d42015-10-06 19:11:58 -0700550
551 switch (image->type) {
552 default:
553 unreachable("bad VkImageType");
554 case VK_IMAGE_TYPE_1D:
555 case VK_IMAGE_TYPE_2D:
556 assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
557 break;
558 case VK_IMAGE_TYPE_3D:
559 assert(range->baseArrayLayer + range->arraySize - 1
560 <= anv_minify(image->extent.depth, range->baseMipLevel));
561 break;
562 }
Chad Versace44143a12015-10-06 18:17:09 -0700563
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700564 switch (device->info.gen) {
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700565 case 7:
Jason Ekstrandf0390bc2015-11-17 07:07:02 -0800566 if (device->info.is_haswell)
567 gen75_image_view_init(iview, device, pCreateInfo, cmd_buffer);
568 else
569 gen7_image_view_init(iview, device, pCreateInfo, cmd_buffer);
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700570 break;
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700571 case 8:
572 gen8_image_view_init(iview, device, pCreateInfo, cmd_buffer);
573 break;
Kristian Høgsberg Kristensencd4721c2015-11-25 22:27:01 -0800574 case 9:
575 gen9_image_view_init(iview, device, pCreateInfo, cmd_buffer);
576 break;
Kristian Høgsberg Kristensen988341a2015-08-19 21:36:57 -0700577 default:
578 unreachable("unsupported gen\n");
579 }
580}
581
Chad Versace5b04db72015-07-06 16:24:28 -0700582VkResult
Chad Versace127cb3f2015-06-26 20:12:42 -0700583anv_CreateImageView(VkDevice _device,
584 const VkImageViewCreateInfo *pCreateInfo,
585 VkImageView *pView)
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700586{
Jason Ekstranda52e2082015-07-09 20:24:07 -0700587 ANV_FROM_HANDLE(anv_device, device, _device);
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700588 struct anv_image_view *view;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700589
Kristian Høgsberg Kristensenf1455ff2015-08-20 22:59:19 -0700590 view = anv_device_alloc(device, sizeof(*view), 8,
591 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
592 if (view == NULL)
593 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
594
595 anv_image_view_init(view, device, pCreateInfo, NULL);
596
597 *pView = anv_image_view_to_handle(view);
598
599 return VK_SUCCESS;
Kristian Høgsberg769785c2015-05-08 22:32:37 -0700600}
601
Chad Versace24de3d42015-10-06 19:11:58 -0700602static void
603anv_image_view_destroy(struct anv_device *device,
604 struct anv_image_view *iview)
605{
606 if (iview->image->needs_color_rt_surface_state) {
607 anv_state_pool_free(&device->surface_state_pool,
608 iview->color_rt_surface_state);
609 }
610
611 if (iview->image->needs_nonrt_surface_state) {
612 anv_state_pool_free(&device->surface_state_pool,
613 iview->nonrt_surface_state);
614 }
615
616 anv_device_free(device, iview);
617}
618
Jason Ekstrand05a26a62015-10-05 20:50:51 -0700619void
Chad Versace8213be72015-07-15 12:00:27 -0700620anv_DestroyImageView(VkDevice _device, VkImageView _iview)
Jason Ekstrandb94b8df2015-07-10 12:25:30 -0700621{
622 ANV_FROM_HANDLE(anv_device, device, _device);
Chad Versace8213be72015-07-15 12:00:27 -0700623 ANV_FROM_HANDLE(anv_image_view, iview, _iview);
Jason Ekstrandb94b8df2015-07-10 12:25:30 -0700624
Chad Versace24de3d42015-10-06 19:11:58 -0700625 anv_image_view_destroy(device, iview);
Jason Ekstrand84783502015-07-10 20:18:52 -0700626}
Kristian Høgsberg37743f92015-05-22 22:59:12 -0700627
Chad Versace941b48e2015-08-28 07:08:58 -0700628struct anv_surface *
Chad Versace7a089bd2015-10-05 06:48:14 -0700629anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlags aspect_mask)
Chad Versace941b48e2015-08-28 07:08:58 -0700630{
Chad Versace7a089bd2015-10-05 06:48:14 -0700631 switch (aspect_mask) {
632 case VK_IMAGE_ASPECT_COLOR_BIT:
Chad Versace24de3d42015-10-06 19:11:58 -0700633 /* Dragons will eat you.
634 *
635 * Meta attaches all destination surfaces as color render targets. Guess
636 * what surface the Meta Dragons really want.
637 */
638 if (image->format->depth_format && image->format->has_stencil) {
639 anv_finishme("combined depth stencil formats");
640 return &image->depth_surface;
641 } else if (image->format->depth_format) {
642 return &image->depth_surface;
643 } else if (image->format->has_stencil) {
644 return &image->stencil_surface;
645 } else {
646 return &image->color_surface;
647 }
648 break;
Chad Versace7a089bd2015-10-05 06:48:14 -0700649 case VK_IMAGE_ASPECT_DEPTH_BIT:
Chad Versace941b48e2015-08-28 07:08:58 -0700650 assert(image->format->depth_format);
651 return &image->depth_surface;
Chad Versace7a089bd2015-10-05 06:48:14 -0700652 case VK_IMAGE_ASPECT_STENCIL_BIT:
Chad Versace941b48e2015-08-28 07:08:58 -0700653 assert(image->format->has_stencil);
Chad Versace941b48e2015-08-28 07:08:58 -0700654 return &image->stencil_surface;
Chad Versace7a089bd2015-10-05 06:48:14 -0700655 case VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT:
Chad Versace03dd7222015-10-07 09:03:47 -0700656 if (image->format->depth_format && image->format->has_stencil) {
657 /* FINISHME: The Vulkan spec (git a511ba2) requires support for combined
658 * depth stencil formats. Specifically, it states:
659 *
660 * At least one of ename:VK_FORMAT_D24_UNORM_S8_UINT or
661 * ename:VK_FORMAT_D32_SFLOAT_S8_UINT must be supported.
662 */
663 anv_finishme("combined depthstencil aspect");
664 return &image->depth_surface;
665 } else if (image->format->depth_format) {
666 return &image->depth_surface;
667 } else if (image->format->has_stencil) {
668 return &image->stencil_surface;
669 }
670 /* fallthrough */
Chad Versace941b48e2015-08-28 07:08:58 -0700671 default:
672 unreachable("image does not have aspect");
673 return NULL;
674 }
675}
676
Chad Versace6dea1a92015-10-07 07:30:52 -0700677#if 0
Chad Versace24de3d42015-10-06 19:11:58 -0700678 VkImageAspectFlags aspect_mask = 0;
679 if (format->depth_format)
680 aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
681 if (format->has_stencil)
682 aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
683 if (!aspect_mask)
684 aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
685
686 anv_image_view_init(iview, device,
687 &(VkImageViewCreateInfo) {
688 .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
689 .image = info->image,
690 .viewType = VK_IMAGE_VIEW_TYPE_2D,
691 .format = info->format,
692 .channels = {
693 .r = VK_CHANNEL_SWIZZLE_R,
694 .g = VK_CHANNEL_SWIZZLE_G,
695 .b = VK_CHANNEL_SWIZZLE_B,
696 .a = VK_CHANNEL_SWIZZLE_A,
697 },
698 .subresourceRange = {
699 .aspectMask = aspect_mask,
700 .baseMipLevel = info->mipLevel,
701 .mipLevels = 1,
702 .baseArrayLayer = info->baseArraySlice,
703 .arraySize = info->arraySize,
704 },
705 },
706 NULL);
Chad Versace6dea1a92015-10-07 07:30:52 -0700707#endif