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