vk/image: Move validation for vkCreateImageView
[mesa.git] / src / vulkan / image.c
1 /*
2 * Copyright © 2015 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <assert.h>
25 #include <stdbool.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <fcntl.h>
29
30 #include "private.h"
31
32 static const uint8_t anv_halign[] = {
33 [4] = HALIGN4,
34 [8] = HALIGN8,
35 [16] = HALIGN16,
36 };
37
38 static const uint8_t anv_valign[] = {
39 [4] = VALIGN4,
40 [8] = VALIGN8,
41 [16] = VALIGN16,
42 };
43
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,
48 };
49
50 static const uint8_t anv_surf_type_from_image_view_type[] = {
51 [VK_IMAGE_VIEW_TYPE_1D] = SURFTYPE_1D,
52 [VK_IMAGE_VIEW_TYPE_2D] = SURFTYPE_2D,
53 [VK_IMAGE_VIEW_TYPE_3D] = SURFTYPE_3D,
54 [VK_IMAGE_VIEW_TYPE_CUBE] = SURFTYPE_CUBE,
55 };
56
57 static const struct anv_surf_type_limits {
58 int32_t width;
59 int32_t height;
60 int32_t depth;
61 } anv_surf_type_limits[] = {
62 [SURFTYPE_1D] = {16384, 0, 2048},
63 [SURFTYPE_2D] = {16384, 16384, 2048},
64 [SURFTYPE_3D] = {2048, 2048, 2048},
65 [SURFTYPE_CUBE] = {16384, 16384, 340},
66 [SURFTYPE_BUFFER] = {128, 16384, 64},
67 [SURFTYPE_STRBUF] = {128, 16384, 64},
68 };
69
70 static const struct anv_tile_info {
71 uint32_t width;
72 uint32_t height;
73
74 /**
75 * Alignment for RENDER_SURFACE_STATE.SurfaceBaseAddress.
76 *
77 * To simplify calculations, the alignments defined in the table are
78 * sometimes larger than required. For example, Skylake requires that X and
79 * Y tiled buffers be aligned to 4K, but Broadwell permits smaller
80 * alignment. We choose 4K to accomodate both chipsets. The alignment of
81 * a linear buffer depends on its element type and usage. Linear depth
82 * buffers have the largest alignment, 64B, so we choose that for all linear
83 * buffers.
84 */
85 uint32_t surface_alignment;
86 } anv_tile_info_table[] = {
87 [LINEAR] = { 1, 1, 64 },
88 [XMAJOR] = { 512, 8, 4096 },
89 [YMAJOR] = { 128, 32, 4096 },
90 [WMAJOR] = { 128, 32, 4096 },
91 };
92
93 static uint32_t
94 anv_image_choose_tile_mode(const struct anv_image_create_info *anv_info)
95 {
96 if (anv_info->force_tile_mode)
97 return anv_info->tile_mode;
98
99 if (anv_info->vk_info->format == VK_FORMAT_S8_UINT)
100 return WMAJOR;
101
102 switch (anv_info->vk_info->tiling) {
103 case VK_IMAGE_TILING_LINEAR:
104 return LINEAR;
105 case VK_IMAGE_TILING_OPTIMAL:
106 return YMAJOR;
107 default:
108 assert(!"bad VKImageTiling");
109 return LINEAR;
110 }
111 }
112
113 static VkResult
114 anv_image_make_surface(const struct anv_image_create_info *create_info,
115 uint64_t *inout_image_size,
116 uint32_t *inout_image_alignment,
117 struct anv_surface *out_surface)
118 {
119 /* See RENDER_SURFACE_STATE.SurfaceQPitch */
120 static const uint16_t min_qpitch UNUSED = 0x4;
121 static const uint16_t max_qpitch UNUSED = 0x1ffc;
122
123 const VkExtent3D *restrict extent = &create_info->vk_info->extent;
124 const uint32_t levels = create_info->vk_info->mipLevels;
125 const uint32_t array_size = create_info->vk_info->arraySize;
126
127 const uint8_t tile_mode = anv_image_choose_tile_mode(create_info);
128
129 const struct anv_tile_info *tile_info =
130 &anv_tile_info_table[tile_mode];
131
132 const struct anv_format *format_info =
133 anv_format_for_vk_format(create_info->vk_info->format);
134
135 const uint32_t i = 4; /* FINISHME: Stop hardcoding subimage alignment */
136 const uint32_t j = 4; /* FINISHME: Stop hardcoding subimage alignment */
137 const uint32_t w0 = align_u32(extent->width, i);
138 const uint32_t h0 = align_u32(extent->height, j);
139
140 uint16_t qpitch;
141 uint32_t mt_width;
142 uint32_t mt_height;
143
144 if (levels == 1 && array_size == 1) {
145 qpitch = min_qpitch;
146 mt_width = w0;
147 mt_height = h0;
148 } else {
149 uint32_t w1 = align_u32(anv_minify(extent->width, 1), i);
150 uint32_t h1 = align_u32(anv_minify(extent->height, 1), j);
151 uint32_t w2 = align_u32(anv_minify(extent->width, 2), i);
152
153 qpitch = h0 + h1 + 11 * j;
154 mt_width = MAX(w0, w1 + w2);
155 mt_height = array_size * qpitch;
156 }
157
158 assert(qpitch >= min_qpitch);
159 if (qpitch > max_qpitch) {
160 anv_loge("image qpitch > 0x%x\n", max_qpitch);
161 return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY);
162 }
163
164 /* From the Broadwell PRM, RENDER_SURFACE_STATE.SurfaceQpitch:
165 *
166 * This field must be set an integer multiple of the Surface Vertical
167 * Alignment.
168 */
169 assert(anv_is_aligned(qpitch, j));
170
171 const uint32_t stride = align_u32(mt_width * format_info->cpp,
172 tile_info->width);
173 const uint32_t size = stride * align_u32(mt_height, tile_info->height);
174 const uint32_t offset = align_u32(*inout_image_size,
175 tile_info->surface_alignment);
176
177 *inout_image_size = offset + size;
178 *inout_image_alignment = MAX(*inout_image_alignment,
179 tile_info->surface_alignment);
180
181 *out_surface = (struct anv_surface) {
182 .offset = offset,
183 .stride = stride,
184 .tile_mode = tile_mode,
185 .qpitch = qpitch,
186 .h_align = i,
187 .v_align = j,
188 };
189
190 return VK_SUCCESS;
191 }
192
193 VkResult
194 anv_image_create(VkDevice _device,
195 const struct anv_image_create_info *create_info,
196 VkImage *pImage)
197 {
198 struct anv_device *device = (struct anv_device *) _device;
199 const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
200 const VkExtent3D *restrict extent = &pCreateInfo->extent;
201 struct anv_image *image = NULL;
202 VkResult r;
203
204 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
205
206 /* XXX: We don't handle any of these */
207 anv_assert(pCreateInfo->imageType == VK_IMAGE_TYPE_2D);
208 anv_assert(pCreateInfo->mipLevels > 0);
209 anv_assert(pCreateInfo->arraySize > 0);
210 anv_assert(pCreateInfo->samples == 1);
211 anv_assert(pCreateInfo->extent.width > 0);
212 anv_assert(pCreateInfo->extent.height > 0);
213 anv_assert(pCreateInfo->extent.depth > 0);
214
215 /* TODO(chadv): How should we validate inputs? */
216 const uint8_t surf_type =
217 anv_surf_type_from_image_type[pCreateInfo->imageType];
218
219 const struct anv_surf_type_limits *limits =
220 &anv_surf_type_limits[surf_type];
221
222 if (extent->width > limits->width ||
223 extent->height > limits->height ||
224 extent->depth > limits->depth) {
225 /* TODO(chadv): What is the correct error? */
226 anv_loge("image extent is too large");
227 return vk_error(VK_ERROR_INVALID_MEMORY_SIZE);
228 }
229
230 const struct anv_format *format_info =
231 anv_format_for_vk_format(pCreateInfo->format);
232
233 image = anv_device_alloc(device, sizeof(*image), 8,
234 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
235 if (!image)
236 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
237
238 memset(image, 0, sizeof(*image));
239 image->type = pCreateInfo->imageType;
240 image->extent = pCreateInfo->extent;
241 image->format = pCreateInfo->format;
242 image->levels = pCreateInfo->mipLevels;
243 image->array_size = pCreateInfo->arraySize;
244 image->surf_type = surf_type;
245
246 if (likely(!format_info->has_stencil || format_info->depth_format)) {
247 /* The image's primary surface is a color or depth surface. */
248 r = anv_image_make_surface(create_info, &image->size, &image->alignment,
249 &image->primary_surface);
250 if (r != VK_SUCCESS)
251 goto fail;
252 }
253
254 if (format_info->has_stencil) {
255 /* From the GPU's perspective, the depth buffer and stencil buffer are
256 * separate buffers. From Vulkan's perspective, though, depth and
257 * stencil reside in the same image. To satisfy Vulkan and the GPU, we
258 * place the depth and stencil buffers in the same bo.
259 */
260 VkImageCreateInfo stencil_info = *pCreateInfo;
261 stencil_info.format = VK_FORMAT_S8_UINT;
262
263 r = anv_image_make_surface(
264 &(struct anv_image_create_info) {
265 .vk_info = &stencil_info,
266 },
267 &image->size, &image->alignment, &image->stencil_surface);
268
269 if (r != VK_SUCCESS)
270 goto fail;
271 }
272
273 *pImage = (VkImage) image;
274
275 return VK_SUCCESS;
276
277 fail:
278 if (image)
279 anv_device_free(device, image);
280
281 return r;
282 }
283
284 VkResult
285 anv_CreateImage(VkDevice device,
286 const VkImageCreateInfo *pCreateInfo,
287 VkImage *pImage)
288 {
289 return anv_image_create(device,
290 &(struct anv_image_create_info) {
291 .vk_info = pCreateInfo,
292 },
293 pImage);
294 }
295
296 VkResult
297 anv_GetImageSubresourceInfo(VkDevice device,
298 VkImage image,
299 const VkImageSubresource *pSubresource,
300 VkSubresourceInfoType infoType,
301 size_t *pDataSize,
302 void *pData)
303 {
304 stub_return(VK_UNSUPPORTED);
305 }
306
307 void
308 anv_surface_view_destroy(struct anv_device *device,
309 struct anv_object *obj, VkObjectType obj_type)
310 {
311 struct anv_surface_view *view = (struct anv_surface_view *)obj;
312
313 assert(obj_type == VK_OBJECT_TYPE_BUFFER_VIEW ||
314 obj_type == VK_OBJECT_TYPE_IMAGE_VIEW ||
315 obj_type == VK_OBJECT_TYPE_COLOR_ATTACHMENT_VIEW);
316
317 anv_state_pool_free(&device->surface_state_pool, view->surface_state);
318
319 anv_device_free(device, view);
320 }
321
322 void
323 anv_image_view_init(struct anv_surface_view *view,
324 struct anv_device *device,
325 const VkImageViewCreateInfo* pCreateInfo,
326 struct anv_cmd_buffer *cmd_buffer)
327 {
328 const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
329 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
330 struct anv_surface *surface;
331
332 const struct anv_format *format_info =
333 anv_format_for_vk_format(pCreateInfo->format);
334
335 if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
336 anv_finishme("non-2D image views");
337
338 switch (pCreateInfo->subresourceRange.aspect) {
339 case VK_IMAGE_ASPECT_STENCIL:
340 anv_finishme("stencil image views");
341 abort();
342 break;
343 case VK_IMAGE_ASPECT_DEPTH:
344 case VK_IMAGE_ASPECT_COLOR:
345 view->offset = image->offset;
346 surface = &image->primary_surface;
347 break;
348 default:
349 unreachable("");
350 break;
351 }
352
353 view->bo = image->bo;
354 view->offset = image->offset + surface->offset;
355 view->format = pCreateInfo->format;
356
357 view->extent = (VkExtent3D) {
358 .width = anv_minify(image->extent.width, range->baseMipLevel),
359 .height = anv_minify(image->extent.height, range->baseMipLevel),
360 .depth = anv_minify(image->extent.depth, range->baseMipLevel),
361 };
362
363 uint32_t depth = 1;
364 if (range->arraySize > 1) {
365 depth = range->arraySize;
366 } else if (image->extent.depth > 1) {
367 depth = image->extent.depth;
368 }
369
370 static const uint32_t vk_to_gen_swizzle[] = {
371 [VK_CHANNEL_SWIZZLE_ZERO] = SCS_ZERO,
372 [VK_CHANNEL_SWIZZLE_ONE] = SCS_ONE,
373 [VK_CHANNEL_SWIZZLE_R] = SCS_RED,
374 [VK_CHANNEL_SWIZZLE_G] = SCS_GREEN,
375 [VK_CHANNEL_SWIZZLE_B] = SCS_BLUE,
376 [VK_CHANNEL_SWIZZLE_A] = SCS_ALPHA
377 };
378
379 struct GEN8_RENDER_SURFACE_STATE surface_state = {
380 .SurfaceType = anv_surf_type_from_image_view_type[pCreateInfo->viewType],
381 .SurfaceArray = image->array_size > 1,
382 .SurfaceFormat = format_info->surface_format,
383 .SurfaceVerticalAlignment = anv_valign[surface->v_align],
384 .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
385 .TileMode = surface->tile_mode,
386 .VerticalLineStride = 0,
387 .VerticalLineStrideOffset = 0,
388 .SamplerL2BypassModeDisable = true,
389 .RenderCacheReadWriteMode = WriteOnlyCache,
390 .MemoryObjectControlState = GEN8_MOCS,
391 .BaseMipLevel = (float) pCreateInfo->minLod,
392 .SurfaceQPitch = surface->qpitch >> 2,
393 .Height = image->extent.height - 1,
394 .Width = image->extent.width - 1,
395 .Depth = depth - 1,
396 .SurfacePitch = surface->stride - 1,
397 .MinimumArrayElement = range->baseArraySlice,
398 .NumberofMultisamples = MULTISAMPLECOUNT_1,
399 .XOffset = 0,
400 .YOffset = 0,
401
402 /* For sampler surfaces, the hardware interprets field MIPCount/LOD as
403 * MIPCount. The range of levels accessible by the sampler engine is
404 * [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
405 */
406 .MIPCountLOD = range->mipLevels - 1,
407 .SurfaceMinLOD = range->baseMipLevel,
408
409 .AuxiliarySurfaceMode = AUX_NONE,
410 .RedClearColor = 0,
411 .GreenClearColor = 0,
412 .BlueClearColor = 0,
413 .AlphaClearColor = 0,
414 .ShaderChannelSelectRed = vk_to_gen_swizzle[pCreateInfo->channels.r],
415 .ShaderChannelSelectGreen = vk_to_gen_swizzle[pCreateInfo->channels.g],
416 .ShaderChannelSelectBlue = vk_to_gen_swizzle[pCreateInfo->channels.b],
417 .ShaderChannelSelectAlpha = vk_to_gen_swizzle[pCreateInfo->channels.a],
418 .ResourceMinLOD = 0.0,
419 .SurfaceBaseAddress = { NULL, view->offset },
420 };
421
422 if (cmd_buffer)
423 view->surface_state =
424 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
425 else
426 view->surface_state =
427 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
428
429 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
430 }
431
432 VkResult
433 anv_validate_CreateImageView(VkDevice _device,
434 const VkImageViewCreateInfo *pCreateInfo,
435 VkImageView *pView)
436 {
437 const struct anv_image *image;
438 const VkImageSubresourceRange *range;
439
440 assert(pCreateInfo);
441 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO);
442 assert(pView);
443
444 image = (struct anv_image *) pCreateInfo->image;
445 range = &pCreateInfo->subresourceRange;
446
447 assert(range->mipLevels > 0);
448 assert(range->arraySize > 0);
449 assert(range->baseMipLevel + range->mipLevels <= image->levels);
450 assert(range->baseArraySlice + range->arraySize <= image->array_size);
451
452 return anv_CreateImageView(_device, pCreateInfo, pView);
453 }
454
455 VkResult
456 anv_CreateImageView(VkDevice _device,
457 const VkImageViewCreateInfo *pCreateInfo,
458 VkImageView *pView)
459 {
460 struct anv_device *device = (struct anv_device *) _device;
461 struct anv_surface_view *view;
462
463 view = anv_device_alloc(device, sizeof(*view), 8,
464 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
465 if (view == NULL)
466 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
467
468 anv_image_view_init(view, device, pCreateInfo, NULL);
469
470 view->base.destructor = anv_surface_view_destroy;
471
472 *pView = (VkImageView) view;
473
474 return VK_SUCCESS;
475 }
476
477 void
478 anv_color_attachment_view_init(struct anv_surface_view *view,
479 struct anv_device *device,
480 const VkColorAttachmentViewCreateInfo* pCreateInfo,
481 struct anv_cmd_buffer *cmd_buffer)
482 {
483 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
484 struct anv_surface *surface = &image->primary_surface;
485 const struct anv_format *format_info =
486 anv_format_for_vk_format(pCreateInfo->format);
487
488 anv_assert(pCreateInfo->arraySize > 0);
489 anv_assert(pCreateInfo->mipLevel < image->levels);
490 anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
491
492 if (pCreateInfo->msaaResolveImage)
493 anv_finishme("msaaResolveImage");
494
495 view->bo = image->bo;
496 view->offset = image->offset + surface->offset;
497 view->format = pCreateInfo->format;
498
499 view->extent = (VkExtent3D) {
500 .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
501 .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
502 .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
503 };
504
505 uint32_t depth = 1;
506 if (pCreateInfo->arraySize > 1) {
507 depth = pCreateInfo->arraySize;
508 } else if (image->extent.depth > 1) {
509 depth = image->extent.depth;
510 }
511
512 if (cmd_buffer)
513 view->surface_state =
514 anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
515 else
516 view->surface_state =
517 anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
518
519 struct GEN8_RENDER_SURFACE_STATE surface_state = {
520 .SurfaceType = SURFTYPE_2D,
521 .SurfaceArray = image->array_size > 1,
522 .SurfaceFormat = format_info->surface_format,
523 .SurfaceVerticalAlignment = anv_valign[surface->v_align],
524 .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
525 .TileMode = surface->tile_mode,
526 .VerticalLineStride = 0,
527 .VerticalLineStrideOffset = 0,
528 .SamplerL2BypassModeDisable = true,
529 .RenderCacheReadWriteMode = WriteOnlyCache,
530 .MemoryObjectControlState = GEN8_MOCS,
531 .BaseMipLevel = 0.0,
532 .SurfaceQPitch = surface->qpitch >> 2,
533 .Height = image->extent.height - 1,
534 .Width = image->extent.width - 1,
535 .Depth = depth - 1,
536 .SurfacePitch = surface->stride - 1,
537 .MinimumArrayElement = pCreateInfo->baseArraySlice,
538 .NumberofMultisamples = MULTISAMPLECOUNT_1,
539 .XOffset = 0,
540 .YOffset = 0,
541
542 /* For render target surfaces, the hardware interprets field MIPCount/LOD as
543 * LOD. The Broadwell PRM says:
544 *
545 * MIPCountLOD defines the LOD that will be rendered into.
546 * SurfaceMinLOD is ignored.
547 */
548 .SurfaceMinLOD = 0,
549 .MIPCountLOD = pCreateInfo->mipLevel,
550
551 .AuxiliarySurfaceMode = AUX_NONE,
552 .RedClearColor = 0,
553 .GreenClearColor = 0,
554 .BlueClearColor = 0,
555 .AlphaClearColor = 0,
556 .ShaderChannelSelectRed = SCS_RED,
557 .ShaderChannelSelectGreen = SCS_GREEN,
558 .ShaderChannelSelectBlue = SCS_BLUE,
559 .ShaderChannelSelectAlpha = SCS_ALPHA,
560 .ResourceMinLOD = 0.0,
561 .SurfaceBaseAddress = { NULL, view->offset },
562 };
563
564 GEN8_RENDER_SURFACE_STATE_pack(NULL, view->surface_state.map, &surface_state);
565 }
566
567 VkResult
568 anv_CreateColorAttachmentView(VkDevice _device,
569 const VkColorAttachmentViewCreateInfo *pCreateInfo,
570 VkColorAttachmentView *pView)
571 {
572 struct anv_device *device = (struct anv_device *) _device;
573 struct anv_surface_view *view;
574
575 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_COLOR_ATTACHMENT_VIEW_CREATE_INFO);
576
577 view = anv_device_alloc(device, sizeof(*view), 8,
578 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
579 if (view == NULL)
580 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
581
582 anv_color_attachment_view_init(view, device, pCreateInfo, NULL);
583
584 view->base.destructor = anv_surface_view_destroy;
585
586 *pView = (VkColorAttachmentView) view;
587
588 return VK_SUCCESS;
589 }
590
591 VkResult
592 anv_CreateDepthStencilView(VkDevice _device,
593 const VkDepthStencilViewCreateInfo *pCreateInfo,
594 VkDepthStencilView *pView)
595 {
596 struct anv_device *device = (struct anv_device *) _device;
597 struct anv_depth_stencil_view *view;
598 struct anv_image *image = (struct anv_image *) pCreateInfo->image;
599 struct anv_surface *depth_surface = &image->primary_surface;
600 struct anv_surface *stencil_surface = &image->stencil_surface;
601 const struct anv_format *format =
602 anv_format_for_vk_format(image->format);
603
604 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_DEPTH_STENCIL_VIEW_CREATE_INFO);
605
606 view = anv_device_alloc(device, sizeof(*view), 8,
607 VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
608 if (view == NULL)
609 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
610
611 /* XXX: We don't handle any of these */
612 anv_assert(pCreateInfo->mipLevel == 0);
613 anv_assert(pCreateInfo->baseArraySlice == 0);
614 anv_assert(pCreateInfo->arraySize == 1);
615 anv_assert(pCreateInfo->msaaResolveImage == 0);
616
617 view->bo = image->bo;
618
619 view->depth_stride = depth_surface->stride;
620 view->depth_offset = image->offset + depth_surface->offset;
621 view->depth_format = format->depth_format;
622 view->depth_qpitch = 0; /* FINISHME: QPitch */
623
624 view->stencil_stride = stencil_surface->stride;
625 view->stencil_offset = image->offset + stencil_surface->offset;
626 view->stencil_qpitch = 0; /* FINISHME: QPitch */
627
628 *pView = (VkDepthStencilView) view;
629
630 return VK_SUCCESS;
631 }