1/* 2 * Copyright © 2020 Valve 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 "vk_render_pass.h" 25 26#include "vk_alloc.h" 27#include "vk_command_buffer.h" 28#include "vk_common_entrypoints.h" 29#include "vk_device.h" 30#include "vk_format.h" 31#include "vk_framebuffer.h" 32#include "vk_image.h" 33#include "vk_util.h" 34 35#include "util/log.h" 36 37static void 38translate_references(VkAttachmentReference2 **reference_ptr, 39 uint32_t reference_count, 40 const VkAttachmentReference *reference, 41 const VkRenderPassCreateInfo *pass_info, 42 bool is_input_attachment) 43{ 44 VkAttachmentReference2 *reference2 = *reference_ptr; 45 *reference_ptr += reference_count; 46 for (uint32_t i = 0; i < reference_count; i++) { 47 reference2[i] = (VkAttachmentReference2) { 48 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 49 .pNext = NULL, 50 .attachment = reference[i].attachment, 51 .layout = reference[i].layout, 52 }; 53 54 if (is_input_attachment && 55 reference2[i].attachment != VK_ATTACHMENT_UNUSED) { 56 assert(reference2[i].attachment < pass_info->attachmentCount); 57 const VkAttachmentDescription *att = 58 &pass_info->pAttachments[reference2[i].attachment]; 59 reference2[i].aspectMask = vk_format_aspects(att->format); 60 } 61 } 62} 63 64VKAPI_ATTR VkResult VKAPI_CALL 65vk_common_CreateRenderPass(VkDevice _device, 66 const VkRenderPassCreateInfo *pCreateInfo, 67 const VkAllocationCallbacks *pAllocator, 68 VkRenderPass *pRenderPass) 69{ 70 VK_FROM_HANDLE(vk_device, device, _device); 71 72 uint32_t reference_count = 0; 73 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 74 reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount; 75 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount; 76 if (pCreateInfo->pSubpasses[i].pResolveAttachments) 77 reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount; 78 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) 79 reference_count += 1; 80 } 81 82 VK_MULTIALLOC(ma); 83 VK_MULTIALLOC_DECL(&ma, VkRenderPassCreateInfo2, create_info, 1); 84 VK_MULTIALLOC_DECL(&ma, VkSubpassDescription2, subpasses, 85 pCreateInfo->subpassCount); 86 VK_MULTIALLOC_DECL(&ma, VkAttachmentDescription2, attachments, 87 pCreateInfo->attachmentCount); 88 VK_MULTIALLOC_DECL(&ma, VkSubpassDependency2, dependencies, 89 pCreateInfo->dependencyCount); 90 VK_MULTIALLOC_DECL(&ma, VkAttachmentReference2, references, 91 reference_count); 92 if (!vk_multialloc_alloc2(&ma, &device->alloc, pAllocator, 93 VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) 94 return VK_ERROR_OUT_OF_HOST_MEMORY; 95 96 VkAttachmentReference2 *reference_ptr = references; 97 98 const VkRenderPassMultiviewCreateInfo *multiview_info = NULL; 99 const VkRenderPassInputAttachmentAspectCreateInfo *aspect_info = NULL; 100 vk_foreach_struct_const(ext, pCreateInfo->pNext) { 101 switch (ext->sType) { 102 case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO: 103 aspect_info = (const VkRenderPassInputAttachmentAspectCreateInfo *)ext; 104 /* We don't care about this information */ 105 break; 106 107 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: 108 multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext; 109 break; 110 111 default: 112 mesa_logd("%s: ignored VkStructureType %u\n", __func__, ext->sType); 113 break; 114 } 115 } 116 117 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 118 attachments[i] = (VkAttachmentDescription2) { 119 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 120 .pNext = NULL, 121 .flags = pCreateInfo->pAttachments[i].flags, 122 .format = pCreateInfo->pAttachments[i].format, 123 .samples = pCreateInfo->pAttachments[i].samples, 124 .loadOp = pCreateInfo->pAttachments[i].loadOp, 125 .storeOp = pCreateInfo->pAttachments[i].storeOp, 126 .stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp, 127 .stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp, 128 .initialLayout = pCreateInfo->pAttachments[i].initialLayout, 129 .finalLayout = pCreateInfo->pAttachments[i].finalLayout, 130 }; 131 } 132 133 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 134 subpasses[i] = (VkSubpassDescription2) { 135 .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, 136 .pNext = NULL, 137 .flags = pCreateInfo->pSubpasses[i].flags, 138 .pipelineBindPoint = pCreateInfo->pSubpasses[i].pipelineBindPoint, 139 .viewMask = 0, 140 .inputAttachmentCount = pCreateInfo->pSubpasses[i].inputAttachmentCount, 141 .colorAttachmentCount = pCreateInfo->pSubpasses[i].colorAttachmentCount, 142 .preserveAttachmentCount = pCreateInfo->pSubpasses[i].preserveAttachmentCount, 143 .pPreserveAttachments = pCreateInfo->pSubpasses[i].pPreserveAttachments, 144 }; 145 146 if (multiview_info && multiview_info->subpassCount) { 147 assert(multiview_info->subpassCount == pCreateInfo->subpassCount); 148 subpasses[i].viewMask = multiview_info->pViewMasks[i]; 149 } 150 151 subpasses[i].pInputAttachments = reference_ptr; 152 translate_references(&reference_ptr, 153 subpasses[i].inputAttachmentCount, 154 pCreateInfo->pSubpasses[i].pInputAttachments, 155 pCreateInfo, true); 156 subpasses[i].pColorAttachments = reference_ptr; 157 translate_references(&reference_ptr, 158 subpasses[i].colorAttachmentCount, 159 pCreateInfo->pSubpasses[i].pColorAttachments, 160 pCreateInfo, false); 161 subpasses[i].pResolveAttachments = NULL; 162 if (pCreateInfo->pSubpasses[i].pResolveAttachments) { 163 subpasses[i].pResolveAttachments = reference_ptr; 164 translate_references(&reference_ptr, 165 subpasses[i].colorAttachmentCount, 166 pCreateInfo->pSubpasses[i].pResolveAttachments, 167 pCreateInfo, false); 168 } 169 subpasses[i].pDepthStencilAttachment = NULL; 170 if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) { 171 subpasses[i].pDepthStencilAttachment = reference_ptr; 172 translate_references(&reference_ptr, 1, 173 pCreateInfo->pSubpasses[i].pDepthStencilAttachment, 174 pCreateInfo, false); 175 } 176 } 177 178 assert(reference_ptr == references + reference_count); 179 180 if (aspect_info != NULL) { 181 for (uint32_t i = 0; i < aspect_info->aspectReferenceCount; i++) { 182 const VkInputAttachmentAspectReference *ref = 183 &aspect_info->pAspectReferences[i]; 184 185 assert(ref->subpass < pCreateInfo->subpassCount); 186 VkSubpassDescription2 *subpass = &subpasses[ref->subpass]; 187 188 assert(ref->inputAttachmentIndex < subpass->inputAttachmentCount); 189 VkAttachmentReference2 *att = (VkAttachmentReference2 *) 190 &subpass->pInputAttachments[ref->inputAttachmentIndex]; 191 192 att->aspectMask = ref->aspectMask; 193 } 194 } 195 196 for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) { 197 dependencies[i] = (VkSubpassDependency2) { 198 .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, 199 .pNext = NULL, 200 .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass, 201 .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass, 202 .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask, 203 .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask, 204 .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask, 205 .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask, 206 .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags, 207 .viewOffset = 0, 208 }; 209 210 if (multiview_info && multiview_info->dependencyCount) { 211 assert(multiview_info->dependencyCount == pCreateInfo->dependencyCount); 212 dependencies[i].viewOffset = multiview_info->pViewOffsets[i]; 213 } 214 } 215 216 *create_info = (VkRenderPassCreateInfo2) { 217 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, 218 .pNext = pCreateInfo->pNext, 219 .flags = pCreateInfo->flags, 220 .attachmentCount = pCreateInfo->attachmentCount, 221 .pAttachments = attachments, 222 .subpassCount = pCreateInfo->subpassCount, 223 .pSubpasses = subpasses, 224 .dependencyCount = pCreateInfo->dependencyCount, 225 .pDependencies = dependencies, 226 }; 227 228 if (multiview_info && multiview_info->correlationMaskCount > 0) { 229 create_info->correlatedViewMaskCount = multiview_info->correlationMaskCount; 230 create_info->pCorrelatedViewMasks = multiview_info->pCorrelationMasks; 231 } 232 233 VkResult result = 234 device->dispatch_table.CreateRenderPass2(_device, create_info, 235 pAllocator, pRenderPass); 236 237 vk_free2(&device->alloc, pAllocator, create_info); 238 239 return result; 240} 241 242VKAPI_ATTR void VKAPI_CALL 243vk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer, 244 const VkRenderPassBeginInfo* pRenderPassBegin, 245 VkSubpassContents contents) 246{ 247 /* We don't have a vk_command_buffer object but we can assume, since we're 248 * using common dispatch, that it's a vk_object of some sort. 249 */ 250 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 251 252 VkSubpassBeginInfo info = { 253 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, 254 .contents = contents, 255 }; 256 257 disp->device->dispatch_table.CmdBeginRenderPass2(commandBuffer, 258 pRenderPassBegin, &info); 259} 260 261VKAPI_ATTR void VKAPI_CALL 262vk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer) 263{ 264 /* We don't have a vk_command_buffer object but we can assume, since we're 265 * using common dispatch, that it's a vk_object of some sort. 266 */ 267 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 268 269 VkSubpassEndInfo info = { 270 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, 271 }; 272 273 disp->device->dispatch_table.CmdEndRenderPass2(commandBuffer, &info); 274} 275 276VKAPI_ATTR void VKAPI_CALL 277vk_common_CmdNextSubpass(VkCommandBuffer commandBuffer, 278 VkSubpassContents contents) 279{ 280 /* We don't have a vk_command_buffer object but we can assume, since we're 281 * using common dispatch, that it's a vk_object of some sort. 282 */ 283 struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 284 285 VkSubpassBeginInfo begin_info = { 286 .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, 287 .contents = contents, 288 }; 289 290 VkSubpassEndInfo end_info = { 291 .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, 292 }; 293 294 disp->device->dispatch_table.CmdNextSubpass2(commandBuffer, &begin_info, 295 &end_info); 296} 297 298static unsigned 299num_subpass_attachments2(const VkSubpassDescription2 *desc) 300{ 301 bool has_depth_stencil_attachment = 302 desc->pDepthStencilAttachment != NULL && 303 desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED; 304 305 const VkSubpassDescriptionDepthStencilResolve *ds_resolve = 306 vk_find_struct_const(desc->pNext, 307 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE); 308 309 bool has_depth_stencil_resolve_attachment = 310 ds_resolve != NULL && ds_resolve->pDepthStencilResolveAttachment && 311 ds_resolve->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED; 312 313 const VkFragmentShadingRateAttachmentInfoKHR *fsr_att_info = 314 vk_find_struct_const(desc->pNext, 315 FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); 316 317 bool has_fragment_shading_rate_attachment = 318 fsr_att_info && fsr_att_info->pFragmentShadingRateAttachment && 319 fsr_att_info->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED; 320 321 return desc->inputAttachmentCount + 322 desc->colorAttachmentCount + 323 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 324 has_depth_stencil_attachment + 325 has_depth_stencil_resolve_attachment + 326 has_fragment_shading_rate_attachment; 327} 328 329static void 330vk_render_pass_attachment_init(struct vk_render_pass_attachment *att, 331 const VkAttachmentDescription2 *desc) 332{ 333 *att = (struct vk_render_pass_attachment) { 334 .format = desc->format, 335 .aspects = vk_format_aspects(desc->format), 336 .samples = desc->samples, 337 .view_mask = 0, 338 .load_op = desc->loadOp, 339 .store_op = desc->storeOp, 340 .stencil_load_op = desc->stencilLoadOp, 341 .stencil_store_op = desc->stencilStoreOp, 342 .initial_layout = desc->initialLayout, 343 .final_layout = desc->finalLayout, 344 .initial_stencil_layout = vk_att_desc_stencil_layout(desc, false), 345 .final_stencil_layout = vk_att_desc_stencil_layout(desc, true), 346 }; 347} 348 349static void 350vk_subpass_attachment_init(struct vk_subpass_attachment *att, 351 struct vk_render_pass *pass, 352 uint32_t subpass_idx, 353 const VkAttachmentReference2 *ref, 354 const VkAttachmentDescription2 *attachments, 355 VkImageUsageFlagBits usage) 356{ 357 if (ref->attachment >= pass->attachment_count) { 358 assert(ref->attachment == VK_ATTACHMENT_UNUSED); 359 *att = (struct vk_subpass_attachment) { 360 .attachment = VK_ATTACHMENT_UNUSED, 361 }; 362 return; 363 } 364 365 struct vk_render_pass_attachment *pass_att = 366 &pass->attachments[ref->attachment]; 367 368 *att = (struct vk_subpass_attachment) { 369 .attachment = ref->attachment, 370 .aspects = vk_format_aspects(pass_att->format), 371 .usage = usage, 372 .layout = ref->layout, 373 .stencil_layout = vk_att_ref_stencil_layout(ref, attachments), 374 }; 375 376 switch (usage) { 377 case VK_IMAGE_USAGE_TRANSFER_DST_BIT: 378 break; /* No special aspect requirements */ 379 380 case VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT: 381 /* From the Vulkan 1.2.184 spec: 382 * 383 * "aspectMask is ignored when this structure is used to describe 384 * anything other than an input attachment reference." 385 */ 386 assert(!(ref->aspectMask & ~att->aspects)); 387 att->aspects = ref->aspectMask; 388 break; 389 390 case VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT: 391 case VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR: 392 assert(att->aspects == VK_IMAGE_ASPECT_COLOR_BIT); 393 break; 394 395 case VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT: 396 assert(!(att->aspects & ~(VK_IMAGE_ASPECT_DEPTH_BIT | 397 VK_IMAGE_ASPECT_STENCIL_BIT))); 398 break; 399 400 default: 401 unreachable("Invalid subpass attachment usage"); 402 } 403} 404 405static void 406vk_subpass_attachment_link_resolve(struct vk_subpass_attachment *att, 407 struct vk_subpass_attachment *resolve, 408 const VkRenderPassCreateInfo2 *info) 409{ 410 if (resolve->attachment == VK_ATTACHMENT_UNUSED) 411 return; 412 413 assert(att->attachment != VK_ATTACHMENT_UNUSED); 414 att->resolve = resolve; 415} 416 417VKAPI_ATTR VkResult VKAPI_CALL 418vk_common_CreateRenderPass2(VkDevice _device, 419 const VkRenderPassCreateInfo2 *pCreateInfo, 420 const VkAllocationCallbacks *pAllocator, 421 VkRenderPass *pRenderPass) 422{ 423 VK_FROM_HANDLE(vk_device, device, _device); 424 425 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2); 426 427 VK_MULTIALLOC(ma); 428 VK_MULTIALLOC_DECL(&ma, struct vk_render_pass, pass, 1); 429 VK_MULTIALLOC_DECL(&ma, struct vk_render_pass_attachment, attachments, 430 pCreateInfo->attachmentCount); 431 VK_MULTIALLOC_DECL(&ma, struct vk_subpass, subpasses, 432 pCreateInfo->subpassCount); 433 VK_MULTIALLOC_DECL(&ma, struct vk_subpass_dependency, dependencies, 434 pCreateInfo->dependencyCount); 435 436 uint32_t subpass_attachment_count = 0; 437 uint32_t subpass_color_attachment_count = 0; 438 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 439 subpass_attachment_count += 440 num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); 441 subpass_color_attachment_count += 442 pCreateInfo->pSubpasses[i].colorAttachmentCount; 443 } 444 VK_MULTIALLOC_DECL(&ma, struct vk_subpass_attachment, subpass_attachments, 445 subpass_attachment_count); 446 VK_MULTIALLOC_DECL(&ma, VkFormat, subpass_color_formats, 447 subpass_color_attachment_count); 448 VK_MULTIALLOC_DECL(&ma, VkSampleCountFlagBits, subpass_color_samples, 449 subpass_color_attachment_count); 450 451 if (!vk_object_multizalloc(device, &ma, pAllocator, 452 VK_OBJECT_TYPE_RENDER_PASS)) 453 return VK_ERROR_OUT_OF_HOST_MEMORY; 454 455 pass->attachment_count = pCreateInfo->attachmentCount; 456 pass->attachments = attachments; 457 pass->subpass_count = pCreateInfo->subpassCount; 458 pass->subpasses = subpasses; 459 pass->dependency_count = pCreateInfo->dependencyCount; 460 pass->dependencies = dependencies; 461 462 for (uint32_t a = 0; a < pCreateInfo->attachmentCount; a++) { 463 vk_render_pass_attachment_init(&pass->attachments[a], 464 &pCreateInfo->pAttachments[a]); 465 } 466 467 struct vk_subpass_attachment *next_subpass_attachment = subpass_attachments; 468 VkFormat *next_subpass_color_format = subpass_color_formats; 469 VkSampleCountFlagBits *next_subpass_color_samples = subpass_color_samples; 470 for (uint32_t s = 0; s < pCreateInfo->subpassCount; s++) { 471 const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[s]; 472 struct vk_subpass *subpass = &pass->subpasses[s]; 473 const VkMultisampledRenderToSingleSampledInfoEXT *mrtss = 474 vk_find_struct_const(desc->pNext, MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT); 475 if (mrtss && !mrtss->multisampledRenderToSingleSampledEnable) 476 mrtss = NULL; 477 478 subpass->attachment_count = num_subpass_attachments2(desc); 479 subpass->attachments = next_subpass_attachment; 480 481 /* From the Vulkan 1.3.204 spec: 482 * 483 * VUID-VkRenderPassCreateInfo2-viewMask-03058 484 * 485 * "The VkSubpassDescription2::viewMask member of all elements of 486 * pSubpasses must either all be 0, or all not be 0" 487 */ 488 if (desc->viewMask) 489 pass->is_multiview = true; 490 assert(pass->is_multiview == (desc->viewMask != 0)); 491 492 /* For all view masks in the vk_render_pass data structure, we use a 493 * mask of 1 for non-multiview instead of a mask of 0. 494 */ 495 subpass->view_mask = desc->viewMask ? desc->viewMask : 1; 496 pass->view_mask |= subpass->view_mask; 497 498 subpass->input_count = desc->inputAttachmentCount; 499 if (desc->inputAttachmentCount > 0) { 500 subpass->input_attachments = next_subpass_attachment; 501 next_subpass_attachment += desc->inputAttachmentCount; 502 503 for (uint32_t a = 0; a < desc->inputAttachmentCount; a++) { 504 vk_subpass_attachment_init(&subpass->input_attachments[a], 505 pass, s, 506 &desc->pInputAttachments[a], 507 pCreateInfo->pAttachments, 508 VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT); 509 } 510 } 511 512 subpass->color_count = desc->colorAttachmentCount; 513 if (desc->colorAttachmentCount > 0) { 514 subpass->color_attachments = next_subpass_attachment; 515 next_subpass_attachment += desc->colorAttachmentCount; 516 517 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) { 518 vk_subpass_attachment_init(&subpass->color_attachments[a], 519 pass, s, 520 &desc->pColorAttachments[a], 521 pCreateInfo->pAttachments, 522 VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT); 523 } 524 } 525 526 if (desc->pResolveAttachments) { 527 subpass->color_resolve_count = desc->colorAttachmentCount; 528 subpass->color_resolve_attachments = next_subpass_attachment; 529 next_subpass_attachment += desc->colorAttachmentCount; 530 531 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) { 532 vk_subpass_attachment_init(&subpass->color_resolve_attachments[a], 533 pass, s, 534 &desc->pResolveAttachments[a], 535 pCreateInfo->pAttachments, 536 VK_IMAGE_USAGE_TRANSFER_DST_BIT); 537 vk_subpass_attachment_link_resolve(&subpass->color_attachments[a], 538 &subpass->color_resolve_attachments[a], 539 pCreateInfo); 540 } 541 } 542 543 if (desc->pDepthStencilAttachment && 544 desc->pDepthStencilAttachment->attachment != VK_ATTACHMENT_UNUSED) { 545 subpass->depth_stencil_attachment = next_subpass_attachment++; 546 547 vk_subpass_attachment_init(subpass->depth_stencil_attachment, 548 pass, s, 549 desc->pDepthStencilAttachment, 550 pCreateInfo->pAttachments, 551 VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT); 552 } 553 554 const VkSubpassDescriptionDepthStencilResolve *ds_resolve = 555 vk_find_struct_const(desc->pNext, 556 SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE); 557 558 if (ds_resolve) { 559 if (ds_resolve->pDepthStencilResolveAttachment && 560 ds_resolve->pDepthStencilResolveAttachment->attachment != VK_ATTACHMENT_UNUSED) { 561 subpass->depth_stencil_resolve_attachment = next_subpass_attachment++; 562 563 vk_subpass_attachment_init(subpass->depth_stencil_resolve_attachment, 564 pass, s, 565 ds_resolve->pDepthStencilResolveAttachment, 566 pCreateInfo->pAttachments, 567 VK_IMAGE_USAGE_TRANSFER_DST_BIT); 568 vk_subpass_attachment_link_resolve(subpass->depth_stencil_attachment, 569 subpass->depth_stencil_resolve_attachment, 570 pCreateInfo); 571 } 572 if (subpass->depth_stencil_resolve_attachment || mrtss) { 573 /* From the Vulkan 1.3.204 spec: 574 * 575 * VUID-VkSubpassDescriptionDepthStencilResolve-pDepthStencilResolveAttachment-03178 576 * 577 * "If pDepthStencilResolveAttachment is not NULL and does not 578 * have the value VK_ATTACHMENT_UNUSED, depthResolveMode and 579 * stencilResolveMode must not both be VK_RESOLVE_MODE_NONE" 580 */ 581 assert(ds_resolve->depthResolveMode != VK_RESOLVE_MODE_NONE || 582 ds_resolve->stencilResolveMode != VK_RESOLVE_MODE_NONE); 583 584 subpass->depth_resolve_mode = ds_resolve->depthResolveMode; 585 subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode; 586 } 587 } 588 589 const VkFragmentShadingRateAttachmentInfoKHR *fsr_att_info = 590 vk_find_struct_const(desc->pNext, 591 FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); 592 593 if (fsr_att_info && fsr_att_info->pFragmentShadingRateAttachment && 594 fsr_att_info->pFragmentShadingRateAttachment->attachment != VK_ATTACHMENT_UNUSED) { 595 subpass->fragment_shading_rate_attachment = next_subpass_attachment++; 596 vk_subpass_attachment_init(subpass->fragment_shading_rate_attachment, 597 pass, s, 598 fsr_att_info->pFragmentShadingRateAttachment, 599 pCreateInfo->pAttachments, 600 VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR); 601 subpass->fragment_shading_rate_attachment_texel_size = 602 fsr_att_info->shadingRateAttachmentTexelSize; 603 } 604 605 /* Figure out any self-dependencies */ 606 assert(desc->colorAttachmentCount <= 32); 607 uint32_t color_self_deps = 0; 608 bool has_depth_self_dep = false; 609 bool has_stencil_self_dep = false; 610 for (uint32_t a = 0; a < desc->inputAttachmentCount; a++) { 611 if (desc->pInputAttachments[a].attachment == VK_ATTACHMENT_UNUSED) 612 continue; 613 614 for (uint32_t c = 0; c < desc->colorAttachmentCount; c++) { 615 if (desc->pColorAttachments[c].attachment == 616 desc->pInputAttachments[a].attachment) { 617 subpass->input_attachments[a].layout = 618 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 619 subpass->color_attachments[c].layout = 620 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 621 color_self_deps |= (1u << c); 622 } 623 } 624 625 if (desc->pDepthStencilAttachment != NULL && 626 desc->pDepthStencilAttachment->attachment == 627 desc->pInputAttachments[a].attachment) { 628 VkImageAspectFlags aspects = 629 subpass->input_attachments[a].aspects; 630 if (aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 631 subpass->input_attachments[a].layout = 632 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 633 subpass->depth_stencil_attachment->layout = 634 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 635 has_depth_self_dep = true; 636 } 637 if (aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 638 subpass->input_attachments[a].stencil_layout = 639 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 640 subpass->depth_stencil_attachment->stencil_layout = 641 VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA; 642 has_stencil_self_dep = true; 643 } 644 } 645 } 646 647 VkFormat *color_formats = NULL; 648 VkSampleCountFlagBits *color_samples = NULL; 649 VkSampleCountFlagBits samples = 0; 650 if (desc->colorAttachmentCount > 0) { 651 color_formats = next_subpass_color_format; 652 color_samples = next_subpass_color_samples; 653 for (uint32_t a = 0; a < desc->colorAttachmentCount; a++) { 654 const VkAttachmentReference2 *ref = &desc->pColorAttachments[a]; 655 if (ref->attachment >= pCreateInfo->attachmentCount) { 656 color_formats[a] = VK_FORMAT_UNDEFINED; 657 color_samples[a] = VK_SAMPLE_COUNT_1_BIT; 658 } else { 659 const VkAttachmentDescription2 *att = 660 &pCreateInfo->pAttachments[ref->attachment]; 661 662 color_formats[a] = att->format; 663 color_samples[a] = att->samples; 664 665 samples |= att->samples; 666 } 667 } 668 next_subpass_color_format += desc->colorAttachmentCount; 669 next_subpass_color_samples += desc->colorAttachmentCount; 670 } 671 672 VkFormat depth_format = VK_FORMAT_UNDEFINED; 673 VkFormat stencil_format = VK_FORMAT_UNDEFINED; 674 VkSampleCountFlagBits depth_stencil_samples = VK_SAMPLE_COUNT_1_BIT; 675 if (desc->pDepthStencilAttachment != NULL) { 676 const VkAttachmentReference2 *ref = desc->pDepthStencilAttachment; 677 if (ref->attachment < pCreateInfo->attachmentCount) { 678 const VkAttachmentDescription2 *att = 679 &pCreateInfo->pAttachments[ref->attachment]; 680 681 if (vk_format_has_depth(att->format)) 682 depth_format = att->format; 683 if (vk_format_has_stencil(att->format)) 684 stencil_format = att->format; 685 686 depth_stencil_samples = att->samples; 687 688 samples |= att->samples; 689 } 690 } 691 692 subpass->self_dep_info = (VkRenderingSelfDependencyInfoMESA) { 693 .sType = VK_STRUCTURE_TYPE_RENDERING_SELF_DEPENDENCY_INFO_MESA, 694 .colorSelfDependencies = color_self_deps, 695 .depthSelfDependency = has_depth_self_dep, 696 .stencilSelfDependency = has_stencil_self_dep, 697 }; 698 699 subpass->sample_count_info_amd = (VkAttachmentSampleCountInfoAMD) { 700 .sType = VK_STRUCTURE_TYPE_ATTACHMENT_SAMPLE_COUNT_INFO_AMD, 701 .pNext = &subpass->self_dep_info, 702 .colorAttachmentCount = desc->colorAttachmentCount, 703 .pColorAttachmentSamples = color_samples, 704 .depthStencilAttachmentSamples = depth_stencil_samples, 705 }; 706 707 subpass->pipeline_info = (VkPipelineRenderingCreateInfo) { 708 .sType = VK_STRUCTURE_TYPE_PIPELINE_RENDERING_CREATE_INFO, 709 .pNext = &subpass->sample_count_info_amd, 710 .viewMask = desc->viewMask, 711 .colorAttachmentCount = desc->colorAttachmentCount, 712 .pColorAttachmentFormats = color_formats, 713 .depthAttachmentFormat = depth_format, 714 .stencilAttachmentFormat = stencil_format, 715 }; 716 717 subpass->inheritance_info = (VkCommandBufferInheritanceRenderingInfo) { 718 .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_INHERITANCE_RENDERING_INFO, 719 .pNext = &subpass->sample_count_info_amd, 720 /* If we're inheriting, the contents are clearly in secondaries */ 721 .flags = VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT, 722 .viewMask = desc->viewMask, 723 .colorAttachmentCount = desc->colorAttachmentCount, 724 .pColorAttachmentFormats = color_formats, 725 .depthAttachmentFormat = depth_format, 726 .stencilAttachmentFormat = stencil_format, 727 .rasterizationSamples = samples, 728 }; 729 730 if (mrtss) { 731 assert(mrtss->multisampledRenderToSingleSampledEnable); 732 subpass->mrtss = (VkMultisampledRenderToSingleSampledInfoEXT) { 733 .sType = VK_STRUCTURE_TYPE_MULTISAMPLED_RENDER_TO_SINGLE_SAMPLED_INFO_EXT, 734 .multisampledRenderToSingleSampledEnable = VK_TRUE, 735 .rasterizationSamples = mrtss->rasterizationSamples, 736 }; 737 subpass->self_dep_info.pNext = &subpass->mrtss; 738 } 739 } 740 assert(next_subpass_attachment == 741 subpass_attachments + subpass_attachment_count); 742 assert(next_subpass_color_format == 743 subpass_color_formats + subpass_color_attachment_count); 744 assert(next_subpass_color_samples == 745 subpass_color_samples + subpass_color_attachment_count); 746 747 /* Walk backwards over the subpasses to compute view masks and 748 * last_subpass masks for all attachments. 749 */ 750 for (uint32_t s = 0; s < pCreateInfo->subpassCount; s++) { 751 struct vk_subpass *subpass = 752 &pass->subpasses[(pCreateInfo->subpassCount - 1) - s]; 753 754 /* First, compute last_subpass for all the attachments */ 755 for (uint32_t a = 0; a < subpass->attachment_count; a++) { 756 struct vk_subpass_attachment *att = &subpass->attachments[a]; 757 if (att->attachment == VK_ATTACHMENT_UNUSED) 758 continue; 759 760 assert(att->attachment < pass->attachment_count); 761 const struct vk_render_pass_attachment *pass_att = 762 &pass->attachments[att->attachment]; 763 764 att->last_subpass = subpass->view_mask & ~pass_att->view_mask; 765 } 766 767 /* Then compute pass_att->view_mask. We do the two separately so that 768 * we end up with the right last_subpass even if the same attachment is 769 * used twice within a subpass. 770 */ 771 for (uint32_t a = 0; a < subpass->attachment_count; a++) { 772 const struct vk_subpass_attachment *att = &subpass->attachments[a]; 773 if (att->attachment == VK_ATTACHMENT_UNUSED) 774 continue; 775 776 assert(att->attachment < pass->attachment_count); 777 struct vk_render_pass_attachment *pass_att = 778 &pass->attachments[att->attachment]; 779 780 pass_att->view_mask |= subpass->view_mask; 781 } 782 } 783 784 pass->dependency_count = pCreateInfo->dependencyCount; 785 for (uint32_t d = 0; d < pCreateInfo->dependencyCount; d++) { 786 const VkSubpassDependency2 *dep = &pCreateInfo->pDependencies[d]; 787 788 pass->dependencies[d] = (struct vk_subpass_dependency) { 789 .flags = dep->dependencyFlags, 790 .src_subpass = dep->srcSubpass, 791 .dst_subpass = dep->dstSubpass, 792 .src_stage_mask = (VkPipelineStageFlags2)dep->srcStageMask, 793 .dst_stage_mask = (VkPipelineStageFlags2)dep->dstStageMask, 794 .src_access_mask = (VkAccessFlags2)dep->srcAccessMask, 795 .dst_access_mask = (VkAccessFlags2)dep->dstAccessMask, 796 .view_offset = dep->viewOffset, 797 }; 798 799 /* From the Vulkan 1.3.204 spec: 800 * 801 * "If a VkMemoryBarrier2 is included in the pNext chain, 802 * srcStageMask, dstStageMask, srcAccessMask, and dstAccessMask 803 * parameters are ignored. The synchronization and access scopes 804 * instead are defined by the parameters of VkMemoryBarrier2." 805 */ 806 const VkMemoryBarrier2 *barrier = 807 vk_find_struct_const(dep->pNext, MEMORY_BARRIER_2); 808 if (barrier != NULL) { 809 pass->dependencies[d].src_stage_mask = barrier->srcStageMask; 810 pass->dependencies[d].dst_stage_mask = barrier->dstStageMask; 811 pass->dependencies[d].src_access_mask = barrier->srcAccessMask; 812 pass->dependencies[d].dst_access_mask = barrier->dstAccessMask; 813 } 814 } 815 816 *pRenderPass = vk_render_pass_to_handle(pass); 817 818 return VK_SUCCESS; 819} 820 821const VkPipelineRenderingCreateInfo * 822vk_get_pipeline_rendering_create_info(const VkGraphicsPipelineCreateInfo *info) 823{ 824 VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass); 825 if (render_pass != NULL) { 826 assert(info->subpass < render_pass->subpass_count); 827 return &render_pass->subpasses[info->subpass].pipeline_info; 828 } 829 830 return vk_find_struct_const(info->pNext, PIPELINE_RENDERING_CREATE_INFO); 831} 832 833const VkAttachmentSampleCountInfoAMD * 834vk_get_pipeline_sample_count_info_amd(const VkGraphicsPipelineCreateInfo *info) 835{ 836 VK_FROM_HANDLE(vk_render_pass, render_pass, info->renderPass); 837 if (render_pass != NULL) { 838 assert(info->subpass < render_pass->subpass_count); 839 return &render_pass->subpasses[info->subpass].sample_count_info_amd; 840 } 841 842 return vk_find_struct_const(info->pNext, ATTACHMENT_SAMPLE_COUNT_INFO_AMD); 843} 844 845const VkCommandBufferInheritanceRenderingInfo * 846vk_get_command_buffer_inheritance_rendering_info( 847 VkCommandBufferLevel level, 848 const VkCommandBufferBeginInfo *pBeginInfo) 849{ 850 /* From the Vulkan 1.3.204 spec: 851 * 852 * "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a 853 * secondary command buffer is considered to be entirely inside a render 854 * pass. If this is a primary command buffer, then this bit is ignored." 855 * 856 * Since we're only concerned with the continue case here, we can ignore 857 * any primary command buffers. 858 */ 859 if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) 860 return NULL; 861 862 if (!(pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) 863 return NULL; 864 865 const VkCommandBufferInheritanceInfo *inheritance = 866 pBeginInfo->pInheritanceInfo; 867 868 /* From the Vulkan 1.3.204 spec: 869 * 870 * "If VkCommandBufferInheritanceInfo::renderPass is not VK_NULL_HANDLE, 871 * or VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT is not specified 872 * in VkCommandBufferBeginInfo::flags, parameters of this structure are 873 * ignored." 874 * 875 * If we have a render pass that wins, even if a 876 * VkCommandBufferInheritanceRenderingInfo struct is included in the pNext 877 * chain. 878 */ 879 VK_FROM_HANDLE(vk_render_pass, render_pass, inheritance->renderPass); 880 if (render_pass != NULL) { 881 assert(inheritance->subpass < render_pass->subpass_count); 882 return &render_pass->subpasses[inheritance->subpass].inheritance_info; 883 } 884 885 return vk_find_struct_const(inheritance->pNext, 886 COMMAND_BUFFER_INHERITANCE_RENDERING_INFO); 887} 888 889const VkRenderingInfo * 890vk_get_command_buffer_inheritance_as_rendering_resume( 891 VkCommandBufferLevel level, 892 const VkCommandBufferBeginInfo *pBeginInfo, 893 void *stack_data) 894{ 895 struct vk_gcbiarr_data *data = stack_data; 896 897 /* From the Vulkan 1.3.204 spec: 898 * 899 * "VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT specifies that a 900 * secondary command buffer is considered to be entirely inside a render 901 * pass. If this is a primary command buffer, then this bit is ignored." 902 * 903 * Since we're only concerned with the continue case here, we can ignore 904 * any primary command buffers. 905 */ 906 if (level == VK_COMMAND_BUFFER_LEVEL_PRIMARY) 907 return NULL; 908 909 if (!(pBeginInfo->flags & VK_COMMAND_BUFFER_USAGE_RENDER_PASS_CONTINUE_BIT)) 910 return NULL; 911 912 const VkCommandBufferInheritanceInfo *inheritance = 913 pBeginInfo->pInheritanceInfo; 914 915 VK_FROM_HANDLE(vk_render_pass, pass, inheritance->renderPass); 916 if (pass == NULL) 917 return NULL; 918 919 assert(inheritance->subpass < pass->subpass_count); 920 const struct vk_subpass *subpass = &pass->subpasses[inheritance->subpass]; 921 922 VK_FROM_HANDLE(vk_framebuffer, fb, inheritance->framebuffer); 923 if (fb == NULL || (fb->flags & VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT)) 924 return NULL; 925 926 data->rendering = (VkRenderingInfo) { 927 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 928 .flags = VK_RENDERING_RESUMING_BIT, 929 .renderArea = { 930 .offset = { 0, 0 }, 931 .extent = { fb->width, fb->height }, 932 }, 933 .layerCount = fb->layers, 934 .viewMask = pass->is_multiview ? subpass->view_mask : 0, 935 }; 936 937 VkRenderingAttachmentInfo *attachments = data->attachments; 938 939 for (unsigned i = 0; i < subpass->color_count; i++) { 940 const struct vk_subpass_attachment *sp_att = 941 &subpass->color_attachments[i]; 942 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) { 943 attachments[i] = (VkRenderingAttachmentInfo) { 944 .imageView = VK_NULL_HANDLE, 945 }; 946 continue; 947 } 948 949 assert(sp_att->attachment < pass->attachment_count); 950 attachments[i] = (VkRenderingAttachmentInfo) { 951 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 952 .imageView = fb->attachments[sp_att->attachment], 953 .imageLayout = sp_att->layout, 954 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 955 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 956 }; 957 } 958 data->rendering.colorAttachmentCount = subpass->color_count; 959 data->rendering.pColorAttachments = attachments; 960 attachments += subpass->color_count; 961 962 if (subpass->depth_stencil_attachment) { 963 const struct vk_subpass_attachment *sp_att = 964 subpass->depth_stencil_attachment; 965 assert(sp_att->attachment < pass->attachment_count); 966 967 VK_FROM_HANDLE(vk_image_view, iview, fb->attachments[sp_att->attachment]); 968 if (iview->image->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 969 *attachments = (VkRenderingAttachmentInfo) { 970 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 971 .imageView = vk_image_view_to_handle(iview), 972 .imageLayout = sp_att->layout, 973 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 974 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 975 }; 976 data->rendering.pDepthAttachment = attachments++; 977 } 978 979 if (iview->image->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 980 *attachments = (VkRenderingAttachmentInfo) { 981 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 982 .imageView = vk_image_view_to_handle(iview), 983 .imageLayout = sp_att->stencil_layout, 984 .loadOp = VK_ATTACHMENT_LOAD_OP_LOAD, 985 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 986 }; 987 data->rendering.pStencilAttachment = attachments++; 988 } 989 } 990 991 if (subpass->fragment_shading_rate_attachment) { 992 const struct vk_subpass_attachment *sp_att = 993 subpass->fragment_shading_rate_attachment; 994 assert(sp_att->attachment < pass->attachment_count); 995 996 data->fsr_att = (VkRenderingFragmentShadingRateAttachmentInfoKHR) { 997 .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, 998 .imageView = fb->attachments[sp_att->attachment], 999 .imageLayout = sp_att->layout, 1000 .shadingRateAttachmentTexelSize = 1001 subpass->fragment_shading_rate_attachment_texel_size, 1002 }; 1003 __vk_append_struct(&data->rendering, &data->fsr_att); 1004 } 1005 1006 /* Append this one last because it lives in the subpass and we don't want 1007 * to be changed by appending other structures later. 1008 */ 1009 __vk_append_struct(&data->rendering, (void *)&subpass->self_dep_info); 1010 1011 return &data->rendering; 1012} 1013 1014VKAPI_ATTR void VKAPI_CALL 1015vk_common_DestroyRenderPass(VkDevice _device, 1016 VkRenderPass renderPass, 1017 const VkAllocationCallbacks *pAllocator) 1018{ 1019 VK_FROM_HANDLE(vk_device, device, _device); 1020 VK_FROM_HANDLE(vk_render_pass, pass, renderPass); 1021 1022 if (!pass) 1023 return; 1024 1025 vk_object_free(device, pAllocator, pass); 1026} 1027 1028VKAPI_ATTR void VKAPI_CALL 1029vk_common_GetRenderAreaGranularity(VkDevice device, 1030 VkRenderPass renderPass, 1031 VkExtent2D *pGranularity) 1032{ 1033 *pGranularity = (VkExtent2D) { 1, 1 }; 1034} 1035 1036static VkRenderPassSampleLocationsBeginInfoEXT * 1037clone_rp_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc) 1038{ 1039 uint32_t sl_count = 0; 1040 1041 for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) { 1042 const VkAttachmentSampleLocationsEXT *att_sl_in = 1043 &loc->pAttachmentInitialSampleLocations[i]; 1044 sl_count += att_sl_in->sampleLocationsInfo.sampleLocationsCount; 1045 } 1046 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) { 1047 const VkSubpassSampleLocationsEXT *sp_sl_in = 1048 &loc->pPostSubpassSampleLocations[i]; 1049 sl_count += sp_sl_in->sampleLocationsInfo.sampleLocationsCount; 1050 } 1051 1052 VK_MULTIALLOC(ma); 1053 VK_MULTIALLOC_DECL(&ma, VkRenderPassSampleLocationsBeginInfoEXT, new_loc, 1); 1054 VK_MULTIALLOC_DECL(&ma, VkAttachmentSampleLocationsEXT, new_att_sl, 1055 loc->attachmentInitialSampleLocationsCount); 1056 VK_MULTIALLOC_DECL(&ma, VkSubpassSampleLocationsEXT, new_sp_sl, 1057 loc->postSubpassSampleLocationsCount); 1058 VK_MULTIALLOC_DECL(&ma, VkSampleLocationEXT, sl, sl_count); 1059 if (!vk_multialloc_alloc(&ma, vk_default_allocator(), 1060 VK_SYSTEM_ALLOCATION_SCOPE_OBJECT)) 1061 return NULL; 1062 1063 VkSampleLocationEXT *next_sl = sl; 1064 for (uint32_t i = 0; i < loc->attachmentInitialSampleLocationsCount; i++) { 1065 const VkAttachmentSampleLocationsEXT *att_sl_in = 1066 &loc->pAttachmentInitialSampleLocations[i]; 1067 const VkSampleLocationsInfoEXT *sli_in = &att_sl_in->sampleLocationsInfo; 1068 1069 typed_memcpy(next_sl, sli_in->pSampleLocations, 1070 sli_in->sampleLocationsCount); 1071 1072 new_att_sl[i] = (VkAttachmentSampleLocationsEXT) { 1073 .attachmentIndex = att_sl_in->attachmentIndex, 1074 .sampleLocationsInfo = { 1075 .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, 1076 .sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel, 1077 .sampleLocationGridSize = sli_in->sampleLocationGridSize, 1078 .sampleLocationsCount = sli_in->sampleLocationsCount, 1079 .pSampleLocations = next_sl, 1080 }, 1081 }; 1082 1083 next_sl += sli_in->sampleLocationsCount; 1084 } 1085 1086 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) { 1087 const VkSubpassSampleLocationsEXT *sp_sl_in = 1088 &loc->pPostSubpassSampleLocations[i]; 1089 const VkSampleLocationsInfoEXT *sli_in = &sp_sl_in->sampleLocationsInfo; 1090 1091 typed_memcpy(next_sl, sli_in->pSampleLocations, 1092 sli_in->sampleLocationsCount); 1093 1094 new_sp_sl[i] = (VkSubpassSampleLocationsEXT) { 1095 .subpassIndex = sp_sl_in->subpassIndex, 1096 .sampleLocationsInfo = { 1097 .sType = VK_STRUCTURE_TYPE_SAMPLE_LOCATIONS_INFO_EXT, 1098 .sampleLocationsPerPixel = sli_in->sampleLocationsPerPixel, 1099 .sampleLocationGridSize = sli_in->sampleLocationGridSize, 1100 .sampleLocationsCount = sli_in->sampleLocationsCount, 1101 .pSampleLocations = next_sl, 1102 }, 1103 }; 1104 1105 next_sl += sli_in->sampleLocationsCount; 1106 } 1107 1108 assert(next_sl == sl + sl_count); 1109 1110 *new_loc = (VkRenderPassSampleLocationsBeginInfoEXT) { 1111 .sType = VK_STRUCTURE_TYPE_RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT, 1112 .attachmentInitialSampleLocationsCount = loc->attachmentInitialSampleLocationsCount, 1113 .pAttachmentInitialSampleLocations = new_att_sl, 1114 .postSubpassSampleLocationsCount = loc->postSubpassSampleLocationsCount, 1115 .pPostSubpassSampleLocations = new_sp_sl, 1116 }; 1117 1118 return new_loc; 1119} 1120 1121static const VkSampleLocationsInfoEXT * 1122get_subpass_sample_locations(const VkRenderPassSampleLocationsBeginInfoEXT *loc, 1123 uint32_t subpass_idx) 1124{ 1125 for (uint32_t i = 0; i < loc->postSubpassSampleLocationsCount; i++) { 1126 if (loc->pPostSubpassSampleLocations[i].subpassIndex == subpass_idx) 1127 return &loc->pPostSubpassSampleLocations[i].sampleLocationsInfo; 1128 } 1129 1130 return NULL; 1131} 1132 1133static bool 1134vk_image_layout_supports_input_attachment(VkImageLayout layout) 1135{ 1136 switch (layout) { 1137 case VK_IMAGE_LAYOUT_GENERAL: 1138 case VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL: 1139 case VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL: 1140 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL: 1141 case VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL: 1142 case VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL: 1143 case VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL: 1144 case VK_IMAGE_LAYOUT_SHARED_PRESENT_KHR: 1145#ifdef __GNUC__ 1146#pragma GCC diagnostic push 1147#pragma GCC diagnostic ignored "-Wswitch" 1148#endif 1149 case VK_IMAGE_LAYOUT_SUBPASS_SELF_DEPENDENCY_MESA: 1150#ifdef __GNUC__ 1151#pragma GCC diagnostic pop 1152#endif 1153 return true; 1154 default: 1155 return false; 1156 } 1157} 1158 1159struct stage_access { 1160 VkPipelineStageFlagBits2 stages; 1161 VkAccessFlagBits2 access; 1162}; 1163 1164static bool 1165vk_image_layout_are_all_aspects_read_only(VkImageLayout layout, 1166 VkImageAspectFlags aspects) 1167{ 1168 u_foreach_bit(a, aspects) { 1169 VkImageAspectFlagBits aspect = 1u << a; 1170 if (!vk_image_layout_is_read_only(layout, aspect)) 1171 return false; 1172 } 1173 return true; 1174} 1175 1176static struct stage_access 1177stage_access_for_layout(VkImageLayout layout, VkImageAspectFlags aspects) 1178{ 1179 VkPipelineStageFlagBits2 stages = 0; 1180 VkAccessFlagBits2 access = 0; 1181 1182 if (vk_image_layout_supports_input_attachment(layout)) { 1183 stages |= VK_PIPELINE_STAGE_2_FRAGMENT_SHADER_BIT; 1184 access |= VK_ACCESS_2_INPUT_ATTACHMENT_READ_BIT; 1185 } 1186 1187 if (aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | VK_IMAGE_ASPECT_STENCIL_BIT)) { 1188 stages |= VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT | 1189 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; 1190 access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_READ_BIT; 1191 if (!vk_image_layout_are_all_aspects_read_only(layout, aspects)) { 1192 access |= VK_ACCESS_2_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 1193 1194 /* It might be a resolve attachment */ 1195 stages |= VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT; 1196 access |= VK_ACCESS_2_TRANSFER_WRITE_BIT; 1197 } 1198 } else { 1199 /* Color */ 1200 if (!vk_image_layout_are_all_aspects_read_only(layout, aspects)) { 1201 /* There are no read-only color attachments */ 1202 stages |= VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; 1203 access |= VK_ACCESS_2_COLOR_ATTACHMENT_READ_BIT | 1204 VK_ACCESS_2_COLOR_ATTACHMENT_WRITE_BIT; 1205 1206 /* It might be a resolve attachment */ 1207 stages |= VK_PIPELINE_STAGE_2_ALL_TRANSFER_BIT; 1208 access |= VK_ACCESS_2_TRANSFER_WRITE_BIT; 1209 } 1210 } 1211 1212 return (struct stage_access) { 1213 .stages = stages, 1214 .access = access, 1215 }; 1216} 1217 1218static void 1219transition_image_range(const struct vk_image_view *image_view, 1220 VkImageSubresourceRange range, 1221 VkImageLayout old_layout, 1222 VkImageLayout new_layout, 1223 VkImageLayout old_stencil_layout, 1224 VkImageLayout new_stencil_layout, 1225 const VkSampleLocationsInfoEXT *sample_locations, 1226 uint32_t *barrier_count, 1227 uint32_t max_barrier_count, 1228 VkImageMemoryBarrier2 *barriers) 1229{ 1230 VkImageAspectFlags aspects_left = range.aspectMask; 1231 while (aspects_left) { 1232 range.aspectMask = aspects_left; 1233 1234 /* If we have a depth/stencil image and one of the layouts doesn't match 1235 * between depth and stencil, we need two barriers. Restrict to depth 1236 * and we'll pick up stencil on the next iteration. 1237 */ 1238 if (range.aspectMask == (VK_IMAGE_ASPECT_DEPTH_BIT | 1239 VK_IMAGE_ASPECT_STENCIL_BIT) && 1240 (old_layout != old_stencil_layout || 1241 new_layout != new_stencil_layout)) 1242 range.aspectMask = VK_IMAGE_ASPECT_DEPTH_BIT; 1243 1244 if (range.aspectMask == VK_IMAGE_ASPECT_STENCIL_BIT) { 1245 /* We're down to a single aspect bit so this is going to be the last 1246 * iteration and it's fine to stomp the input variables here. 1247 */ 1248 old_layout = old_stencil_layout; 1249 new_layout = new_stencil_layout; 1250 } 1251 1252 if (new_layout != old_layout) { 1253 /* We could go about carefully calculating every possible way the 1254 * attachment may have been used in the render pass or we can break 1255 * out the big hammer and throw in any stage and access flags 1256 * possible for the given layouts. 1257 */ 1258 struct stage_access src_sa, dst_sa; 1259 src_sa = stage_access_for_layout(old_layout, range.aspectMask); 1260 dst_sa = stage_access_for_layout(new_layout, range.aspectMask); 1261 1262 assert(*barrier_count < max_barrier_count); 1263 barriers[(*barrier_count)++] = (VkImageMemoryBarrier2) { 1264 .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2, 1265 .pNext = sample_locations, 1266 .srcStageMask = src_sa.stages, 1267 .srcAccessMask = src_sa.access, 1268 .dstStageMask = dst_sa.stages, 1269 .dstAccessMask = dst_sa.access, 1270 .oldLayout = old_layout, 1271 .newLayout = new_layout, 1272 .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 1273 .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, 1274 .image = vk_image_to_handle(image_view->image), 1275 .subresourceRange = range, 1276 }; 1277 } 1278 1279 aspects_left &= ~range.aspectMask; 1280 } 1281} 1282 1283static bool 1284can_use_attachment_initial_layout(struct vk_command_buffer *cmd_buffer, 1285 uint32_t att_idx, 1286 uint32_t view_mask, 1287 VkImageLayout *layout_out, 1288 VkImageLayout *stencil_layout_out) 1289{ 1290 const struct vk_render_pass *pass = cmd_buffer->render_pass; 1291 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer; 1292 const struct vk_render_pass_attachment *rp_att = &pass->attachments[att_idx]; 1293 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx]; 1294 const struct vk_image_view *image_view = att_state->image_view; 1295 1296 if ((rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) && 1297 rp_att->load_op != VK_ATTACHMENT_LOAD_OP_CLEAR) 1298 return false; 1299 1300 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 1301 rp_att->stencil_load_op != VK_ATTACHMENT_LOAD_OP_CLEAR) 1302 return false; 1303 1304 if (cmd_buffer->render_area.offset.x != 0 || 1305 cmd_buffer->render_area.offset.y != 0 || 1306 cmd_buffer->render_area.extent.width != image_view->extent.width || 1307 cmd_buffer->render_area.extent.height != image_view->extent.height) 1308 return false; 1309 1310 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) { 1311 /* For 3D images, the view has to be the whole thing */ 1312 if (image_view->base_array_layer != 0) 1313 return false; 1314 1315 if (pass->is_multiview) { 1316 if (!util_is_power_of_two_or_zero(view_mask + 1) || 1317 util_last_bit(view_mask) != image_view->layer_count) 1318 return false; 1319 } else { 1320 if (framebuffer->layers != image_view->layer_count) 1321 return false; 1322 } 1323 } 1324 1325 /* Finally, check if the entire thing is undefined. It's ok to smash the 1326 * view_mask now as the only thing using it will be the loop below. 1327 */ 1328 1329 /* 3D is stupidly special. See transition_attachment() */ 1330 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) 1331 view_mask = 1; 1332 1333 VkImageLayout layout = VK_IMAGE_LAYOUT_MAX_ENUM; 1334 VkImageLayout stencil_layout = VK_IMAGE_LAYOUT_MAX_ENUM; 1335 1336 assert(view_mask != 0); 1337 u_foreach_bit(view, view_mask) { 1338 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT); 1339 struct vk_attachment_view_state *att_view_state = &att_state->views[view]; 1340 1341 if (rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) { 1342 if (layout == VK_IMAGE_LAYOUT_MAX_ENUM) 1343 layout = att_view_state->layout; 1344 else if (layout != att_view_state->layout) 1345 return false; 1346 } 1347 1348 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 1349 if (stencil_layout == VK_IMAGE_LAYOUT_MAX_ENUM) 1350 stencil_layout = att_view_state->stencil_layout; 1351 else if (stencil_layout != att_view_state->stencil_layout) 1352 return false; 1353 } 1354 } 1355 1356 if (layout != VK_IMAGE_LAYOUT_MAX_ENUM) 1357 *layout_out = layout; 1358 else if (layout_out != NULL) 1359 *layout_out = VK_IMAGE_LAYOUT_UNDEFINED; 1360 1361 if (stencil_layout != VK_IMAGE_LAYOUT_MAX_ENUM) 1362 *stencil_layout_out = stencil_layout; 1363 else if (stencil_layout_out != NULL) 1364 *stencil_layout_out = VK_IMAGE_LAYOUT_UNDEFINED; 1365 1366 return true; 1367} 1368 1369static void 1370set_attachment_layout(struct vk_command_buffer *cmd_buffer, 1371 uint32_t att_idx, 1372 uint32_t view_mask, 1373 VkImageLayout layout, 1374 VkImageLayout stencil_layout) 1375{ 1376 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx]; 1377 1378 u_foreach_bit(view, view_mask) { 1379 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT); 1380 struct vk_attachment_view_state *att_view_state = &att_state->views[view]; 1381 1382 att_view_state->layout = layout; 1383 att_view_state->stencil_layout = stencil_layout; 1384 } 1385} 1386 1387static void 1388transition_attachment(struct vk_command_buffer *cmd_buffer, 1389 uint32_t att_idx, 1390 uint32_t view_mask, 1391 VkImageLayout layout, 1392 VkImageLayout stencil_layout, 1393 uint32_t *barrier_count, 1394 uint32_t max_barrier_count, 1395 VkImageMemoryBarrier2 *barriers) 1396{ 1397 const struct vk_render_pass *pass = cmd_buffer->render_pass; 1398 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer; 1399 const struct vk_render_pass_attachment *pass_att = 1400 &pass->attachments[att_idx]; 1401 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx]; 1402 const struct vk_image_view *image_view = att_state->image_view; 1403 1404 /* 3D is stupidly special. From the Vulkan 1.3.204 spec: 1405 * 1406 * "When the VkImageSubresourceRange structure is used to select a 1407 * subset of the slices of a 3D image’s mip level in order to create 1408 * a 2D or 2D array image view of a 3D image created with 1409 * VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT, baseArrayLayer and 1410 * layerCount specify the first slice index and the number of slices 1411 * to include in the created image view. Such an image view can be 1412 * used as a framebuffer attachment that refers only to the specified 1413 * range of slices of the selected mip level. However, any layout 1414 * transitions performed on such an attachment view during a render 1415 * pass instance still apply to the entire subresource referenced 1416 * which includes all the slices of the selected mip level." 1417 * 1418 * To deal with this, we expand out the layer range to include the 1419 * entire 3D image and treat them as having only a single view even when 1420 * multiview is enabled. This later part means that we effectively only 1421 * track one image layout for the entire attachment rather than one per 1422 * view like we do for all the others. 1423 */ 1424 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) 1425 view_mask = 1; 1426 1427 u_foreach_bit(view, view_mask) { 1428 assert(view >= 0 && view < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT); 1429 struct vk_attachment_view_state *att_view_state = &att_state->views[view]; 1430 1431 /* First, check to see if we even need a transition */ 1432 if (att_view_state->layout == layout && 1433 att_view_state->stencil_layout == stencil_layout) 1434 continue; 1435 1436 VkImageSubresourceRange range = { 1437 .aspectMask = pass_att->aspects, 1438 .baseMipLevel = image_view->base_mip_level, 1439 .levelCount = 1, 1440 }; 1441 1442 /* From the Vulkan 1.3.207 spec: 1443 * 1444 * "Automatic layout transitions apply to the entire image 1445 * subresource attached to the framebuffer. If multiview is not 1446 * enabled and the attachment is a view of a 1D or 2D image, the 1447 * automatic layout transitions apply to the number of layers 1448 * specified by VkFramebufferCreateInfo::layers. If multiview is 1449 * enabled and the attachment is a view of a 1D or 2D image, the 1450 * automatic layout transitions apply to the layers corresponding to 1451 * views which are used by some subpass in the render pass, even if 1452 * that subpass does not reference the given attachment. If the 1453 * attachment view is a 2D or 2D array view of a 3D image, even if 1454 * the attachment view only refers to a subset of the slices of the 1455 * selected mip level of the 3D image, automatic layout transitions 1456 * apply to the entire subresource referenced which is the entire mip 1457 * level in this case." 1458 */ 1459 if (image_view->image->image_type == VK_IMAGE_TYPE_3D) { 1460 assert(view == 0); 1461 range.baseArrayLayer = 0; 1462 range.layerCount = image_view->extent.depth; 1463 } else if (pass->is_multiview) { 1464 range.baseArrayLayer = image_view->base_array_layer + view; 1465 range.layerCount = 1; 1466 } else { 1467 assert(view == 0); 1468 range.baseArrayLayer = image_view->base_array_layer; 1469 range.layerCount = framebuffer->layers; 1470 } 1471 1472 transition_image_range(image_view, range, 1473 att_view_state->layout, layout, 1474 att_view_state->stencil_layout, stencil_layout, 1475 att_view_state->sample_locations, 1476 barrier_count, max_barrier_count, barriers); 1477 1478 att_view_state->layout = layout; 1479 att_view_state->stencil_layout = stencil_layout; 1480 } 1481} 1482 1483static void 1484load_attachment(struct vk_command_buffer *cmd_buffer, 1485 uint32_t att_idx, uint32_t view_mask, 1486 VkImageLayout layout, VkImageLayout stencil_layout) 1487{ 1488 const struct vk_render_pass *pass = cmd_buffer->render_pass; 1489 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer; 1490 const struct vk_render_pass_attachment *rp_att = &pass->attachments[att_idx]; 1491 struct vk_attachment_state *att_state = &cmd_buffer->attachments[att_idx]; 1492 struct vk_device_dispatch_table *disp = 1493 &cmd_buffer->base.device->dispatch_table; 1494 1495 /* Don't load any views we've already loaded */ 1496 view_mask &= ~att_state->views_loaded; 1497 if (view_mask == 0) 1498 return; 1499 1500 /* From here on, if we return, we loaded the views */ 1501 att_state->views_loaded |= view_mask; 1502 1503 /* We only need to load/store if there's a clear */ 1504 bool need_load_store = false; 1505 if ((rp_att->aspects & ~VK_IMAGE_ASPECT_STENCIL_BIT) && 1506 rp_att->load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 1507 need_load_store = true; 1508 1509 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 1510 rp_att->stencil_load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 1511 need_load_store = true; 1512 1513 if (!need_load_store) 1514 return; 1515 1516 const VkRenderingAttachmentInfo att = { 1517 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1518 .imageView = vk_image_view_to_handle(att_state->image_view), 1519 .imageLayout = layout, 1520 .loadOp = rp_att->load_op, 1521 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 1522 .clearValue = att_state->clear_value, 1523 }; 1524 1525 const VkRenderingAttachmentInfo stencil_att = { 1526 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1527 .imageView = vk_image_view_to_handle(att_state->image_view), 1528 .imageLayout = stencil_layout, 1529 .loadOp = rp_att->stencil_load_op, 1530 .storeOp = VK_ATTACHMENT_STORE_OP_STORE, 1531 .clearValue = att_state->clear_value, 1532 }; 1533 1534 VkRenderingInfo render = { 1535 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 1536 .renderArea = cmd_buffer->render_area, 1537 .layerCount = pass->is_multiview ? 1 : framebuffer->layers, 1538 .viewMask = pass->is_multiview ? view_mask : 0, 1539 }; 1540 1541 if (rp_att->aspects & (VK_IMAGE_ASPECT_DEPTH_BIT | 1542 VK_IMAGE_ASPECT_STENCIL_BIT)) { 1543 if (rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 1544 render.pDepthAttachment = &att; 1545 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) 1546 render.pStencilAttachment = &stencil_att; 1547 } else { 1548 render.colorAttachmentCount = 1; 1549 render.pColorAttachments = &att; 1550 } 1551 1552 disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer), &render); 1553 disp->CmdEndRendering(vk_command_buffer_to_handle(cmd_buffer)); 1554} 1555 1556static void 1557begin_subpass(struct vk_command_buffer *cmd_buffer, 1558 const VkSubpassBeginInfo *begin_info) 1559{ 1560 const struct vk_render_pass *pass = cmd_buffer->render_pass; 1561 const struct vk_framebuffer *framebuffer = cmd_buffer->framebuffer; 1562 const uint32_t subpass_idx = cmd_buffer->subpass_idx; 1563 assert(subpass_idx < pass->subpass_count); 1564 const struct vk_subpass *subpass = &pass->subpasses[subpass_idx]; 1565 struct vk_device_dispatch_table *disp = 1566 &cmd_buffer->base.device->dispatch_table; 1567 1568 /* First, we figure out all our attachments and attempt to handle image 1569 * layout transitions and load ops as part of vkCmdBeginRendering if we 1570 * can. For any we can't handle this way, we'll need explicit barriers 1571 * or quick vkCmdBegin/EndRendering to do the load op. 1572 */ 1573 1574 STACK_ARRAY(VkRenderingAttachmentInfo, color_attachments, 1575 subpass->color_count); 1576 STACK_ARRAY(VkRenderingAttachmentInitialLayoutInfoMESA, 1577 color_attachment_initial_layouts, 1578 subpass->color_count); 1579 1580 for (uint32_t i = 0; i < subpass->color_count; i++) { 1581 const struct vk_subpass_attachment *sp_att = 1582 &subpass->color_attachments[i]; 1583 VkRenderingAttachmentInfo *color_attachment = &color_attachments[i]; 1584 1585 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) { 1586 *color_attachment = (VkRenderingAttachmentInfo) { 1587 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1588 .imageView = VK_NULL_HANDLE, 1589 }; 1590 continue; 1591 } 1592 1593 assert(sp_att->attachment < pass->attachment_count); 1594 const struct vk_render_pass_attachment *rp_att = 1595 &pass->attachments[sp_att->attachment]; 1596 struct vk_attachment_state *att_state = 1597 &cmd_buffer->attachments[sp_att->attachment]; 1598 1599 *color_attachment = (VkRenderingAttachmentInfo) { 1600 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1601 .imageView = vk_image_view_to_handle(att_state->image_view), 1602 .imageLayout = sp_att->layout, 1603 }; 1604 1605 if (!(subpass->view_mask & att_state->views_loaded)) { 1606 /* None of these views have been used before */ 1607 color_attachment->loadOp = rp_att->load_op; 1608 color_attachment->clearValue = att_state->clear_value; 1609 att_state->views_loaded |= subpass->view_mask; 1610 1611 VkImageLayout initial_layout; 1612 if (can_use_attachment_initial_layout(cmd_buffer, 1613 sp_att->attachment, 1614 subpass->view_mask, 1615 &initial_layout, NULL) && 1616 sp_att->layout != initial_layout) { 1617 assert(color_attachment->loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); 1618 1619 VkRenderingAttachmentInitialLayoutInfoMESA *color_initial_layout = 1620 &color_attachment_initial_layouts[i]; 1621 *color_initial_layout = (VkRenderingAttachmentInitialLayoutInfoMESA) { 1622 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA, 1623 .initialLayout = initial_layout, 1624 }; 1625 __vk_append_struct(color_attachment, color_initial_layout); 1626 1627 set_attachment_layout(cmd_buffer, sp_att->attachment, 1628 subpass->view_mask, 1629 sp_att->layout, VK_IMAGE_LAYOUT_UNDEFINED); 1630 } 1631 } else { 1632 /* We've seen at least one of the views of this attachment before so 1633 * we need to LOAD_OP_LOAD. 1634 */ 1635 color_attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1636 } 1637 1638 if (!(subpass->view_mask & ~sp_att->last_subpass)) { 1639 /* This is the last subpass for every view */ 1640 color_attachment->storeOp = rp_att->store_op; 1641 } else { 1642 /* For at least one of our views, this isn't the last subpass 1643 * 1644 * In the edge case where we have lots of weird overlap between view 1645 * masks of different subThis may mean that we get STORE_OP_STORE in 1646 * some places where it may have wanted STORE_OP_NONE but that should 1647 * be harmless. 1648 */ 1649 color_attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1650 } 1651 1652 if (sp_att->resolve != NULL) { 1653 assert(sp_att->resolve->attachment < pass->attachment_count); 1654 struct vk_attachment_state *res_att_state = 1655 &cmd_buffer->attachments[sp_att->resolve->attachment]; 1656 1657 /* Resolve attachments are entirely overwritten by the resolve 1658 * operation so the load op really doesn't matter. We can consider 1659 * the resolve as being the load. 1660 */ 1661 res_att_state->views_loaded |= subpass->view_mask; 1662 1663 if (vk_format_is_int(res_att_state->image_view->format)) 1664 color_attachment->resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; 1665 else 1666 color_attachment->resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1667 1668 color_attachment->resolveImageView = 1669 vk_image_view_to_handle(res_att_state->image_view); 1670 color_attachment->resolveImageLayout = sp_att->resolve->layout; 1671 } else if (subpass->mrtss.multisampledRenderToSingleSampledEnable && 1672 rp_att->samples == VK_SAMPLE_COUNT_1_BIT) { 1673 if (vk_format_is_int(att_state->image_view->format)) 1674 color_attachment->resolveMode = VK_RESOLVE_MODE_SAMPLE_ZERO_BIT; 1675 else 1676 color_attachment->resolveMode = VK_RESOLVE_MODE_AVERAGE_BIT; 1677 } 1678 } 1679 1680 VkRenderingAttachmentInfo depth_attachment = { 1681 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1682 }; 1683 VkRenderingAttachmentInfo stencil_attachment = { 1684 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO, 1685 }; 1686 VkRenderingAttachmentInitialLayoutInfoMESA depth_initial_layout = { 1687 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA, 1688 }; 1689 VkRenderingAttachmentInitialLayoutInfoMESA stencil_initial_layout = { 1690 .sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INITIAL_LAYOUT_INFO_MESA, 1691 }; 1692 1693 const VkSampleLocationsInfoEXT *sample_locations = NULL; 1694 if (subpass->depth_stencil_attachment != NULL) { 1695 const struct vk_subpass_attachment *sp_att = 1696 subpass->depth_stencil_attachment; 1697 1698 assert(sp_att->attachment < pass->attachment_count); 1699 const struct vk_render_pass_attachment *rp_att = 1700 &pass->attachments[sp_att->attachment]; 1701 struct vk_attachment_state *att_state = 1702 &cmd_buffer->attachments[sp_att->attachment]; 1703 1704 assert(sp_att->aspects == rp_att->aspects); 1705 if (rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) { 1706 depth_attachment.imageView = 1707 vk_image_view_to_handle(att_state->image_view); 1708 depth_attachment.imageLayout = sp_att->layout; 1709 } 1710 1711 if (rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) { 1712 stencil_attachment.imageView = 1713 vk_image_view_to_handle(att_state->image_view); 1714 stencil_attachment.imageLayout = sp_att->stencil_layout; 1715 } 1716 1717 if (!(subpass->view_mask & att_state->views_loaded)) { 1718 /* None of these views have been used before */ 1719 depth_attachment.loadOp = rp_att->load_op; 1720 depth_attachment.clearValue = att_state->clear_value; 1721 stencil_attachment.loadOp = rp_att->stencil_load_op; 1722 stencil_attachment.clearValue = att_state->clear_value; 1723 att_state->views_loaded |= subpass->view_mask; 1724 1725 VkImageLayout initial_layout, initial_stencil_layout; 1726 if (can_use_attachment_initial_layout(cmd_buffer, 1727 sp_att->attachment, 1728 subpass->view_mask, 1729 &initial_layout, 1730 &initial_stencil_layout)) { 1731 if ((rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) && 1732 sp_att->layout != initial_layout) { 1733 assert(depth_attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); 1734 depth_initial_layout.initialLayout = initial_layout; 1735 __vk_append_struct(&depth_attachment, 1736 &depth_initial_layout); 1737 } 1738 1739 if ((rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) && 1740 sp_att->stencil_layout != initial_stencil_layout) { 1741 assert(stencil_attachment.loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR); 1742 stencil_initial_layout.initialLayout = initial_stencil_layout; 1743 __vk_append_struct(&stencil_attachment, 1744 &stencil_initial_layout); 1745 } 1746 1747 set_attachment_layout(cmd_buffer, sp_att->attachment, 1748 subpass->view_mask, 1749 sp_att->layout, sp_att->stencil_layout); 1750 } 1751 } else { 1752 /* We've seen at least one of the views of this attachment before so 1753 * we need to LOAD_OP_LOAD. 1754 */ 1755 depth_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1756 stencil_attachment.loadOp = VK_ATTACHMENT_LOAD_OP_LOAD; 1757 } 1758 1759 if (!(subpass->view_mask & ~sp_att->last_subpass)) { 1760 /* This is the last subpass for every view */ 1761 depth_attachment.storeOp = rp_att->store_op; 1762 stencil_attachment.storeOp = rp_att->stencil_store_op; 1763 } else { 1764 /* For at least one of our views, this isn't the last subpass 1765 * 1766 * In the edge case where we have lots of weird overlap between view 1767 * masks of different subThis may mean that we get STORE_OP_STORE in 1768 * some places where it may have wanted STORE_OP_NONE but that should 1769 * be harmless. 1770 */ 1771 depth_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1772 stencil_attachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE; 1773 } 1774 1775 /* From the Vulkan 1.3.212 spec: 1776 * 1777 * "If the current render pass does not use the attachment as a 1778 * depth/stencil attachment in any subpass that happens-before, the 1779 * automatic layout transition uses the sample locations state 1780 * specified in the sampleLocationsInfo member of the element of the 1781 * VkRenderPassSampleLocationsBeginInfoEXT::pAttachmentInitialSampleLocations 1782 * array for which the attachmentIndex member equals the attachment 1783 * index of the attachment, if one is specified. Otherwise, the 1784 * automatic layout transition uses the sample locations state 1785 * specified in the sampleLocationsInfo member of the element of the 1786 * VkRenderPassSampleLocationsBeginInfoEXT::pPostSubpassSampleLocations 1787 * array for which the subpassIndex member equals the index of the 1788 * subpass that last used the attachment as a depth/stencil 1789 * attachment, if one is specified." 1790 * 1791 * Unfortunately, this says nothing whatsoever about multiview. 1792 * However, since multiview render passes are described as a single-view 1793 * render pass repeated per-view, we assume this is per-view. 1794 */ 1795 if (cmd_buffer->pass_sample_locations != NULL && 1796 (att_state->image_view->image->create_flags & 1797 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) { 1798 sample_locations = 1799 get_subpass_sample_locations(cmd_buffer->pass_sample_locations, 1800 subpass_idx); 1801 1802 u_foreach_bit(view, subpass->view_mask) 1803 att_state->views[view].sample_locations = sample_locations; 1804 } 1805 1806 if (sp_att->resolve != NULL || 1807 (subpass->mrtss.multisampledRenderToSingleSampledEnable && 1808 rp_att->samples == VK_SAMPLE_COUNT_1_BIT)) { 1809 const struct vk_subpass_attachment *res_sp_att = sp_att->resolve ? sp_att->resolve : sp_att; 1810 assert(res_sp_att->attachment < pass->attachment_count); 1811 const struct vk_render_pass_attachment *res_rp_att = 1812 &pass->attachments[res_sp_att->attachment]; 1813 struct vk_attachment_state *res_att_state = 1814 &cmd_buffer->attachments[res_sp_att->attachment]; 1815 1816 /* From the Vulkan 1.3.204 spec: 1817 * 1818 * "VkSubpassDescriptionDepthStencilResolve::depthResolveMode is 1819 * ignored if the VkFormat of the pDepthStencilResolveAttachment 1820 * does not have a depth component. Similarly, 1821 * VkSubpassDescriptionDepthStencilResolve::stencilResolveMode is 1822 * ignored if the VkFormat of the pDepthStencilResolveAttachment 1823 * does not have a stencil component." 1824 * 1825 * TODO: Should we handle this here or when we create the render 1826 * pass? Handling it here makes load ops "correct" in the sense 1827 * that, if we resolve to the wrong aspect, we will still consider 1828 * it bound and clear it if requested. 1829 */ 1830 VkResolveModeFlagBits depth_resolve_mode = VK_RESOLVE_MODE_NONE; 1831 if (res_rp_att->aspects & VK_IMAGE_ASPECT_DEPTH_BIT) 1832 depth_resolve_mode = subpass->depth_resolve_mode; 1833 1834 VkResolveModeFlagBits stencil_resolve_mode = VK_RESOLVE_MODE_NONE; 1835 if (res_rp_att->aspects & VK_IMAGE_ASPECT_STENCIL_BIT) 1836 stencil_resolve_mode = subpass->stencil_resolve_mode; 1837 1838 VkImageAspectFlags resolved_aspects = 0; 1839 1840 if (depth_resolve_mode != VK_RESOLVE_MODE_NONE) { 1841 depth_attachment.resolveMode = depth_resolve_mode; 1842 if (sp_att->resolve) { 1843 depth_attachment.resolveImageView = 1844 vk_image_view_to_handle(res_att_state->image_view); 1845 depth_attachment.resolveImageLayout = 1846 sp_att->resolve->layout; 1847 } 1848 1849 resolved_aspects |= VK_IMAGE_ASPECT_DEPTH_BIT; 1850 } 1851 1852 if (stencil_resolve_mode != VK_RESOLVE_MODE_NONE) { 1853 stencil_attachment.resolveMode = stencil_resolve_mode; 1854 if (sp_att->resolve) { 1855 stencil_attachment.resolveImageView = 1856 vk_image_view_to_handle(res_att_state->image_view); 1857 stencil_attachment.resolveImageLayout = 1858 sp_att->resolve->stencil_layout; 1859 } 1860 1861 resolved_aspects |= VK_IMAGE_ASPECT_STENCIL_BIT; 1862 } 1863 1864 if (sp_att->resolve && resolved_aspects == rp_att->aspects) { 1865 /* The resolve attachment is entirely overwritten by the 1866 * resolve operation so the load op really doesn't matter. 1867 * We can consider the resolve as being the load. 1868 */ 1869 res_att_state->views_loaded |= subpass->view_mask; 1870 } 1871 } 1872 } 1873 1874 /* Next, handle any barriers we need. This may include a general 1875 * VkMemoryBarrier for subpass dependencies and it may include some 1876 * number of VkImageMemoryBarriers for layout transitions. 1877 */ 1878 1879 bool needs_mem_barrier = false; 1880 VkMemoryBarrier2 mem_barrier = { 1881 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, 1882 }; 1883 for (uint32_t d = 0; d < pass->dependency_count; d++) { 1884 const struct vk_subpass_dependency *dep = &pass->dependencies[d]; 1885 if (dep->dst_subpass != subpass_idx) 1886 continue; 1887 1888 if (dep->flags & VK_DEPENDENCY_VIEW_LOCAL_BIT) { 1889 /* From the Vulkan 1.3.204 spec: 1890 * 1891 * VUID-VkSubpassDependency2-dependencyFlags-03091 1892 * 1893 * "If dependencyFlags includes VK_DEPENDENCY_VIEW_LOCAL_BIT, 1894 * dstSubpass must not be equal to VK_SUBPASS_EXTERNAL" 1895 */ 1896 assert(dep->src_subpass != VK_SUBPASS_EXTERNAL); 1897 1898 assert(dep->src_subpass < pass->subpass_count); 1899 const struct vk_subpass *src_subpass = 1900 &pass->subpasses[dep->src_subpass]; 1901 1902 /* Figure out the set of views in the source subpass affected by this 1903 * dependency. 1904 */ 1905 uint32_t src_dep_view_mask = subpass->view_mask; 1906 if (dep->view_offset >= 0) 1907 src_dep_view_mask <<= dep->view_offset; 1908 else 1909 src_dep_view_mask >>= -dep->view_offset; 1910 1911 /* From the Vulkan 1.3.204 spec: 1912 * 1913 * "If the dependency is view-local, then each view (dstView) in 1914 * the destination subpass depends on the view dstView + 1915 * pViewOffsets[dependency] in the source subpass. If there is not 1916 * such a view in the source subpass, then this dependency does 1917 * not affect that view in the destination subpass." 1918 */ 1919 if (!(src_subpass->view_mask & src_dep_view_mask)) 1920 continue; 1921 } 1922 1923 needs_mem_barrier = true; 1924 mem_barrier.srcStageMask |= dep->src_stage_mask; 1925 mem_barrier.srcAccessMask |= dep->src_access_mask; 1926 mem_barrier.dstStageMask |= dep->dst_stage_mask; 1927 mem_barrier.dstAccessMask |= dep->dst_access_mask; 1928 } 1929 1930 if (subpass_idx == 0) { 1931 /* From the Vulkan 1.3.232 spec: 1932 * 1933 * "If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the 1934 * first subpass that uses an attachment, then an implicit subpass 1935 * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it 1936 * is used in. The implicit subpass dependency only exists if there 1937 * exists an automatic layout transition away from initialLayout. The 1938 * subpass dependency operates as if defined with the following 1939 * parameters: 1940 * 1941 * VkSubpassDependency implicitDependency = { 1942 * .srcSubpass = VK_SUBPASS_EXTERNAL; 1943 * .dstSubpass = firstSubpass; // First subpass attachment is used in 1944 * .srcStageMask = VK_PIPELINE_STAGE_NONE; 1945 * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1946 * .srcAccessMask = 0; 1947 * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 1948 * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1949 * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1950 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 1951 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 1952 * .dependencyFlags = 0; 1953 * };" 1954 * 1955 * We could track individual subpasses and attachments and views to make 1956 * sure we only insert this barrier when it's absolutely necessary. 1957 * However, this is only going to happen for the first subpass and 1958 * you're probably going to take a stall in BeginRenderPass() anyway. 1959 * If this is ever a perf problem, we can re-evaluate and do something 1960 * more intellegent at that time. 1961 */ 1962 needs_mem_barrier = true; 1963 mem_barrier.dstStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 1964 mem_barrier.dstAccessMask |= VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 1965 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 1966 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 1967 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 1968 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 1969 } 1970 1971 uint32_t max_image_barrier_count = 0; 1972 for (uint32_t a = 0; a < subpass->attachment_count; a++) { 1973 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a]; 1974 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) 1975 continue; 1976 1977 assert(sp_att->attachment < pass->attachment_count); 1978 const struct vk_render_pass_attachment *rp_att = 1979 &pass->attachments[sp_att->attachment]; 1980 1981 max_image_barrier_count += util_bitcount(subpass->view_mask) * 1982 util_bitcount(rp_att->aspects); 1983 } 1984 STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, max_image_barrier_count); 1985 uint32_t image_barrier_count = 0; 1986 1987 for (uint32_t a = 0; a < subpass->attachment_count; a++) { 1988 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a]; 1989 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) 1990 continue; 1991 1992 /* If we're using an initial layout, the attachment will already be 1993 * marked as transitioned and this will be a no-op. 1994 */ 1995 transition_attachment(cmd_buffer, sp_att->attachment, 1996 subpass->view_mask, 1997 sp_att->layout, sp_att->stencil_layout, 1998 &image_barrier_count, 1999 max_image_barrier_count, 2000 image_barriers); 2001 } 2002 assert(image_barrier_count <= max_image_barrier_count); 2003 2004 if (needs_mem_barrier || image_barrier_count > 0) { 2005 const VkDependencyInfo dependency_info = { 2006 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, 2007 .dependencyFlags = 0, 2008 .memoryBarrierCount = needs_mem_barrier ? 1 : 0, 2009 .pMemoryBarriers = needs_mem_barrier ? &mem_barrier : NULL, 2010 .imageMemoryBarrierCount = image_barrier_count, 2011 .pImageMemoryBarriers = image_barrier_count > 0 ? 2012 image_barriers : NULL, 2013 }; 2014 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer), 2015 &dependency_info); 2016 } 2017 2018 STACK_ARRAY_FINISH(image_barriers); 2019 2020 /* Next, handle any VK_ATTACHMENT_LOAD_OP_CLEAR that we couldn't handle 2021 * directly by emitting a quick vkCmdBegin/EndRendering to do the load. 2022 */ 2023 for (uint32_t a = 0; a < subpass->attachment_count; a++) { 2024 const struct vk_subpass_attachment *sp_att = &subpass->attachments[a]; 2025 if (sp_att->attachment == VK_ATTACHMENT_UNUSED) 2026 continue; 2027 2028 load_attachment(cmd_buffer, sp_att->attachment, subpass->view_mask, 2029 sp_att->layout, sp_att->stencil_layout); 2030 } 2031 2032 /* TODO: Handle preserve attachments 2033 * 2034 * For immediate renderers, this isn't a big deal as LOAD_OP_LOAD and 2035 * STORE_OP_STORE are effectively free. However, before this gets used on 2036 * a tiling GPU, we should really hook up preserve attachments and use them 2037 * to determine when we can use LOAD/STORE_OP_DONT_CARE between subpasses. 2038 */ 2039 2040 VkRenderingInfo rendering = { 2041 .sType = VK_STRUCTURE_TYPE_RENDERING_INFO, 2042 .renderArea = cmd_buffer->render_area, 2043 .layerCount = pass->is_multiview ? 1 : framebuffer->layers, 2044 .viewMask = pass->is_multiview ? subpass->view_mask : 0, 2045 .colorAttachmentCount = subpass->color_count, 2046 .pColorAttachments = color_attachments, 2047 .pDepthAttachment = &depth_attachment, 2048 .pStencilAttachment = &stencil_attachment, 2049 }; 2050 2051 VkRenderingFragmentShadingRateAttachmentInfoKHR fsr_attachment; 2052 if (subpass->fragment_shading_rate_attachment) { 2053 const struct vk_subpass_attachment *sp_att = 2054 subpass->fragment_shading_rate_attachment; 2055 2056 assert(sp_att->attachment < pass->attachment_count); 2057 struct vk_attachment_state *att_state = 2058 &cmd_buffer->attachments[sp_att->attachment]; 2059 2060 /* Fragment shading rate attachments have no loadOp (it's implicitly 2061 * LOAD_OP_LOAD) so we need to ensure the load op happens. 2062 */ 2063 load_attachment(cmd_buffer, sp_att->attachment, subpass->view_mask, 2064 sp_att->layout, sp_att->stencil_layout); 2065 2066 fsr_attachment = (VkRenderingFragmentShadingRateAttachmentInfoKHR) { 2067 .sType = VK_STRUCTURE_TYPE_RENDERING_FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR, 2068 .imageView = vk_image_view_to_handle(att_state->image_view), 2069 .imageLayout = sp_att->layout, 2070 .shadingRateAttachmentTexelSize = 2071 subpass->fragment_shading_rate_attachment_texel_size, 2072 }; 2073 __vk_append_struct(&rendering, &fsr_attachment); 2074 } 2075 2076 VkSampleLocationsInfoEXT sample_locations_tmp; 2077 if (sample_locations) { 2078 sample_locations_tmp = *sample_locations; 2079 __vk_append_struct(&rendering, &sample_locations_tmp); 2080 } 2081 2082 /* Append this one last because it lives in the subpass and we don't want 2083 * to be changed by appending other structures later. 2084 */ 2085 __vk_append_struct(&rendering, (void *)&subpass->self_dep_info); 2086 2087 disp->CmdBeginRendering(vk_command_buffer_to_handle(cmd_buffer), 2088 &rendering); 2089 2090 STACK_ARRAY_FINISH(color_attachments); 2091 STACK_ARRAY_FINISH(color_attachment_initial_layouts); 2092} 2093 2094static void 2095end_subpass(struct vk_command_buffer *cmd_buffer, 2096 const VkSubpassEndInfo *end_info) 2097{ 2098 const struct vk_render_pass *pass = cmd_buffer->render_pass; 2099 const uint32_t subpass_idx = cmd_buffer->subpass_idx; 2100 struct vk_device_dispatch_table *disp = 2101 &cmd_buffer->base.device->dispatch_table; 2102 2103 disp->CmdEndRendering(vk_command_buffer_to_handle(cmd_buffer)); 2104 2105 bool needs_mem_barrier = false; 2106 VkMemoryBarrier2 mem_barrier = { 2107 .sType = VK_STRUCTURE_TYPE_MEMORY_BARRIER_2, 2108 }; 2109 for (uint32_t d = 0; d < pass->dependency_count; d++) { 2110 const struct vk_subpass_dependency *dep = &pass->dependencies[d]; 2111 if (dep->src_subpass != subpass_idx) 2112 continue; 2113 2114 if (dep->dst_subpass != VK_SUBPASS_EXTERNAL) 2115 continue; 2116 2117 needs_mem_barrier = true; 2118 mem_barrier.srcStageMask |= dep->src_stage_mask; 2119 mem_barrier.srcAccessMask |= dep->src_access_mask; 2120 mem_barrier.dstStageMask |= dep->dst_stage_mask; 2121 mem_barrier.dstAccessMask |= dep->dst_access_mask; 2122 } 2123 2124 if (subpass_idx == pass->subpass_count - 1) { 2125 /* From the Vulkan 1.3.232 spec: 2126 * 2127 * "Similarly, if there is no subpass dependency from the last 2128 * subpass that uses an attachment to VK_SUBPASS_EXTERNAL, then an 2129 * implicit subpass dependency exists from the last subpass it is 2130 * used in to VK_SUBPASS_EXTERNAL. The implicit subpass dependency 2131 * only exists if there exists an automatic layout transition into 2132 * finalLayout. The subpass dependency operates as if defined with 2133 * the following parameters: 2134 * 2135 * VkSubpassDependency implicitDependency = { 2136 * .srcSubpass = lastSubpass; // Last subpass attachment is used in 2137 * .dstSubpass = VK_SUBPASS_EXTERNAL; 2138 * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 2139 * .dstStageMask = VK_PIPELINE_STAGE_NONE; 2140 * .srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 2141 * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 2142 * .dstAccessMask = 0; 2143 * .dependencyFlags = 0; 2144 * };" 2145 * 2146 * We could track individual subpasses and attachments and views to make 2147 * sure we only insert this barrier when it's absolutely necessary. 2148 * However, this is only going to happen for the last subpass and 2149 * you're probably going to take a stall in EndRenderPass() anyway. 2150 * If this is ever a perf problem, we can re-evaluate and do something 2151 * more intellegent at that time. 2152 */ 2153 needs_mem_barrier = true; 2154 mem_barrier.srcStageMask |= VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 2155 mem_barrier.srcAccessMask |= VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 2156 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 2157 } 2158 2159 if (needs_mem_barrier) { 2160 const VkDependencyInfo dependency_info = { 2161 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, 2162 .dependencyFlags = 0, 2163 .memoryBarrierCount = 1, 2164 .pMemoryBarriers = &mem_barrier, 2165 }; 2166 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer), 2167 &dependency_info); 2168 } 2169} 2170 2171VKAPI_ATTR void VKAPI_CALL 2172vk_common_CmdBeginRenderPass2(VkCommandBuffer commandBuffer, 2173 const VkRenderPassBeginInfo *pRenderPassBeginInfo, 2174 const VkSubpassBeginInfo *pSubpassBeginInfo) 2175{ 2176 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 2177 VK_FROM_HANDLE(vk_render_pass, pass, pRenderPassBeginInfo->renderPass); 2178 VK_FROM_HANDLE(vk_framebuffer, framebuffer, 2179 pRenderPassBeginInfo->framebuffer); 2180 2181 assert(cmd_buffer->render_pass == NULL); 2182 cmd_buffer->render_pass = pass; 2183 cmd_buffer->subpass_idx = 0; 2184 2185 assert(cmd_buffer->framebuffer == NULL); 2186 cmd_buffer->framebuffer = framebuffer; 2187 2188 cmd_buffer->render_area = pRenderPassBeginInfo->renderArea; 2189 2190 assert(cmd_buffer->attachments == NULL); 2191 if (pass->attachment_count > ARRAY_SIZE(cmd_buffer->_attachments)) { 2192 cmd_buffer->attachments = malloc(pass->attachment_count * 2193 sizeof(*cmd_buffer->attachments)); 2194 } else { 2195 cmd_buffer->attachments = cmd_buffer->_attachments; 2196 } 2197 2198 const VkRenderPassAttachmentBeginInfo *attach_begin = 2199 vk_find_struct_const(pRenderPassBeginInfo, 2200 RENDER_PASS_ATTACHMENT_BEGIN_INFO); 2201 if (!attach_begin) 2202 assert(pass->attachment_count == framebuffer->attachment_count); 2203 2204 const VkImageView *image_views; 2205 if (attach_begin && attach_begin->attachmentCount != 0) { 2206 assert(attach_begin->attachmentCount == pass->attachment_count); 2207 image_views = attach_begin->pAttachments; 2208 } else { 2209 assert(framebuffer->attachment_count >= pass->attachment_count); 2210 image_views = framebuffer->attachments; 2211 } 2212 2213 for (uint32_t a = 0; a < pass->attachment_count; ++a) { 2214 VK_FROM_HANDLE(vk_image_view, image_view, image_views[a]); 2215 const struct vk_render_pass_attachment *pass_att = &pass->attachments[a]; 2216 struct vk_attachment_state *att_state = &cmd_buffer->attachments[a]; 2217 2218 /* From the Vulkan 1.3.204 spec: 2219 * 2220 * VUID-VkFramebufferCreateInfo-pAttachments-00880 2221 * 2222 * "If renderpass is not VK_NULL_HANDLE and flags does not include 2223 * VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments 2224 * must have been created with a VkFormat value that matches the 2225 * VkFormat specified by the corresponding VkAttachmentDescription in 2226 * renderPass" 2227 * 2228 * and 2229 * 2230 * VUID-VkRenderPassBeginInfo-framebuffer-03216 2231 * 2232 * "If framebuffer was created with a VkFramebufferCreateInfo::flags 2233 * value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each 2234 * element of the pAttachments member of a 2235 * VkRenderPassAttachmentBeginInfo structure included in the pNext 2236 * chain must be a VkImageView of an image created with a value of 2237 * VkImageViewCreateInfo::format equal to the corresponding value of 2238 * VkAttachmentDescription::format in renderPass" 2239 */ 2240 assert(image_view->format == pass_att->format); 2241 2242 /* From the Vulkan 1.3.204 spec: 2243 * 2244 * VUID-VkFramebufferCreateInfo-pAttachments-00881 2245 * 2246 * "If renderpass is not VK_NULL_HANDLE and flags does not include 2247 * VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each element of pAttachments 2248 * must have been created with a samples value that matches the 2249 * samples value specified by the corresponding 2250 * VkAttachmentDescription in renderPass" 2251 * 2252 * and 2253 * 2254 * UID-VkRenderPassBeginInfo-framebuffer-03217 2255 * 2256 * "If framebuffer was created with a VkFramebufferCreateInfo::flags 2257 * value that included VK_FRAMEBUFFER_CREATE_IMAGELESS_BIT, each 2258 * element of the pAttachments member of a 2259 * VkRenderPassAttachmentBeginInfo structure included in the pNext 2260 * chain must be a VkImageView of an image created with a value of 2261 * VkImageCreateInfo::samples equal to the corresponding value of 2262 * VkAttachmentDescription::samples in renderPass" 2263 */ 2264 assert(image_view->image->samples == pass_att->samples); 2265 2266 /* From the Vulkan 1.3.204 spec: 2267 * 2268 * If multiview is enabled and the shading rate attachment has 2269 * multiple layers, the shading rate attachment texel is selected 2270 * from the layer determined by the ViewIndex built-in. If multiview 2271 * is disabled, and both the shading rate attachment and the 2272 * framebuffer have multiple layers, the shading rate attachment 2273 * texel is selected from the layer determined by the Layer built-in. 2274 * Otherwise, the texel is unconditionally selected from the first 2275 * layer of the attachment. 2276 */ 2277 if (!(image_view->usage & VK_IMAGE_USAGE_FRAGMENT_SHADING_RATE_ATTACHMENT_BIT_KHR)) 2278 assert(util_last_bit(pass_att->view_mask) <= image_view->layer_count); 2279 2280 *att_state = (struct vk_attachment_state) { 2281 .image_view = image_view, 2282 .views_loaded = 0, 2283 }; 2284 2285 for (uint32_t v = 0; v < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT; v++) { 2286 att_state->views[v] = (struct vk_attachment_view_state) { 2287 .layout = pass_att->initial_layout, 2288 .stencil_layout = pass_att->initial_stencil_layout, 2289 }; 2290 } 2291 2292 if (a < pRenderPassBeginInfo->clearValueCount) 2293 att_state->clear_value = pRenderPassBeginInfo->pClearValues[a]; 2294 } 2295 2296 const VkRenderPassSampleLocationsBeginInfoEXT *rp_sl_info = 2297 vk_find_struct_const(pRenderPassBeginInfo->pNext, 2298 RENDER_PASS_SAMPLE_LOCATIONS_BEGIN_INFO_EXT); 2299 if (rp_sl_info) { 2300 cmd_buffer->pass_sample_locations = clone_rp_sample_locations(rp_sl_info); 2301 assert(cmd_buffer->pass_sample_locations); 2302 2303 for (uint32_t i = 0; i < rp_sl_info->attachmentInitialSampleLocationsCount; i++) { 2304 const VkAttachmentSampleLocationsEXT *att_sl = 2305 &rp_sl_info->pAttachmentInitialSampleLocations[i]; 2306 2307 assert(att_sl->attachmentIndex < pass->attachment_count); 2308 struct vk_attachment_state *att_state = 2309 &cmd_buffer->attachments[att_sl->attachmentIndex]; 2310 2311 /* Sample locations only matter for depth/stencil images created with 2312 * VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT 2313 */ 2314 if (vk_format_is_depth_or_stencil(att_state->image_view->format) && 2315 (att_state->image_view->image->create_flags & 2316 VK_IMAGE_CREATE_SAMPLE_LOCATIONS_COMPATIBLE_DEPTH_BIT_EXT)) { 2317 for (uint32_t v = 0; v < MESA_VK_MAX_MULTIVIEW_VIEW_COUNT; v++) 2318 att_state->views[v].sample_locations = &att_sl->sampleLocationsInfo; 2319 } 2320 } 2321 } 2322 2323 begin_subpass(cmd_buffer, pSubpassBeginInfo); 2324} 2325 2326void 2327vk_command_buffer_reset_render_pass(struct vk_command_buffer *cmd_buffer) 2328{ 2329 cmd_buffer->render_pass = NULL; 2330 cmd_buffer->subpass_idx = 0; 2331 cmd_buffer->framebuffer = NULL; 2332 if (cmd_buffer->attachments != cmd_buffer->_attachments) 2333 free(cmd_buffer->attachments); 2334 cmd_buffer->attachments = NULL; 2335 if (cmd_buffer->pass_sample_locations != NULL) 2336 vk_free(vk_default_allocator(), cmd_buffer->pass_sample_locations); 2337 cmd_buffer->pass_sample_locations = NULL; 2338} 2339 2340VKAPI_ATTR void VKAPI_CALL 2341vk_common_CmdNextSubpass2(VkCommandBuffer commandBuffer, 2342 const VkSubpassBeginInfo *pSubpassBeginInfo, 2343 const VkSubpassEndInfo *pSubpassEndInfo) 2344{ 2345 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 2346 2347 end_subpass(cmd_buffer, pSubpassEndInfo); 2348 cmd_buffer->subpass_idx++; 2349 begin_subpass(cmd_buffer, pSubpassBeginInfo); 2350} 2351 2352VKAPI_ATTR void VKAPI_CALL 2353vk_common_CmdEndRenderPass2(VkCommandBuffer commandBuffer, 2354 const VkSubpassEndInfo *pSubpassEndInfo) 2355{ 2356 VK_FROM_HANDLE(vk_command_buffer, cmd_buffer, commandBuffer); 2357 const struct vk_render_pass *pass = cmd_buffer->render_pass; 2358 struct vk_device_dispatch_table *disp = 2359 &cmd_buffer->base.device->dispatch_table; 2360 2361 end_subpass(cmd_buffer, pSubpassEndInfo); 2362 2363 /* Make sure all our attachments end up in their finalLayout */ 2364 2365 uint32_t max_image_barrier_count = 0; 2366 for (uint32_t a = 0; a < pass->attachment_count; a++) { 2367 const struct vk_render_pass_attachment *rp_att = &pass->attachments[a]; 2368 2369 max_image_barrier_count += util_bitcount(pass->view_mask) * 2370 util_bitcount(rp_att->aspects); 2371 } 2372 STACK_ARRAY(VkImageMemoryBarrier2, image_barriers, max_image_barrier_count); 2373 uint32_t image_barrier_count = 0; 2374 2375 for (uint32_t a = 0; a < pass->attachment_count; a++) { 2376 const struct vk_render_pass_attachment *rp_att = &pass->attachments[a]; 2377 2378 transition_attachment(cmd_buffer, a, pass->view_mask, 2379 rp_att->final_layout, 2380 rp_att->final_stencil_layout, 2381 &image_barrier_count, 2382 max_image_barrier_count, 2383 image_barriers); 2384 } 2385 assert(image_barrier_count <= max_image_barrier_count); 2386 2387 if (image_barrier_count > 0) { 2388 const VkDependencyInfo dependency_info = { 2389 .sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO, 2390 .dependencyFlags = 0, 2391 .imageMemoryBarrierCount = image_barrier_count, 2392 .pImageMemoryBarriers = image_barriers, 2393 }; 2394 disp->CmdPipelineBarrier2(vk_command_buffer_to_handle(cmd_buffer), 2395 &dependency_info); 2396 } 2397 2398 STACK_ARRAY_FINISH(image_barriers); 2399 2400 vk_command_buffer_reset_render_pass(cmd_buffer); 2401} 2402