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 "anv_private.h"
25
26 #include "vk_format_info.h"
27 #include "vk_util.h"
28
29 static void
anv_render_pass_add_subpass_dep(struct anv_device * device,struct anv_render_pass * pass,const VkSubpassDependency2KHR * dep)30 anv_render_pass_add_subpass_dep(struct anv_device *device,
31 struct anv_render_pass *pass,
32 const VkSubpassDependency2KHR *dep)
33 {
34 if (dep->dstSubpass == VK_SUBPASS_EXTERNAL) {
35 pass->subpass_flushes[pass->subpass_count] |=
36 anv_pipe_invalidate_bits_for_access_flags(device, dep->dstAccessMask);
37 } else {
38 assert(dep->dstSubpass < pass->subpass_count);
39 pass->subpass_flushes[dep->dstSubpass] |=
40 anv_pipe_invalidate_bits_for_access_flags(device, dep->dstAccessMask);
41 }
42
43 if (dep->srcSubpass == VK_SUBPASS_EXTERNAL) {
44 pass->subpass_flushes[0] |=
45 anv_pipe_flush_bits_for_access_flags(device, dep->srcAccessMask);
46 } else {
47 assert(dep->srcSubpass < pass->subpass_count);
48 pass->subpass_flushes[dep->srcSubpass + 1] |=
49 anv_pipe_flush_bits_for_access_flags(device, dep->srcAccessMask);
50 }
51 }
52
53 /* Do a second "compile" step on a render pass */
54 static void
anv_render_pass_compile(struct anv_render_pass * pass)55 anv_render_pass_compile(struct anv_render_pass *pass)
56 {
57 /* The CreateRenderPass code zeros the entire render pass and also uses a
58 * designated initializer for filling these out. There's no need for us to
59 * do it again.
60 *
61 * for (uint32_t i = 0; i < pass->attachment_count; i++) {
62 * pass->attachments[i].usage = 0;
63 * pass->attachments[i].first_subpass_layout = VK_IMAGE_LAYOUT_UNDEFINED;
64 * }
65 */
66
67 VkImageUsageFlags all_usage = 0;
68 for (uint32_t i = 0; i < pass->subpass_count; i++) {
69 struct anv_subpass *subpass = &pass->subpasses[i];
70
71 /* We don't allow depth_stencil_attachment to be non-NULL and be
72 * VK_ATTACHMENT_UNUSED. This way something can just check for NULL
73 * and be guaranteed that they have a valid attachment.
74 */
75 if (subpass->depth_stencil_attachment &&
76 subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED)
77 subpass->depth_stencil_attachment = NULL;
78
79 if (subpass->ds_resolve_attachment &&
80 subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED)
81 subpass->ds_resolve_attachment = NULL;
82
83 for (uint32_t j = 0; j < subpass->attachment_count; j++) {
84 struct anv_subpass_attachment *subpass_att = &subpass->attachments[j];
85 if (subpass_att->attachment == VK_ATTACHMENT_UNUSED)
86 continue;
87
88 struct anv_render_pass_attachment *pass_att =
89 &pass->attachments[subpass_att->attachment];
90
91 pass_att->usage |= subpass_att->usage;
92 pass_att->last_subpass_idx = i;
93
94 all_usage |= subpass_att->usage;
95
96 if (pass_att->first_subpass_layout == VK_IMAGE_LAYOUT_UNDEFINED) {
97 pass_att->first_subpass_layout = subpass_att->layout;
98 assert(pass_att->first_subpass_layout != VK_IMAGE_LAYOUT_UNDEFINED);
99 }
100
101 if (subpass_att->usage == VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT &&
102 subpass->depth_stencil_attachment &&
103 subpass_att->attachment == subpass->depth_stencil_attachment->attachment)
104 subpass->has_ds_self_dep = true;
105 }
106
107 /* We have to handle resolve attachments specially */
108 subpass->has_color_resolve = false;
109 if (subpass->resolve_attachments) {
110 for (uint32_t j = 0; j < subpass->color_count; j++) {
111 struct anv_subpass_attachment *color_att =
112 &subpass->color_attachments[j];
113 struct anv_subpass_attachment *resolve_att =
114 &subpass->resolve_attachments[j];
115 if (resolve_att->attachment == VK_ATTACHMENT_UNUSED)
116 continue;
117
118 subpass->has_color_resolve = true;
119
120 assert(color_att->attachment < pass->attachment_count);
121 struct anv_render_pass_attachment *color_pass_att =
122 &pass->attachments[color_att->attachment];
123
124 assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT);
125 assert(color_att->usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
126 color_pass_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
127 }
128 }
129
130 if (subpass->ds_resolve_attachment) {
131 struct anv_subpass_attachment *ds_att =
132 subpass->depth_stencil_attachment;
133 UNUSED struct anv_subpass_attachment *resolve_att =
134 subpass->ds_resolve_attachment;
135
136 assert(ds_att->attachment < pass->attachment_count);
137 struct anv_render_pass_attachment *ds_pass_att =
138 &pass->attachments[ds_att->attachment];
139
140 assert(resolve_att->usage == VK_IMAGE_USAGE_TRANSFER_DST_BIT);
141 assert(ds_att->usage == VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT);
142 ds_pass_att->usage |= VK_IMAGE_USAGE_TRANSFER_SRC_BIT;
143 }
144
145 for (uint32_t j = 0; j < subpass->attachment_count; j++)
146 assert(__builtin_popcount(subpass->attachments[j].usage) == 1);
147 }
148
149 /* From the Vulkan 1.0.39 spec:
150 *
151 * If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
152 * first subpass that uses an attachment, then an implicit subpass
153 * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
154 * used in. The subpass dependency operates as if defined with the
155 * following parameters:
156 *
157 * VkSubpassDependency implicitDependency = {
158 * .srcSubpass = VK_SUBPASS_EXTERNAL;
159 * .dstSubpass = firstSubpass; // First subpass attachment is used in
160 * .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
161 * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
162 * .srcAccessMask = 0;
163 * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
164 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
165 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
166 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
167 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
168 * .dependencyFlags = 0;
169 * };
170 *
171 * Similarly, if there is no subpass dependency from the last subpass
172 * that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
173 * subpass dependency exists from the last subpass it is used in to
174 * VK_SUBPASS_EXTERNAL. The subpass dependency operates as if defined
175 * with the following parameters:
176 *
177 * VkSubpassDependency implicitDependency = {
178 * .srcSubpass = lastSubpass; // Last subpass attachment is used in
179 * .dstSubpass = VK_SUBPASS_EXTERNAL;
180 * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
181 * .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
182 * .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
183 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
184 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
185 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
186 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
187 * .dstAccessMask = 0;
188 * .dependencyFlags = 0;
189 * };
190 *
191 * We could implement this by walking over all of the attachments and
192 * subpasses and checking to see if any of them don't have an external
193 * dependency. Or, we could just be lazy and add a couple extra flushes.
194 * We choose to be lazy.
195 *
196 * From the documentation for vkCmdNextSubpass:
197 *
198 * "Moving to the next subpass automatically performs any multisample
199 * resolve operations in the subpass being ended. End-of-subpass
200 * multisample resolves are treated as color attachment writes for the
201 * purposes of synchronization. This applies to resolve operations for
202 * both color and depth/stencil attachments. That is, they are
203 * considered to execute in the
204 * VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT pipeline stage and
205 * their writes are synchronized with
206 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT."
207 *
208 * Therefore, the above flags concerning color attachments also apply to
209 * color and depth/stencil resolve attachments.
210 */
211 if (all_usage & VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT) {
212 pass->subpass_flushes[0] |=
213 ANV_PIPE_TEXTURE_CACHE_INVALIDATE_BIT;
214 }
215 if (all_usage & (VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
216 VK_IMAGE_USAGE_TRANSFER_DST_BIT)) {
217 pass->subpass_flushes[pass->subpass_count] |=
218 ANV_PIPE_RENDER_TARGET_CACHE_FLUSH_BIT;
219 }
220 if (all_usage & VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT) {
221 pass->subpass_flushes[pass->subpass_count] |=
222 ANV_PIPE_DEPTH_CACHE_FLUSH_BIT;
223 }
224 }
225
226 static unsigned
num_subpass_attachments(const VkSubpassDescription * desc)227 num_subpass_attachments(const VkSubpassDescription *desc)
228 {
229 return desc->inputAttachmentCount +
230 desc->colorAttachmentCount +
231 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
232 (desc->pDepthStencilAttachment != NULL);
233 }
234
anv_CreateRenderPass(VkDevice _device,const VkRenderPassCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)235 VkResult anv_CreateRenderPass(
236 VkDevice _device,
237 const VkRenderPassCreateInfo* pCreateInfo,
238 const VkAllocationCallbacks* pAllocator,
239 VkRenderPass* pRenderPass)
240 {
241 ANV_FROM_HANDLE(anv_device, device, _device);
242
243 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO);
244
245 struct anv_render_pass *pass;
246 struct anv_subpass *subpasses;
247 struct anv_render_pass_attachment *attachments;
248 enum anv_pipe_bits *subpass_flushes;
249
250 ANV_MULTIALLOC(ma);
251 anv_multialloc_add(&ma, &pass, 1);
252 anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
253 anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
254 anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1);
255
256 struct anv_subpass_attachment *subpass_attachments;
257 uint32_t subpass_attachment_count = 0;
258 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
259 subpass_attachment_count +=
260 num_subpass_attachments(&pCreateInfo->pSubpasses[i]);
261 }
262 anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count);
263
264 if (!anv_multialloc_alloc2(&ma, &device->vk.alloc, pAllocator,
265 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
266 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
267
268 /* Clear the subpasses along with the parent pass. This required because
269 * each array member of anv_subpass must be a valid pointer if not NULL.
270 */
271 memset(pass, 0, ma.size);
272 vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS);
273 pass->attachment_count = pCreateInfo->attachmentCount;
274 pass->subpass_count = pCreateInfo->subpassCount;
275 pass->attachments = attachments;
276 pass->subpass_flushes = subpass_flushes;
277
278 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
279 pass->attachments[i] = (struct anv_render_pass_attachment) {
280 .format = pCreateInfo->pAttachments[i].format,
281 .samples = pCreateInfo->pAttachments[i].samples,
282 .load_op = pCreateInfo->pAttachments[i].loadOp,
283 .store_op = pCreateInfo->pAttachments[i].storeOp,
284 .stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp,
285 .initial_layout = pCreateInfo->pAttachments[i].initialLayout,
286 .final_layout = pCreateInfo->pAttachments[i].finalLayout,
287
288 .stencil_initial_layout = pCreateInfo->pAttachments[i].initialLayout,
289 .stencil_final_layout = pCreateInfo->pAttachments[i].finalLayout,
290 };
291 }
292
293 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
294 const VkSubpassDescription *desc = &pCreateInfo->pSubpasses[i];
295 struct anv_subpass *subpass = &pass->subpasses[i];
296
297 subpass->input_count = desc->inputAttachmentCount;
298 subpass->color_count = desc->colorAttachmentCount;
299 subpass->attachment_count = num_subpass_attachments(desc);
300 subpass->attachments = subpass_attachments;
301 subpass->view_mask = 0;
302
303 if (desc->inputAttachmentCount > 0) {
304 subpass->input_attachments = subpass_attachments;
305 subpass_attachments += desc->inputAttachmentCount;
306
307 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
308 subpass->input_attachments[j] = (struct anv_subpass_attachment) {
309 .usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
310 .attachment = desc->pInputAttachments[j].attachment,
311 .layout = desc->pInputAttachments[j].layout,
312 .stencil_layout = desc->pInputAttachments[j].layout,
313 };
314 }
315 }
316
317 if (desc->colorAttachmentCount > 0) {
318 subpass->color_attachments = subpass_attachments;
319 subpass_attachments += desc->colorAttachmentCount;
320
321 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
322 subpass->color_attachments[j] = (struct anv_subpass_attachment) {
323 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
324 .attachment = desc->pColorAttachments[j].attachment,
325 .layout = desc->pColorAttachments[j].layout,
326 };
327 }
328 }
329
330 if (desc->pResolveAttachments) {
331 subpass->resolve_attachments = subpass_attachments;
332 subpass_attachments += desc->colorAttachmentCount;
333
334 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
335 subpass->resolve_attachments[j] = (struct anv_subpass_attachment) {
336 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
337 .attachment = desc->pResolveAttachments[j].attachment,
338 .layout = desc->pResolveAttachments[j].layout,
339 };
340 }
341 }
342
343 if (desc->pDepthStencilAttachment) {
344 subpass->depth_stencil_attachment = subpass_attachments++;
345
346 *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
347 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
348 .attachment = desc->pDepthStencilAttachment->attachment,
349 .layout = desc->pDepthStencilAttachment->layout,
350 .stencil_layout = desc->pDepthStencilAttachment->layout,
351 };
352 }
353 }
354
355 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
356 /* Convert to a Dependency2KHR */
357 VkSubpassDependency2 dep2 = {
358 .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass,
359 .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass,
360 .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask,
361 .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask,
362 .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask,
363 .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask,
364 .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags,
365 };
366 anv_render_pass_add_subpass_dep(device, pass, &dep2);
367 }
368
369 vk_foreach_struct(ext, pCreateInfo->pNext) {
370 switch (ext->sType) {
371 case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO:
372 /* We don't care about this information */
373 break;
374
375 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: {
376 VkRenderPassMultiviewCreateInfo *mv = (void *)ext;
377
378 for (uint32_t i = 0; i < mv->subpassCount; i++) {
379 pass->subpasses[i].view_mask = mv->pViewMasks[i];
380 }
381 break;
382 }
383
384 default:
385 anv_debug_ignored_stype(ext->sType);
386 }
387 }
388
389 anv_render_pass_compile(pass);
390
391 *pRenderPass = anv_render_pass_to_handle(pass);
392
393 return VK_SUCCESS;
394 }
395
396 static unsigned
num_subpass_attachments2(const VkSubpassDescription2KHR * desc)397 num_subpass_attachments2(const VkSubpassDescription2KHR *desc)
398 {
399 const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =
400 vk_find_struct_const(desc->pNext,
401 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);
402
403 return desc->inputAttachmentCount +
404 desc->colorAttachmentCount +
405 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) +
406 (desc->pDepthStencilAttachment != NULL) +
407 (ds_resolve && ds_resolve->pDepthStencilResolveAttachment);
408 }
409
410 static bool
vk_image_layout_depth_only(VkImageLayout layout)411 vk_image_layout_depth_only(VkImageLayout layout)
412 {
413 switch (layout) {
414 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL:
415 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL:
416 return true;
417
418 default:
419 return false;
420 }
421 }
422
423 /* From the Vulkan Specification 1.2.166 - VkAttachmentReference2:
424 *
425 * "If layout only specifies the layout of the depth aspect of the
426 * attachment, the layout of the stencil aspect is specified by the
427 * stencilLayout member of a VkAttachmentReferenceStencilLayout structure
428 * included in the pNext chain. Otherwise, layout describes the layout for
429 * all relevant image aspects."
430 */
431 static VkImageLayout
stencil_ref_layout(const VkAttachmentReference2KHR * att_ref)432 stencil_ref_layout(const VkAttachmentReference2KHR *att_ref)
433 {
434 if (!vk_image_layout_depth_only(att_ref->layout))
435 return att_ref->layout;
436
437 const VkAttachmentReferenceStencilLayoutKHR *stencil_ref =
438 vk_find_struct_const(att_ref->pNext,
439 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR);
440 if (!stencil_ref)
441 return VK_IMAGE_LAYOUT_UNDEFINED;
442 return stencil_ref->stencilLayout;
443 }
444
445 /* From the Vulkan Specification 1.2.166 - VkAttachmentDescription2:
446 *
447 * "If format is a depth/stencil format, and initialLayout only specifies
448 * the initial layout of the depth aspect of the attachment, the initial
449 * layout of the stencil aspect is specified by the stencilInitialLayout
450 * member of a VkAttachmentDescriptionStencilLayout structure included in
451 * the pNext chain. Otherwise, initialLayout describes the initial layout
452 * for all relevant image aspects."
453 */
454 static VkImageLayout
stencil_desc_layout(const VkAttachmentDescription2KHR * att_desc,bool final)455 stencil_desc_layout(const VkAttachmentDescription2KHR *att_desc, bool final)
456 {
457 if (!vk_format_has_stencil(att_desc->format))
458 return VK_IMAGE_LAYOUT_UNDEFINED;
459
460 const VkImageLayout main_layout =
461 final ? att_desc->finalLayout : att_desc->initialLayout;
462 if (!vk_image_layout_depth_only(main_layout))
463 return main_layout;
464
465 const VkAttachmentDescriptionStencilLayoutKHR *stencil_desc =
466 vk_find_struct_const(att_desc->pNext,
467 ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR);
468 assert(stencil_desc);
469 return final ?
470 stencil_desc->stencilFinalLayout :
471 stencil_desc->stencilInitialLayout;
472 }
473
anv_CreateRenderPass2(VkDevice _device,const VkRenderPassCreateInfo2KHR * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkRenderPass * pRenderPass)474 VkResult anv_CreateRenderPass2(
475 VkDevice _device,
476 const VkRenderPassCreateInfo2KHR* pCreateInfo,
477 const VkAllocationCallbacks* pAllocator,
478 VkRenderPass* pRenderPass)
479 {
480 ANV_FROM_HANDLE(anv_device, device, _device);
481
482 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2_KHR);
483
484 struct anv_render_pass *pass;
485 struct anv_subpass *subpasses;
486 struct anv_render_pass_attachment *attachments;
487 enum anv_pipe_bits *subpass_flushes;
488
489 ANV_MULTIALLOC(ma);
490 anv_multialloc_add(&ma, &pass, 1);
491 anv_multialloc_add(&ma, &subpasses, pCreateInfo->subpassCount);
492 anv_multialloc_add(&ma, &attachments, pCreateInfo->attachmentCount);
493 anv_multialloc_add(&ma, &subpass_flushes, pCreateInfo->subpassCount + 1);
494
495 struct anv_subpass_attachment *subpass_attachments;
496 uint32_t subpass_attachment_count = 0;
497 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
498 subpass_attachment_count +=
499 num_subpass_attachments2(&pCreateInfo->pSubpasses[i]);
500 }
501 anv_multialloc_add(&ma, &subpass_attachments, subpass_attachment_count);
502
503 if (!anv_multialloc_alloc2(&ma, &device->vk.alloc, pAllocator,
504 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT))
505 return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
506
507 /* Clear the subpasses along with the parent pass. This required because
508 * each array member of anv_subpass must be a valid pointer if not NULL.
509 */
510 memset(pass, 0, ma.size);
511 vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS);
512 pass->attachment_count = pCreateInfo->attachmentCount;
513 pass->subpass_count = pCreateInfo->subpassCount;
514 pass->attachments = attachments;
515 pass->subpass_flushes = subpass_flushes;
516
517 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) {
518 pass->attachments[i] = (struct anv_render_pass_attachment) {
519 .format = pCreateInfo->pAttachments[i].format,
520 .samples = pCreateInfo->pAttachments[i].samples,
521 .load_op = pCreateInfo->pAttachments[i].loadOp,
522 .store_op = pCreateInfo->pAttachments[i].storeOp,
523 .stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp,
524 .initial_layout = pCreateInfo->pAttachments[i].initialLayout,
525 .final_layout = pCreateInfo->pAttachments[i].finalLayout,
526
527 .stencil_initial_layout = stencil_desc_layout(&pCreateInfo->pAttachments[i],
528 false),
529 .stencil_final_layout = stencil_desc_layout(&pCreateInfo->pAttachments[i],
530 true),
531 };
532 }
533
534 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) {
535 const VkSubpassDescription2KHR *desc = &pCreateInfo->pSubpasses[i];
536 struct anv_subpass *subpass = &pass->subpasses[i];
537
538 subpass->input_count = desc->inputAttachmentCount;
539 subpass->color_count = desc->colorAttachmentCount;
540 subpass->attachment_count = num_subpass_attachments2(desc);
541 subpass->attachments = subpass_attachments;
542 subpass->view_mask = desc->viewMask;
543
544 if (desc->inputAttachmentCount > 0) {
545 subpass->input_attachments = subpass_attachments;
546 subpass_attachments += desc->inputAttachmentCount;
547
548 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) {
549 subpass->input_attachments[j] = (struct anv_subpass_attachment) {
550 .usage = VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT,
551 .attachment = desc->pInputAttachments[j].attachment,
552 .layout = desc->pInputAttachments[j].layout,
553 .stencil_layout = stencil_ref_layout(&desc->pInputAttachments[j]),
554 };
555 }
556 }
557
558 if (desc->colorAttachmentCount > 0) {
559 subpass->color_attachments = subpass_attachments;
560 subpass_attachments += desc->colorAttachmentCount;
561
562 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
563 subpass->color_attachments[j] = (struct anv_subpass_attachment) {
564 .usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT,
565 .attachment = desc->pColorAttachments[j].attachment,
566 .layout = desc->pColorAttachments[j].layout,
567 };
568 }
569 }
570
571 if (desc->pResolveAttachments) {
572 subpass->resolve_attachments = subpass_attachments;
573 subpass_attachments += desc->colorAttachmentCount;
574
575 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) {
576 subpass->resolve_attachments[j] = (struct anv_subpass_attachment) {
577 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
578 .attachment = desc->pResolveAttachments[j].attachment,
579 .layout = desc->pResolveAttachments[j].layout,
580 };
581 }
582 }
583
584 if (desc->pDepthStencilAttachment) {
585 subpass->depth_stencil_attachment = subpass_attachments++;
586
587 *subpass->depth_stencil_attachment = (struct anv_subpass_attachment) {
588 .usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
589 .attachment = desc->pDepthStencilAttachment->attachment,
590 .layout = desc->pDepthStencilAttachment->layout,
591 .stencil_layout = stencil_ref_layout(desc->pDepthStencilAttachment),
592 };
593 }
594
595 const VkSubpassDescriptionDepthStencilResolveKHR *ds_resolve =
596 vk_find_struct_const(desc->pNext,
597 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE_KHR);
598
599 if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) {
600 subpass->ds_resolve_attachment = subpass_attachments++;
601
602 *subpass->ds_resolve_attachment = (struct anv_subpass_attachment) {
603 .usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT,
604 .attachment = ds_resolve->pDepthStencilResolveAttachment->attachment,
605 .layout = ds_resolve->pDepthStencilResolveAttachment->layout,
606 .stencil_layout = stencil_ref_layout(ds_resolve->pDepthStencilResolveAttachment),
607 };
608 subpass->depth_resolve_mode = ds_resolve->depthResolveMode;
609 subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode;
610 }
611 }
612
613 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) {
614 anv_render_pass_add_subpass_dep(device, pass,
615 &pCreateInfo->pDependencies[i]);
616 }
617
618 vk_foreach_struct(ext, pCreateInfo->pNext) {
619 switch (ext->sType) {
620 default:
621 anv_debug_ignored_stype(ext->sType);
622 }
623 }
624
625 anv_render_pass_compile(pass);
626
627 *pRenderPass = anv_render_pass_to_handle(pass);
628
629 return VK_SUCCESS;
630 }
631
anv_DestroyRenderPass(VkDevice _device,VkRenderPass _pass,const VkAllocationCallbacks * pAllocator)632 void anv_DestroyRenderPass(
633 VkDevice _device,
634 VkRenderPass _pass,
635 const VkAllocationCallbacks* pAllocator)
636 {
637 ANV_FROM_HANDLE(anv_device, device, _device);
638 ANV_FROM_HANDLE(anv_render_pass, pass, _pass);
639
640 if (!pass)
641 return;
642
643 vk_object_base_finish(&pass->base);
644 vk_free2(&device->vk.alloc, pAllocator, pass);
645 }
646
anv_GetRenderAreaGranularity(VkDevice device,VkRenderPass renderPass,VkExtent2D * pGranularity)647 void anv_GetRenderAreaGranularity(
648 VkDevice device,
649 VkRenderPass renderPass,
650 VkExtent2D* pGranularity)
651 {
652 ANV_FROM_HANDLE(anv_render_pass, pass, renderPass);
653
654 /* This granularity satisfies HiZ fast clear alignment requirements
655 * for all sample counts.
656 */
657 for (unsigned i = 0; i < pass->subpass_count; ++i) {
658 if (pass->subpasses[i].depth_stencil_attachment) {
659 *pGranularity = (VkExtent2D) { .width = 8, .height = 4 };
660 return;
661 }
662 }
663
664 *pGranularity = (VkExtent2D) { 1, 1 };
665 }
666