2 * Copyright © 2016 Red Hat.
3 * Copyright © 2016 Bas Nieuwenhuizen
5 * based in part on anv driver which is:
6 * Copyright © 2015 Intel Corporation
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
27 #include "radv_private.h"
32 radv_render_pass_add_subpass_dep(struct radv_render_pass
*pass
,
33 const VkSubpassDependency2
*dep
)
35 uint32_t src
= dep
->srcSubpass
;
36 uint32_t dst
= dep
->dstSubpass
;
38 /* Ignore subpass self-dependencies as they allow the app to call
39 * vkCmdPipelineBarrier() inside the render pass and the driver should
40 * only do the barrier when called, not when starting the render pass.
45 /* Accumulate all ingoing external dependencies to the first subpass. */
46 if (src
== VK_SUBPASS_EXTERNAL
)
49 if (dst
== VK_SUBPASS_EXTERNAL
) {
50 if (dep
->dstStageMask
!= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
)
51 pass
->end_barrier
.src_stage_mask
|= dep
->srcStageMask
;
52 pass
->end_barrier
.src_access_mask
|= dep
->srcAccessMask
;
53 pass
->end_barrier
.dst_access_mask
|= dep
->dstAccessMask
;
55 if (dep
->dstStageMask
!= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
)
56 pass
->subpasses
[dst
].start_barrier
.src_stage_mask
|= dep
->srcStageMask
;
57 pass
->subpasses
[dst
].start_barrier
.src_access_mask
|= dep
->srcAccessMask
;
58 pass
->subpasses
[dst
].start_barrier
.dst_access_mask
|= dep
->dstAccessMask
;
63 radv_pass_has_layout_transitions(const struct radv_render_pass
*pass
)
65 for (unsigned i
= 0; i
< pass
->subpass_count
; i
++) {
66 const struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
67 for (unsigned j
= 0; j
< subpass
->attachment_count
; j
++) {
68 const uint32_t a
= subpass
->attachments
[j
].attachment
;
69 if (a
== VK_ATTACHMENT_UNUSED
)
72 uint32_t initial_layout
= pass
->attachments
[a
].initial_layout
;
73 uint32_t stencil_initial_layout
= pass
->attachments
[a
].stencil_initial_layout
;
74 uint32_t final_layout
= pass
->attachments
[a
].final_layout
;
75 uint32_t stencil_final_layout
= pass
->attachments
[a
].stencil_final_layout
;
77 if (subpass
->attachments
[j
].layout
!= initial_layout
||
78 subpass
->attachments
[j
].layout
!= stencil_initial_layout
||
79 subpass
->attachments
[j
].layout
!= final_layout
||
80 subpass
->attachments
[j
].layout
!= stencil_final_layout
)
89 radv_render_pass_add_implicit_deps(struct radv_render_pass
*pass
,
90 bool has_ingoing_dep
, bool has_outgoing_dep
)
92 /* From the Vulkan 1.0.39 spec:
94 * If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the
95 * first subpass that uses an attachment, then an implicit subpass
96 * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is
97 * used in. The implicit subpass dependency only exists if there
98 * exists an automatic layout transition away from initialLayout.
99 * The subpass dependency operates as if defined with the
100 * following parameters:
102 * VkSubpassDependency implicitDependency = {
103 * .srcSubpass = VK_SUBPASS_EXTERNAL;
104 * .dstSubpass = firstSubpass; // First subpass attachment is used in
105 * .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT;
106 * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
107 * .srcAccessMask = 0;
108 * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
109 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
110 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
111 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
112 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
113 * .dependencyFlags = 0;
116 * Similarly, if there is no subpass dependency from the last subpass
117 * that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit
118 * subpass dependency exists from the last subpass it is used in to
119 * VK_SUBPASS_EXTERNAL. The implicit subpass dependency only exists
120 * if there exists an automatic layout transition into finalLayout.
121 * The subpass dependency operates as if defined with the following
124 * VkSubpassDependency implicitDependency = {
125 * .srcSubpass = lastSubpass; // Last subpass attachment is used in
126 * .dstSubpass = VK_SUBPASS_EXTERNAL;
127 * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT;
128 * .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
129 * .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT |
130 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT |
131 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT |
132 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
133 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT;
134 * .dstAccessMask = 0;
135 * .dependencyFlags = 0;
139 /* Implicit subpass dependencies only make sense if automatic layout
140 * transitions are performed.
142 if (!radv_pass_has_layout_transitions(pass
))
145 if (!has_ingoing_dep
) {
146 const VkSubpassDependency2KHR implicit_ingoing_dep
= {
147 .srcSubpass
= VK_SUBPASS_EXTERNAL
,
149 .srcStageMask
= VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT
,
150 .dstStageMask
= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
,
152 .dstAccessMask
= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
|
153 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
154 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
155 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
156 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
,
157 .dependencyFlags
= 0,
160 radv_render_pass_add_subpass_dep(pass
, &implicit_ingoing_dep
);
163 if (!has_outgoing_dep
) {
164 const VkSubpassDependency2KHR implicit_outgoing_dep
= {
166 .dstSubpass
= VK_SUBPASS_EXTERNAL
,
167 .srcStageMask
= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT
,
168 .dstStageMask
= VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT
,
169 .srcAccessMask
= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT
|
170 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT
|
171 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT
|
172 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT
|
173 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT
,
175 .dependencyFlags
= 0,
178 radv_render_pass_add_subpass_dep(pass
, &implicit_outgoing_dep
);
183 radv_render_pass_compile(struct radv_render_pass
*pass
)
185 for (uint32_t i
= 0; i
< pass
->subpass_count
; i
++) {
186 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
188 for (uint32_t j
= 0; j
< subpass
->attachment_count
; j
++) {
189 struct radv_subpass_attachment
*subpass_att
=
190 &subpass
->attachments
[j
];
191 if (subpass_att
->attachment
== VK_ATTACHMENT_UNUSED
)
194 struct radv_render_pass_attachment
*pass_att
=
195 &pass
->attachments
[subpass_att
->attachment
];
197 pass_att
->first_subpass_idx
= UINT32_MAX
;
201 for (uint32_t i
= 0; i
< pass
->subpass_count
; i
++) {
202 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
203 uint32_t color_sample_count
= 1, depth_sample_count
= 1;
205 /* We don't allow depth_stencil_attachment to be non-NULL and
206 * be VK_ATTACHMENT_UNUSED. This way something can just check
207 * for NULL and be guaranteed that they have a valid
210 if (subpass
->depth_stencil_attachment
&&
211 subpass
->depth_stencil_attachment
->attachment
== VK_ATTACHMENT_UNUSED
)
212 subpass
->depth_stencil_attachment
= NULL
;
214 if (subpass
->ds_resolve_attachment
&&
215 subpass
->ds_resolve_attachment
->attachment
== VK_ATTACHMENT_UNUSED
)
216 subpass
->ds_resolve_attachment
= NULL
;
218 for (uint32_t j
= 0; j
< subpass
->attachment_count
; j
++) {
219 struct radv_subpass_attachment
*subpass_att
=
220 &subpass
->attachments
[j
];
221 if (subpass_att
->attachment
== VK_ATTACHMENT_UNUSED
)
224 struct radv_render_pass_attachment
*pass_att
=
225 &pass
->attachments
[subpass_att
->attachment
];
227 if (i
< pass_att
->first_subpass_idx
)
228 pass_att
->first_subpass_idx
= i
;
229 pass_att
->last_subpass_idx
= i
;
232 subpass
->has_color_att
= false;
233 for (uint32_t j
= 0; j
< subpass
->color_count
; j
++) {
234 struct radv_subpass_attachment
*subpass_att
=
235 &subpass
->color_attachments
[j
];
236 if (subpass_att
->attachment
== VK_ATTACHMENT_UNUSED
)
239 subpass
->has_color_att
= true;
241 struct radv_render_pass_attachment
*pass_att
=
242 &pass
->attachments
[subpass_att
->attachment
];
244 color_sample_count
= pass_att
->samples
;
247 if (subpass
->depth_stencil_attachment
) {
249 subpass
->depth_stencil_attachment
->attachment
;
250 struct radv_render_pass_attachment
*pass_att
=
251 &pass
->attachments
[a
];
252 depth_sample_count
= pass_att
->samples
;
255 subpass
->max_sample_count
= MAX2(color_sample_count
,
257 subpass
->color_sample_count
= color_sample_count
;
258 subpass
->depth_sample_count
= depth_sample_count
;
260 /* We have to handle resolve attachments specially */
261 subpass
->has_color_resolve
= false;
262 if (subpass
->resolve_attachments
) {
263 for (uint32_t j
= 0; j
< subpass
->color_count
; j
++) {
264 struct radv_subpass_attachment
*resolve_att
=
265 &subpass
->resolve_attachments
[j
];
267 if (resolve_att
->attachment
== VK_ATTACHMENT_UNUSED
)
270 subpass
->has_color_resolve
= true;
274 for (uint32_t j
= 0; j
< subpass
->input_count
; ++j
) {
275 if (subpass
->input_attachments
[j
].attachment
== VK_ATTACHMENT_UNUSED
)
278 for (uint32_t k
= 0; k
< subpass
->color_count
; ++k
) {
279 if (subpass
->color_attachments
[k
].attachment
== subpass
->input_attachments
[j
].attachment
) {
280 subpass
->input_attachments
[j
].in_render_loop
= true;
281 subpass
->color_attachments
[k
].in_render_loop
= true;
285 if (subpass
->depth_stencil_attachment
&&
286 subpass
->depth_stencil_attachment
->attachment
== subpass
->input_attachments
[j
].attachment
) {
287 subpass
->input_attachments
[j
].in_render_loop
= true;
288 subpass
->depth_stencil_attachment
->in_render_loop
= true;
295 radv_num_subpass_attachments(const VkSubpassDescription
*desc
)
297 return desc
->inputAttachmentCount
+
298 desc
->colorAttachmentCount
+
299 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
300 (desc
->pDepthStencilAttachment
!= NULL
);
304 radv_destroy_render_pass(struct radv_device
*device
,
305 const VkAllocationCallbacks
*pAllocator
,
306 struct radv_render_pass
*pass
)
308 vk_object_base_finish(&pass
->base
);
309 vk_free2(&device
->vk
.alloc
, pAllocator
, pass
->subpass_attachments
);
310 vk_free2(&device
->vk
.alloc
, pAllocator
, pass
);
313 VkResult
radv_CreateRenderPass(
315 const VkRenderPassCreateInfo
* pCreateInfo
,
316 const VkAllocationCallbacks
* pAllocator
,
317 VkRenderPass
* pRenderPass
)
319 RADV_FROM_HANDLE(radv_device
, device
, _device
);
320 struct radv_render_pass
*pass
;
322 size_t attachments_offset
;
323 VkRenderPassMultiviewCreateInfo
*multiview_info
= NULL
;
325 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO
);
327 size
= sizeof(*pass
);
328 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
329 attachments_offset
= size
;
330 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
332 pass
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, size
, 8,
333 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
335 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
337 memset(pass
, 0, size
);
339 vk_object_base_init(&device
->vk
, &pass
->base
,
340 VK_OBJECT_TYPE_RENDER_PASS
);
342 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
343 pass
->subpass_count
= pCreateInfo
->subpassCount
;
344 pass
->attachments
= (void *) pass
+ attachments_offset
;
346 vk_foreach_struct(ext
, pCreateInfo
->pNext
) {
348 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO
:
349 multiview_info
= (VkRenderPassMultiviewCreateInfo
*)ext
;
356 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
357 struct radv_render_pass_attachment
*att
= &pass
->attachments
[i
];
359 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
360 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
361 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
362 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
363 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
364 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
365 att
->stencil_initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
366 att
->stencil_final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
367 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
368 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
370 uint32_t subpass_attachment_count
= 0;
371 struct radv_subpass_attachment
*p
;
372 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
373 subpass_attachment_count
+=
374 radv_num_subpass_attachments(&pCreateInfo
->pSubpasses
[i
]);
377 if (subpass_attachment_count
) {
378 pass
->subpass_attachments
=
379 vk_alloc2(&device
->vk
.alloc
, pAllocator
,
380 subpass_attachment_count
* sizeof(struct radv_subpass_attachment
), 8,
381 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
382 if (pass
->subpass_attachments
== NULL
) {
383 radv_destroy_render_pass(device
, pAllocator
, pass
);
384 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
387 pass
->subpass_attachments
= NULL
;
389 p
= pass
->subpass_attachments
;
390 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
391 const VkSubpassDescription
*desc
= &pCreateInfo
->pSubpasses
[i
];
392 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
394 subpass
->input_count
= desc
->inputAttachmentCount
;
395 subpass
->color_count
= desc
->colorAttachmentCount
;
396 subpass
->attachment_count
= radv_num_subpass_attachments(desc
);
397 subpass
->attachments
= p
;
400 subpass
->view_mask
= multiview_info
->pViewMasks
[i
];
402 if (desc
->inputAttachmentCount
> 0) {
403 subpass
->input_attachments
= p
;
404 p
+= desc
->inputAttachmentCount
;
406 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
407 subpass
->input_attachments
[j
] = (struct radv_subpass_attachment
) {
408 .attachment
= desc
->pInputAttachments
[j
].attachment
,
409 .layout
= desc
->pInputAttachments
[j
].layout
,
410 .stencil_layout
= desc
->pInputAttachments
[j
].layout
,
415 if (desc
->colorAttachmentCount
> 0) {
416 subpass
->color_attachments
= p
;
417 p
+= desc
->colorAttachmentCount
;
419 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
420 subpass
->color_attachments
[j
] = (struct radv_subpass_attachment
) {
421 .attachment
= desc
->pColorAttachments
[j
].attachment
,
422 .layout
= desc
->pColorAttachments
[j
].layout
,
427 if (desc
->pResolveAttachments
) {
428 subpass
->resolve_attachments
= p
;
429 p
+= desc
->colorAttachmentCount
;
431 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
432 subpass
->resolve_attachments
[j
] = (struct radv_subpass_attachment
) {
433 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
434 .layout
= desc
->pResolveAttachments
[j
].layout
,
435 .stencil_layout
= desc
->pResolveAttachments
[j
].layout
,
440 if (desc
->pDepthStencilAttachment
) {
441 subpass
->depth_stencil_attachment
= p
++;
443 *subpass
->depth_stencil_attachment
= (struct radv_subpass_attachment
) {
444 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
445 .layout
= desc
->pDepthStencilAttachment
->layout
,
446 .stencil_layout
= desc
->pDepthStencilAttachment
->layout
,
451 bool has_ingoing_dep
= false;
452 bool has_outgoing_dep
= false;
454 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
455 /* Convert to a Dependency2 */
456 struct VkSubpassDependency2 dep2
= {
457 .srcSubpass
= pCreateInfo
->pDependencies
[i
].srcSubpass
,
458 .dstSubpass
= pCreateInfo
->pDependencies
[i
].dstSubpass
,
459 .srcStageMask
= pCreateInfo
->pDependencies
[i
].srcStageMask
,
460 .dstStageMask
= pCreateInfo
->pDependencies
[i
].dstStageMask
,
461 .srcAccessMask
= pCreateInfo
->pDependencies
[i
].srcAccessMask
,
462 .dstAccessMask
= pCreateInfo
->pDependencies
[i
].dstAccessMask
,
463 .dependencyFlags
= pCreateInfo
->pDependencies
[i
].dependencyFlags
,
465 radv_render_pass_add_subpass_dep(pass
, &dep2
);
467 /* Determine if the subpass has explicit dependencies from/to
468 * VK_SUBPASS_EXTERNAL.
470 if (pCreateInfo
->pDependencies
[i
].srcSubpass
== VK_SUBPASS_EXTERNAL
)
471 has_ingoing_dep
= true;
472 if (pCreateInfo
->pDependencies
[i
].dstSubpass
== VK_SUBPASS_EXTERNAL
)
473 has_outgoing_dep
= true;
476 radv_render_pass_add_implicit_deps(pass
,
477 has_ingoing_dep
, has_outgoing_dep
);
479 radv_render_pass_compile(pass
);
481 *pRenderPass
= radv_render_pass_to_handle(pass
);
487 radv_num_subpass_attachments2(const VkSubpassDescription2
*desc
)
489 const VkSubpassDescriptionDepthStencilResolve
*ds_resolve
=
490 vk_find_struct_const(desc
->pNext
,
491 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE
);
493 return desc
->inputAttachmentCount
+
494 desc
->colorAttachmentCount
+
495 (desc
->pResolveAttachments
? desc
->colorAttachmentCount
: 0) +
496 (desc
->pDepthStencilAttachment
!= NULL
) +
497 (ds_resolve
&& ds_resolve
->pDepthStencilResolveAttachment
);
500 VkResult
radv_CreateRenderPass2(
502 const VkRenderPassCreateInfo2
* pCreateInfo
,
503 const VkAllocationCallbacks
* pAllocator
,
504 VkRenderPass
* pRenderPass
)
506 RADV_FROM_HANDLE(radv_device
, device
, _device
);
507 struct radv_render_pass
*pass
;
509 size_t attachments_offset
;
511 assert(pCreateInfo
->sType
== VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2
);
513 size
= sizeof(*pass
);
514 size
+= pCreateInfo
->subpassCount
* sizeof(pass
->subpasses
[0]);
515 attachments_offset
= size
;
516 size
+= pCreateInfo
->attachmentCount
* sizeof(pass
->attachments
[0]);
518 pass
= vk_alloc2(&device
->vk
.alloc
, pAllocator
, size
, 8,
519 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
521 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
523 memset(pass
, 0, size
);
525 vk_object_base_init(&device
->vk
, &pass
->base
,
526 VK_OBJECT_TYPE_RENDER_PASS
);
528 pass
->attachment_count
= pCreateInfo
->attachmentCount
;
529 pass
->subpass_count
= pCreateInfo
->subpassCount
;
530 pass
->attachments
= (void *) pass
+ attachments_offset
;
532 for (uint32_t i
= 0; i
< pCreateInfo
->attachmentCount
; i
++) {
533 struct radv_render_pass_attachment
*att
= &pass
->attachments
[i
];
534 const VkAttachmentDescriptionStencilLayoutKHR
*stencil_layout
=
535 vk_find_struct_const(pCreateInfo
->pAttachments
[i
].pNext
,
536 ATTACHMENT_DESCRIPTION_STENCIL_LAYOUT_KHR
);
538 att
->format
= pCreateInfo
->pAttachments
[i
].format
;
539 att
->samples
= pCreateInfo
->pAttachments
[i
].samples
;
540 att
->load_op
= pCreateInfo
->pAttachments
[i
].loadOp
;
541 att
->stencil_load_op
= pCreateInfo
->pAttachments
[i
].stencilLoadOp
;
542 att
->initial_layout
= pCreateInfo
->pAttachments
[i
].initialLayout
;
543 att
->final_layout
= pCreateInfo
->pAttachments
[i
].finalLayout
;
544 att
->stencil_initial_layout
= (stencil_layout
?
545 stencil_layout
->stencilInitialLayout
:
546 pCreateInfo
->pAttachments
[i
].initialLayout
);
547 att
->stencil_final_layout
= (stencil_layout
?
548 stencil_layout
->stencilFinalLayout
:
549 pCreateInfo
->pAttachments
[i
].finalLayout
);
550 // att->store_op = pCreateInfo->pAttachments[i].storeOp;
551 // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp;
553 uint32_t subpass_attachment_count
= 0;
554 struct radv_subpass_attachment
*p
;
555 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
556 subpass_attachment_count
+=
557 radv_num_subpass_attachments2(&pCreateInfo
->pSubpasses
[i
]);
560 if (subpass_attachment_count
) {
561 pass
->subpass_attachments
=
562 vk_alloc2(&device
->vk
.alloc
, pAllocator
,
563 subpass_attachment_count
* sizeof(struct radv_subpass_attachment
), 8,
564 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT
);
565 if (pass
->subpass_attachments
== NULL
) {
566 radv_destroy_render_pass(device
, pAllocator
, pass
);
567 return vk_error(device
->instance
, VK_ERROR_OUT_OF_HOST_MEMORY
);
570 pass
->subpass_attachments
= NULL
;
572 p
= pass
->subpass_attachments
;
573 for (uint32_t i
= 0; i
< pCreateInfo
->subpassCount
; i
++) {
574 const VkSubpassDescription2
*desc
= &pCreateInfo
->pSubpasses
[i
];
575 struct radv_subpass
*subpass
= &pass
->subpasses
[i
];
577 subpass
->input_count
= desc
->inputAttachmentCount
;
578 subpass
->color_count
= desc
->colorAttachmentCount
;
579 subpass
->attachment_count
= radv_num_subpass_attachments2(desc
);
580 subpass
->attachments
= p
;
581 subpass
->view_mask
= desc
->viewMask
;
583 if (desc
->inputAttachmentCount
> 0) {
584 subpass
->input_attachments
= p
;
585 p
+= desc
->inputAttachmentCount
;
587 for (uint32_t j
= 0; j
< desc
->inputAttachmentCount
; j
++) {
588 const VkAttachmentReferenceStencilLayoutKHR
*stencil_attachment
=
589 vk_find_struct_const(desc
->pInputAttachments
[j
].pNext
,
590 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR
);
592 subpass
->input_attachments
[j
] = (struct radv_subpass_attachment
) {
593 .attachment
= desc
->pInputAttachments
[j
].attachment
,
594 .layout
= desc
->pInputAttachments
[j
].layout
,
595 .stencil_layout
= (stencil_attachment
?
596 stencil_attachment
->stencilLayout
:
597 desc
->pInputAttachments
[j
].layout
),
602 if (desc
->colorAttachmentCount
> 0) {
603 subpass
->color_attachments
= p
;
604 p
+= desc
->colorAttachmentCount
;
606 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
607 subpass
->color_attachments
[j
] = (struct radv_subpass_attachment
) {
608 .attachment
= desc
->pColorAttachments
[j
].attachment
,
609 .layout
= desc
->pColorAttachments
[j
].layout
,
614 if (desc
->pResolveAttachments
) {
615 subpass
->resolve_attachments
= p
;
616 p
+= desc
->colorAttachmentCount
;
618 for (uint32_t j
= 0; j
< desc
->colorAttachmentCount
; j
++) {
619 subpass
->resolve_attachments
[j
] = (struct radv_subpass_attachment
) {
620 .attachment
= desc
->pResolveAttachments
[j
].attachment
,
621 .layout
= desc
->pResolveAttachments
[j
].layout
,
626 if (desc
->pDepthStencilAttachment
) {
627 subpass
->depth_stencil_attachment
= p
++;
629 const VkAttachmentReferenceStencilLayoutKHR
*stencil_attachment
=
630 vk_find_struct_const(desc
->pDepthStencilAttachment
->pNext
,
631 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR
);
633 *subpass
->depth_stencil_attachment
= (struct radv_subpass_attachment
) {
634 .attachment
= desc
->pDepthStencilAttachment
->attachment
,
635 .layout
= desc
->pDepthStencilAttachment
->layout
,
636 .stencil_layout
= (stencil_attachment
?
637 stencil_attachment
->stencilLayout
:
638 desc
->pDepthStencilAttachment
->layout
),
642 const VkSubpassDescriptionDepthStencilResolve
*ds_resolve
=
643 vk_find_struct_const(desc
->pNext
,
644 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE
);
646 if (ds_resolve
&& ds_resolve
->pDepthStencilResolveAttachment
) {
647 subpass
->ds_resolve_attachment
= p
++;
649 const VkAttachmentReferenceStencilLayoutKHR
*stencil_resolve_attachment
=
650 vk_find_struct_const(ds_resolve
->pDepthStencilResolveAttachment
->pNext
,
651 ATTACHMENT_REFERENCE_STENCIL_LAYOUT_KHR
);
653 *subpass
->ds_resolve_attachment
= (struct radv_subpass_attachment
) {
654 .attachment
= ds_resolve
->pDepthStencilResolveAttachment
->attachment
,
655 .layout
= ds_resolve
->pDepthStencilResolveAttachment
->layout
,
656 .stencil_layout
= (stencil_resolve_attachment
?
657 stencil_resolve_attachment
->stencilLayout
:
658 ds_resolve
->pDepthStencilResolveAttachment
->layout
),
661 subpass
->depth_resolve_mode
= ds_resolve
->depthResolveMode
;
662 subpass
->stencil_resolve_mode
= ds_resolve
->stencilResolveMode
;
666 bool has_ingoing_dep
= false;
667 bool has_outgoing_dep
= false;
669 for (unsigned i
= 0; i
< pCreateInfo
->dependencyCount
; ++i
) {
670 radv_render_pass_add_subpass_dep(pass
,
671 &pCreateInfo
->pDependencies
[i
]);
673 /* Determine if the subpass has explicit dependencies from/to
674 * VK_SUBPASS_EXTERNAL.
676 if (pCreateInfo
->pDependencies
[i
].srcSubpass
== VK_SUBPASS_EXTERNAL
)
677 has_ingoing_dep
= true;
678 if (pCreateInfo
->pDependencies
[i
].dstSubpass
== VK_SUBPASS_EXTERNAL
)
679 has_outgoing_dep
= true;
682 radv_render_pass_add_implicit_deps(pass
,
683 has_ingoing_dep
, has_outgoing_dep
);
685 radv_render_pass_compile(pass
);
687 *pRenderPass
= radv_render_pass_to_handle(pass
);
692 void radv_DestroyRenderPass(
695 const VkAllocationCallbacks
* pAllocator
)
697 RADV_FROM_HANDLE(radv_device
, device
, _device
);
698 RADV_FROM_HANDLE(radv_render_pass
, pass
, _pass
);
703 radv_destroy_render_pass(device
, pAllocator
, pass
);
706 void radv_GetRenderAreaGranularity(
708 VkRenderPass renderPass
,
709 VkExtent2D
* pGranularity
)
711 pGranularity
->width
= 1;
712 pGranularity
->height
= 1;