1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Copyright © 2016 Red Hat. 3bf215546Sopenharmony_ci * Copyright © 2016 Bas Nieuwenhuizen 4bf215546Sopenharmony_ci * 5bf215546Sopenharmony_ci * based in part on anv driver which is: 6bf215546Sopenharmony_ci * Copyright © 2015 Intel Corporation 7bf215546Sopenharmony_ci * 8bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 9bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 10bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 11bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 12bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 13bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 14bf215546Sopenharmony_ci * 15bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next 16bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the 17bf215546Sopenharmony_ci * Software. 18bf215546Sopenharmony_ci * 19bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 25bf215546Sopenharmony_ci * IN THE SOFTWARE. 26bf215546Sopenharmony_ci */ 27bf215546Sopenharmony_ci#include "radv_private.h" 28bf215546Sopenharmony_ci 29bf215546Sopenharmony_ci#include "vk_util.h" 30bf215546Sopenharmony_ci 31bf215546Sopenharmony_cistatic void 32bf215546Sopenharmony_ciradv_render_pass_add_subpass_dep(struct radv_render_pass *pass, const VkSubpassDependency2 *dep) 33bf215546Sopenharmony_ci{ 34bf215546Sopenharmony_ci uint32_t src = dep->srcSubpass; 35bf215546Sopenharmony_ci uint32_t dst = dep->dstSubpass; 36bf215546Sopenharmony_ci 37bf215546Sopenharmony_ci /* Ignore subpass self-dependencies as they allow the app to call 38bf215546Sopenharmony_ci * vkCmdPipelineBarrier() inside the render pass and the driver should 39bf215546Sopenharmony_ci * only do the barrier when called, not when starting the render pass. 40bf215546Sopenharmony_ci */ 41bf215546Sopenharmony_ci if (src == dst) 42bf215546Sopenharmony_ci return; 43bf215546Sopenharmony_ci 44bf215546Sopenharmony_ci /* Accumulate all ingoing external dependencies to the first subpass. */ 45bf215546Sopenharmony_ci if (src == VK_SUBPASS_EXTERNAL) 46bf215546Sopenharmony_ci dst = 0; 47bf215546Sopenharmony_ci 48bf215546Sopenharmony_ci 49bf215546Sopenharmony_ci /* From the Vulkan 1.2.195 spec: 50bf215546Sopenharmony_ci * 51bf215546Sopenharmony_ci * "If an instance of VkMemoryBarrier2 is included in the pNext chain, srcStageMask, 52bf215546Sopenharmony_ci * dstStageMask, srcAccessMask, and dstAccessMask parameters are ignored. The synchronization 53bf215546Sopenharmony_ci * and access scopes instead are defined by the parameters of VkMemoryBarrier2." 54bf215546Sopenharmony_ci */ 55bf215546Sopenharmony_ci const VkMemoryBarrier2 *barrier = 56bf215546Sopenharmony_ci vk_find_struct_const(dep->pNext, MEMORY_BARRIER_2); 57bf215546Sopenharmony_ci VkPipelineStageFlags2 src_stage_mask = barrier ? barrier->srcStageMask : dep->srcStageMask; 58bf215546Sopenharmony_ci VkAccessFlags2 src_access_mask = barrier ? barrier->srcAccessMask : dep->srcAccessMask; 59bf215546Sopenharmony_ci VkPipelineStageFlags2 dst_stage_mask = barrier ? barrier->dstStageMask : dep->dstStageMask; 60bf215546Sopenharmony_ci VkAccessFlags2 dst_access_mask = barrier ? barrier->dstAccessMask : dep->dstAccessMask; 61bf215546Sopenharmony_ci 62bf215546Sopenharmony_ci if (dst == VK_SUBPASS_EXTERNAL) { 63bf215546Sopenharmony_ci if (dst_stage_mask != VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) { 64bf215546Sopenharmony_ci pass->end_barrier.src_stage_mask |= src_stage_mask; 65bf215546Sopenharmony_ci pass->end_barrier.dst_stage_mask |= dst_stage_mask; 66bf215546Sopenharmony_ci } 67bf215546Sopenharmony_ci pass->end_barrier.src_access_mask |= src_access_mask; 68bf215546Sopenharmony_ci pass->end_barrier.dst_access_mask |= dst_access_mask; 69bf215546Sopenharmony_ci } else { 70bf215546Sopenharmony_ci if (dst_stage_mask != VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT) { 71bf215546Sopenharmony_ci pass->subpasses[dst].start_barrier.src_stage_mask |= src_stage_mask; 72bf215546Sopenharmony_ci pass->subpasses[dst].start_barrier.dst_stage_mask |= dst_stage_mask; 73bf215546Sopenharmony_ci } 74bf215546Sopenharmony_ci pass->subpasses[dst].start_barrier.src_access_mask |= src_access_mask; 75bf215546Sopenharmony_ci pass->subpasses[dst].start_barrier.dst_access_mask |= dst_access_mask; 76bf215546Sopenharmony_ci } 77bf215546Sopenharmony_ci} 78bf215546Sopenharmony_ci 79bf215546Sopenharmony_cistatic void 80bf215546Sopenharmony_ciradv_render_pass_add_implicit_deps(struct radv_render_pass *pass) 81bf215546Sopenharmony_ci{ 82bf215546Sopenharmony_ci /* From the Vulkan 1.0.39 spec: 83bf215546Sopenharmony_ci * 84bf215546Sopenharmony_ci * If there is no subpass dependency from VK_SUBPASS_EXTERNAL to the 85bf215546Sopenharmony_ci * first subpass that uses an attachment, then an implicit subpass 86bf215546Sopenharmony_ci * dependency exists from VK_SUBPASS_EXTERNAL to the first subpass it is 87bf215546Sopenharmony_ci * used in. The implicit subpass dependency only exists if there 88bf215546Sopenharmony_ci * exists an automatic layout transition away from initialLayout. 89bf215546Sopenharmony_ci * The subpass dependency operates as if defined with the 90bf215546Sopenharmony_ci * following parameters: 91bf215546Sopenharmony_ci * 92bf215546Sopenharmony_ci * VkSubpassDependency implicitDependency = { 93bf215546Sopenharmony_ci * .srcSubpass = VK_SUBPASS_EXTERNAL; 94bf215546Sopenharmony_ci * .dstSubpass = firstSubpass; // First subpass attachment is used in 95bf215546Sopenharmony_ci * .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT; 96bf215546Sopenharmony_ci * .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 97bf215546Sopenharmony_ci * .srcAccessMask = 0; 98bf215546Sopenharmony_ci * .dstAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 99bf215546Sopenharmony_ci * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 100bf215546Sopenharmony_ci * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 101bf215546Sopenharmony_ci * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 102bf215546Sopenharmony_ci * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 103bf215546Sopenharmony_ci * .dependencyFlags = 0; 104bf215546Sopenharmony_ci * }; 105bf215546Sopenharmony_ci * 106bf215546Sopenharmony_ci * Similarly, if there is no subpass dependency from the last subpass 107bf215546Sopenharmony_ci * that uses an attachment to VK_SUBPASS_EXTERNAL, then an implicit 108bf215546Sopenharmony_ci * subpass dependency exists from the last subpass it is used in to 109bf215546Sopenharmony_ci * VK_SUBPASS_EXTERNAL. The implicit subpass dependency only exists 110bf215546Sopenharmony_ci * if there exists an automatic layout transition into finalLayout. 111bf215546Sopenharmony_ci * The subpass dependency operates as if defined with the following 112bf215546Sopenharmony_ci * parameters: 113bf215546Sopenharmony_ci * 114bf215546Sopenharmony_ci * VkSubpassDependency implicitDependency = { 115bf215546Sopenharmony_ci * .srcSubpass = lastSubpass; // Last subpass attachment is used in 116bf215546Sopenharmony_ci * .dstSubpass = VK_SUBPASS_EXTERNAL; 117bf215546Sopenharmony_ci * .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT; 118bf215546Sopenharmony_ci * .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT; 119bf215546Sopenharmony_ci * .srcAccessMask = VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | 120bf215546Sopenharmony_ci * VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 121bf215546Sopenharmony_ci * VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | 122bf215546Sopenharmony_ci * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 123bf215546Sopenharmony_ci * VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; 124bf215546Sopenharmony_ci * .dstAccessMask = 0; 125bf215546Sopenharmony_ci * .dependencyFlags = 0; 126bf215546Sopenharmony_ci * }; 127bf215546Sopenharmony_ci */ 128bf215546Sopenharmony_ci for (uint32_t i = 0; i < pass->subpass_count; i++) { 129bf215546Sopenharmony_ci struct radv_subpass *subpass = &pass->subpasses[i]; 130bf215546Sopenharmony_ci bool add_ingoing_dep = false, add_outgoing_dep = false; 131bf215546Sopenharmony_ci 132bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->attachment_count; j++) { 133bf215546Sopenharmony_ci struct radv_subpass_attachment *subpass_att = &subpass->attachments[j]; 134bf215546Sopenharmony_ci if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) 135bf215546Sopenharmony_ci continue; 136bf215546Sopenharmony_ci 137bf215546Sopenharmony_ci struct radv_render_pass_attachment *pass_att = &pass->attachments[subpass_att->attachment]; 138bf215546Sopenharmony_ci uint32_t initial_layout = pass_att->initial_layout; 139bf215546Sopenharmony_ci uint32_t stencil_initial_layout = pass_att->stencil_initial_layout; 140bf215546Sopenharmony_ci uint32_t final_layout = pass_att->final_layout; 141bf215546Sopenharmony_ci uint32_t stencil_final_layout = pass_att->stencil_final_layout; 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci /* The implicit subpass dependency only exists if 144bf215546Sopenharmony_ci * there exists an automatic layout transition away 145bf215546Sopenharmony_ci * from initialLayout. 146bf215546Sopenharmony_ci */ 147bf215546Sopenharmony_ci if (pass_att->first_subpass_idx == i && !subpass->has_ingoing_dep && 148bf215546Sopenharmony_ci ((subpass_att->layout != initial_layout) || 149bf215546Sopenharmony_ci (subpass_att->stencil_layout != stencil_initial_layout))) { 150bf215546Sopenharmony_ci add_ingoing_dep = true; 151bf215546Sopenharmony_ci } 152bf215546Sopenharmony_ci 153bf215546Sopenharmony_ci /* The implicit subpass dependency only exists if 154bf215546Sopenharmony_ci * there exists an automatic layout transition into 155bf215546Sopenharmony_ci * finalLayout. 156bf215546Sopenharmony_ci */ 157bf215546Sopenharmony_ci if (pass_att->last_subpass_idx == i && !subpass->has_outgoing_dep && 158bf215546Sopenharmony_ci ((subpass_att->layout != final_layout) || 159bf215546Sopenharmony_ci (subpass_att->stencil_layout != stencil_final_layout))) { 160bf215546Sopenharmony_ci add_outgoing_dep = true; 161bf215546Sopenharmony_ci } 162bf215546Sopenharmony_ci } 163bf215546Sopenharmony_ci 164bf215546Sopenharmony_ci if (add_ingoing_dep) { 165bf215546Sopenharmony_ci const VkSubpassDependency2 implicit_ingoing_dep = { 166bf215546Sopenharmony_ci .srcSubpass = VK_SUBPASS_EXTERNAL, 167bf215546Sopenharmony_ci .dstSubpass = i, /* first subpass attachment is used in */ 168bf215546Sopenharmony_ci .srcStageMask = VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, 169bf215546Sopenharmony_ci .dstStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 170bf215546Sopenharmony_ci .srcAccessMask = 0, 171bf215546Sopenharmony_ci .dstAccessMask = 172bf215546Sopenharmony_ci VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 173bf215546Sopenharmony_ci VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 174bf215546Sopenharmony_ci VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 175bf215546Sopenharmony_ci .dependencyFlags = 0, 176bf215546Sopenharmony_ci }; 177bf215546Sopenharmony_ci 178bf215546Sopenharmony_ci radv_render_pass_add_subpass_dep(pass, &implicit_ingoing_dep); 179bf215546Sopenharmony_ci } 180bf215546Sopenharmony_ci 181bf215546Sopenharmony_ci if (add_outgoing_dep) { 182bf215546Sopenharmony_ci const VkSubpassDependency2 implicit_outgoing_dep = { 183bf215546Sopenharmony_ci .srcSubpass = i, /* last subpass attachment is used in */ 184bf215546Sopenharmony_ci .dstSubpass = VK_SUBPASS_EXTERNAL, 185bf215546Sopenharmony_ci .srcStageMask = VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 186bf215546Sopenharmony_ci .dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, 187bf215546Sopenharmony_ci .srcAccessMask = 188bf215546Sopenharmony_ci VK_ACCESS_INPUT_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | 189bf215546Sopenharmony_ci VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | 190bf215546Sopenharmony_ci VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, 191bf215546Sopenharmony_ci .dstAccessMask = 0, 192bf215546Sopenharmony_ci .dependencyFlags = 0, 193bf215546Sopenharmony_ci }; 194bf215546Sopenharmony_ci 195bf215546Sopenharmony_ci radv_render_pass_add_subpass_dep(pass, &implicit_outgoing_dep); 196bf215546Sopenharmony_ci } 197bf215546Sopenharmony_ci } 198bf215546Sopenharmony_ci} 199bf215546Sopenharmony_ci 200bf215546Sopenharmony_cistatic void 201bf215546Sopenharmony_ciradv_render_pass_compile(struct radv_render_pass *pass) 202bf215546Sopenharmony_ci{ 203bf215546Sopenharmony_ci for (uint32_t i = 0; i < pass->subpass_count; i++) { 204bf215546Sopenharmony_ci struct radv_subpass *subpass = &pass->subpasses[i]; 205bf215546Sopenharmony_ci 206bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->attachment_count; j++) { 207bf215546Sopenharmony_ci struct radv_subpass_attachment *subpass_att = &subpass->attachments[j]; 208bf215546Sopenharmony_ci if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) 209bf215546Sopenharmony_ci continue; 210bf215546Sopenharmony_ci 211bf215546Sopenharmony_ci struct radv_render_pass_attachment *pass_att = &pass->attachments[subpass_att->attachment]; 212bf215546Sopenharmony_ci 213bf215546Sopenharmony_ci pass_att->first_subpass_idx = VK_SUBPASS_EXTERNAL; 214bf215546Sopenharmony_ci pass_att->last_subpass_idx = VK_SUBPASS_EXTERNAL; 215bf215546Sopenharmony_ci } 216bf215546Sopenharmony_ci } 217bf215546Sopenharmony_ci 218bf215546Sopenharmony_ci for (uint32_t i = 0; i < pass->subpass_count; i++) { 219bf215546Sopenharmony_ci struct radv_subpass *subpass = &pass->subpasses[i]; 220bf215546Sopenharmony_ci uint32_t color_sample_count = 1, depth_sample_count = 1; 221bf215546Sopenharmony_ci 222bf215546Sopenharmony_ci /* We don't allow depth_stencil_attachment to be non-NULL and 223bf215546Sopenharmony_ci * be VK_ATTACHMENT_UNUSED. This way something can just check 224bf215546Sopenharmony_ci * for NULL and be guaranteed that they have a valid 225bf215546Sopenharmony_ci * attachment. 226bf215546Sopenharmony_ci */ 227bf215546Sopenharmony_ci if (subpass->depth_stencil_attachment && 228bf215546Sopenharmony_ci subpass->depth_stencil_attachment->attachment == VK_ATTACHMENT_UNUSED) 229bf215546Sopenharmony_ci subpass->depth_stencil_attachment = NULL; 230bf215546Sopenharmony_ci 231bf215546Sopenharmony_ci if (subpass->ds_resolve_attachment && 232bf215546Sopenharmony_ci subpass->ds_resolve_attachment->attachment == VK_ATTACHMENT_UNUSED) 233bf215546Sopenharmony_ci subpass->ds_resolve_attachment = NULL; 234bf215546Sopenharmony_ci 235bf215546Sopenharmony_ci if (subpass->vrs_attachment && subpass->vrs_attachment->attachment == VK_ATTACHMENT_UNUSED) 236bf215546Sopenharmony_ci subpass->vrs_attachment = NULL; 237bf215546Sopenharmony_ci 238bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->attachment_count; j++) { 239bf215546Sopenharmony_ci struct radv_subpass_attachment *subpass_att = &subpass->attachments[j]; 240bf215546Sopenharmony_ci if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) 241bf215546Sopenharmony_ci continue; 242bf215546Sopenharmony_ci 243bf215546Sopenharmony_ci struct radv_render_pass_attachment *pass_att = &pass->attachments[subpass_att->attachment]; 244bf215546Sopenharmony_ci 245bf215546Sopenharmony_ci if (i < pass_att->first_subpass_idx) 246bf215546Sopenharmony_ci pass_att->first_subpass_idx = i; 247bf215546Sopenharmony_ci pass_att->last_subpass_idx = i; 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci 250bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->color_count; j++) { 251bf215546Sopenharmony_ci struct radv_subpass_attachment *subpass_att = &subpass->color_attachments[j]; 252bf215546Sopenharmony_ci if (subpass_att->attachment == VK_ATTACHMENT_UNUSED) 253bf215546Sopenharmony_ci continue; 254bf215546Sopenharmony_ci 255bf215546Sopenharmony_ci 256bf215546Sopenharmony_ci struct radv_render_pass_attachment *pass_att = &pass->attachments[subpass_att->attachment]; 257bf215546Sopenharmony_ci 258bf215546Sopenharmony_ci color_sample_count = pass_att->samples; 259bf215546Sopenharmony_ci } 260bf215546Sopenharmony_ci 261bf215546Sopenharmony_ci if (subpass->depth_stencil_attachment) { 262bf215546Sopenharmony_ci const uint32_t a = subpass->depth_stencil_attachment->attachment; 263bf215546Sopenharmony_ci struct radv_render_pass_attachment *pass_att = &pass->attachments[a]; 264bf215546Sopenharmony_ci depth_sample_count = pass_att->samples; 265bf215546Sopenharmony_ci } 266bf215546Sopenharmony_ci 267bf215546Sopenharmony_ci subpass->max_sample_count = MAX2(color_sample_count, depth_sample_count); 268bf215546Sopenharmony_ci subpass->color_sample_count = color_sample_count; 269bf215546Sopenharmony_ci subpass->depth_sample_count = depth_sample_count; 270bf215546Sopenharmony_ci 271bf215546Sopenharmony_ci /* We have to handle resolve attachments specially */ 272bf215546Sopenharmony_ci subpass->has_color_resolve = false; 273bf215546Sopenharmony_ci if (subpass->resolve_attachments) { 274bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->color_count; j++) { 275bf215546Sopenharmony_ci struct radv_subpass_attachment *resolve_att = &subpass->resolve_attachments[j]; 276bf215546Sopenharmony_ci 277bf215546Sopenharmony_ci if (resolve_att->attachment == VK_ATTACHMENT_UNUSED) 278bf215546Sopenharmony_ci continue; 279bf215546Sopenharmony_ci 280bf215546Sopenharmony_ci subpass->has_color_resolve = true; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci for (uint32_t j = 0; j < subpass->input_count; ++j) { 285bf215546Sopenharmony_ci if (subpass->input_attachments[j].attachment == VK_ATTACHMENT_UNUSED) 286bf215546Sopenharmony_ci continue; 287bf215546Sopenharmony_ci 288bf215546Sopenharmony_ci for (uint32_t k = 0; k < subpass->color_count; ++k) { 289bf215546Sopenharmony_ci if (subpass->color_attachments[k].attachment == 290bf215546Sopenharmony_ci subpass->input_attachments[j].attachment) { 291bf215546Sopenharmony_ci subpass->input_attachments[j].in_render_loop = true; 292bf215546Sopenharmony_ci subpass->color_attachments[k].in_render_loop = true; 293bf215546Sopenharmony_ci } 294bf215546Sopenharmony_ci } 295bf215546Sopenharmony_ci 296bf215546Sopenharmony_ci if (subpass->depth_stencil_attachment && subpass->depth_stencil_attachment->attachment == 297bf215546Sopenharmony_ci subpass->input_attachments[j].attachment) { 298bf215546Sopenharmony_ci subpass->input_attachments[j].in_render_loop = true; 299bf215546Sopenharmony_ci subpass->depth_stencil_attachment->in_render_loop = true; 300bf215546Sopenharmony_ci } 301bf215546Sopenharmony_ci } 302bf215546Sopenharmony_ci } 303bf215546Sopenharmony_ci} 304bf215546Sopenharmony_ci 305bf215546Sopenharmony_cistatic void 306bf215546Sopenharmony_ciradv_destroy_render_pass(struct radv_device *device, const VkAllocationCallbacks *pAllocator, 307bf215546Sopenharmony_ci struct radv_render_pass *pass) 308bf215546Sopenharmony_ci{ 309bf215546Sopenharmony_ci vk_object_base_finish(&pass->base); 310bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments); 311bf215546Sopenharmony_ci vk_free2(&device->vk.alloc, pAllocator, pass); 312bf215546Sopenharmony_ci} 313bf215546Sopenharmony_ci 314bf215546Sopenharmony_cistatic unsigned 315bf215546Sopenharmony_ciradv_num_subpass_attachments2(const VkSubpassDescription2 *desc) 316bf215546Sopenharmony_ci{ 317bf215546Sopenharmony_ci const VkSubpassDescriptionDepthStencilResolve *ds_resolve = 318bf215546Sopenharmony_ci vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE); 319bf215546Sopenharmony_ci const VkFragmentShadingRateAttachmentInfoKHR *vrs = 320bf215546Sopenharmony_ci vk_find_struct_const(desc->pNext, FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); 321bf215546Sopenharmony_ci 322bf215546Sopenharmony_ci return desc->inputAttachmentCount + desc->colorAttachmentCount + 323bf215546Sopenharmony_ci (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 324bf215546Sopenharmony_ci (desc->pDepthStencilAttachment != NULL) + 325bf215546Sopenharmony_ci (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) + 326bf215546Sopenharmony_ci (vrs && vrs->pFragmentShadingRateAttachment); 327bf215546Sopenharmony_ci} 328bf215546Sopenharmony_ci 329bf215546Sopenharmony_ciVKAPI_ATTR VkResult VKAPI_CALL 330bf215546Sopenharmony_ciradv_CreateRenderPass2(VkDevice _device, const VkRenderPassCreateInfo2 *pCreateInfo, 331bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator, VkRenderPass *pRenderPass) 332bf215546Sopenharmony_ci{ 333bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 334bf215546Sopenharmony_ci struct radv_render_pass *pass; 335bf215546Sopenharmony_ci size_t size; 336bf215546Sopenharmony_ci size_t attachments_offset; 337bf215546Sopenharmony_ci 338bf215546Sopenharmony_ci assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2); 339bf215546Sopenharmony_ci 340bf215546Sopenharmony_ci size = sizeof(*pass); 341bf215546Sopenharmony_ci size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]); 342bf215546Sopenharmony_ci attachments_offset = size; 343bf215546Sopenharmony_ci size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]); 344bf215546Sopenharmony_ci 345bf215546Sopenharmony_ci pass = vk_alloc2(&device->vk.alloc, pAllocator, size, 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 346bf215546Sopenharmony_ci if (pass == NULL) 347bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 348bf215546Sopenharmony_ci 349bf215546Sopenharmony_ci memset(pass, 0, size); 350bf215546Sopenharmony_ci 351bf215546Sopenharmony_ci vk_object_base_init(&device->vk, &pass->base, VK_OBJECT_TYPE_RENDER_PASS); 352bf215546Sopenharmony_ci 353bf215546Sopenharmony_ci pass->attachment_count = pCreateInfo->attachmentCount; 354bf215546Sopenharmony_ci pass->subpass_count = pCreateInfo->subpassCount; 355bf215546Sopenharmony_ci pass->attachments = (struct radv_render_pass_attachment *)((uint8_t *)pass + attachments_offset); 356bf215546Sopenharmony_ci 357bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 358bf215546Sopenharmony_ci struct radv_render_pass_attachment *att = &pass->attachments[i]; 359bf215546Sopenharmony_ci 360bf215546Sopenharmony_ci att->format = pCreateInfo->pAttachments[i].format; 361bf215546Sopenharmony_ci att->samples = pCreateInfo->pAttachments[i].samples; 362bf215546Sopenharmony_ci att->load_op = pCreateInfo->pAttachments[i].loadOp; 363bf215546Sopenharmony_ci att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; 364bf215546Sopenharmony_ci att->initial_layout = pCreateInfo->pAttachments[i].initialLayout; 365bf215546Sopenharmony_ci att->final_layout = pCreateInfo->pAttachments[i].finalLayout; 366bf215546Sopenharmony_ci att->stencil_initial_layout = vk_att_desc_stencil_layout(&pCreateInfo->pAttachments[i], false); 367bf215546Sopenharmony_ci att->stencil_final_layout = vk_att_desc_stencil_layout(&pCreateInfo->pAttachments[i], true); 368bf215546Sopenharmony_ci // att->store_op = pCreateInfo->pAttachments[i].storeOp; 369bf215546Sopenharmony_ci // att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; 370bf215546Sopenharmony_ci } 371bf215546Sopenharmony_ci uint32_t subpass_attachment_count = 0; 372bf215546Sopenharmony_ci struct radv_subpass_attachment *p; 373bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 374bf215546Sopenharmony_ci subpass_attachment_count += radv_num_subpass_attachments2(&pCreateInfo->pSubpasses[i]); 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci 377bf215546Sopenharmony_ci if (subpass_attachment_count) { 378bf215546Sopenharmony_ci pass->subpass_attachments = 379bf215546Sopenharmony_ci vk_alloc2(&device->vk.alloc, pAllocator, 380bf215546Sopenharmony_ci subpass_attachment_count * sizeof(struct radv_subpass_attachment), 8, 381bf215546Sopenharmony_ci VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 382bf215546Sopenharmony_ci if (pass->subpass_attachments == NULL) { 383bf215546Sopenharmony_ci radv_destroy_render_pass(device, pAllocator, pass); 384bf215546Sopenharmony_ci return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 385bf215546Sopenharmony_ci } 386bf215546Sopenharmony_ci } else 387bf215546Sopenharmony_ci pass->subpass_attachments = NULL; 388bf215546Sopenharmony_ci 389bf215546Sopenharmony_ci p = pass->subpass_attachments; 390bf215546Sopenharmony_ci for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 391bf215546Sopenharmony_ci const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; 392bf215546Sopenharmony_ci struct radv_subpass *subpass = &pass->subpasses[i]; 393bf215546Sopenharmony_ci 394bf215546Sopenharmony_ci subpass->input_count = desc->inputAttachmentCount; 395bf215546Sopenharmony_ci subpass->color_count = desc->colorAttachmentCount; 396bf215546Sopenharmony_ci subpass->attachment_count = radv_num_subpass_attachments2(desc); 397bf215546Sopenharmony_ci subpass->attachments = p; 398bf215546Sopenharmony_ci subpass->view_mask = desc->viewMask; 399bf215546Sopenharmony_ci 400bf215546Sopenharmony_ci if (desc->inputAttachmentCount > 0) { 401bf215546Sopenharmony_ci subpass->input_attachments = p; 402bf215546Sopenharmony_ci p += desc->inputAttachmentCount; 403bf215546Sopenharmony_ci 404bf215546Sopenharmony_ci for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { 405bf215546Sopenharmony_ci subpass->input_attachments[j] = (struct radv_subpass_attachment){ 406bf215546Sopenharmony_ci .attachment = desc->pInputAttachments[j].attachment, 407bf215546Sopenharmony_ci .layout = desc->pInputAttachments[j].layout, 408bf215546Sopenharmony_ci .stencil_layout = vk_att_ref_stencil_layout(&desc->pInputAttachments[j], 409bf215546Sopenharmony_ci pCreateInfo->pAttachments), 410bf215546Sopenharmony_ci }; 411bf215546Sopenharmony_ci } 412bf215546Sopenharmony_ci } 413bf215546Sopenharmony_ci 414bf215546Sopenharmony_ci if (desc->colorAttachmentCount > 0) { 415bf215546Sopenharmony_ci subpass->color_attachments = p; 416bf215546Sopenharmony_ci p += desc->colorAttachmentCount; 417bf215546Sopenharmony_ci 418bf215546Sopenharmony_ci for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 419bf215546Sopenharmony_ci subpass->color_attachments[j] = (struct radv_subpass_attachment){ 420bf215546Sopenharmony_ci .attachment = desc->pColorAttachments[j].attachment, 421bf215546Sopenharmony_ci .layout = desc->pColorAttachments[j].layout, 422bf215546Sopenharmony_ci }; 423bf215546Sopenharmony_ci } 424bf215546Sopenharmony_ci } 425bf215546Sopenharmony_ci 426bf215546Sopenharmony_ci if (desc->pResolveAttachments) { 427bf215546Sopenharmony_ci subpass->resolve_attachments = p; 428bf215546Sopenharmony_ci p += desc->colorAttachmentCount; 429bf215546Sopenharmony_ci 430bf215546Sopenharmony_ci for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 431bf215546Sopenharmony_ci subpass->resolve_attachments[j] = (struct radv_subpass_attachment){ 432bf215546Sopenharmony_ci .attachment = desc->pResolveAttachments[j].attachment, 433bf215546Sopenharmony_ci .layout = desc->pResolveAttachments[j].layout, 434bf215546Sopenharmony_ci }; 435bf215546Sopenharmony_ci } 436bf215546Sopenharmony_ci } 437bf215546Sopenharmony_ci 438bf215546Sopenharmony_ci if (desc->pDepthStencilAttachment) { 439bf215546Sopenharmony_ci subpass->depth_stencil_attachment = p++; 440bf215546Sopenharmony_ci 441bf215546Sopenharmony_ci *subpass->depth_stencil_attachment = (struct radv_subpass_attachment){ 442bf215546Sopenharmony_ci .attachment = desc->pDepthStencilAttachment->attachment, 443bf215546Sopenharmony_ci .layout = desc->pDepthStencilAttachment->layout, 444bf215546Sopenharmony_ci .stencil_layout = vk_att_ref_stencil_layout(desc->pDepthStencilAttachment, 445bf215546Sopenharmony_ci pCreateInfo->pAttachments), 446bf215546Sopenharmony_ci }; 447bf215546Sopenharmony_ci } 448bf215546Sopenharmony_ci 449bf215546Sopenharmony_ci const VkSubpassDescriptionDepthStencilResolve *ds_resolve = 450bf215546Sopenharmony_ci vk_find_struct_const(desc->pNext, SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE); 451bf215546Sopenharmony_ci 452bf215546Sopenharmony_ci if (ds_resolve && ds_resolve->pDepthStencilResolveAttachment) { 453bf215546Sopenharmony_ci subpass->ds_resolve_attachment = p++; 454bf215546Sopenharmony_ci 455bf215546Sopenharmony_ci *subpass->ds_resolve_attachment = (struct radv_subpass_attachment){ 456bf215546Sopenharmony_ci .attachment = ds_resolve->pDepthStencilResolveAttachment->attachment, 457bf215546Sopenharmony_ci .layout = ds_resolve->pDepthStencilResolveAttachment->layout, 458bf215546Sopenharmony_ci .stencil_layout = vk_att_ref_stencil_layout(ds_resolve->pDepthStencilResolveAttachment, 459bf215546Sopenharmony_ci pCreateInfo->pAttachments), 460bf215546Sopenharmony_ci }; 461bf215546Sopenharmony_ci 462bf215546Sopenharmony_ci subpass->depth_resolve_mode = ds_resolve->depthResolveMode; 463bf215546Sopenharmony_ci subpass->stencil_resolve_mode = ds_resolve->stencilResolveMode; 464bf215546Sopenharmony_ci } 465bf215546Sopenharmony_ci 466bf215546Sopenharmony_ci const VkFragmentShadingRateAttachmentInfoKHR *vrs = 467bf215546Sopenharmony_ci vk_find_struct_const(desc->pNext, FRAGMENT_SHADING_RATE_ATTACHMENT_INFO_KHR); 468bf215546Sopenharmony_ci 469bf215546Sopenharmony_ci if (vrs && vrs->pFragmentShadingRateAttachment) { 470bf215546Sopenharmony_ci subpass->vrs_attachment = p++; 471bf215546Sopenharmony_ci 472bf215546Sopenharmony_ci *subpass->vrs_attachment = (struct radv_subpass_attachment){ 473bf215546Sopenharmony_ci .attachment = vrs->pFragmentShadingRateAttachment->attachment, 474bf215546Sopenharmony_ci .layout = vrs->pFragmentShadingRateAttachment->layout, 475bf215546Sopenharmony_ci }; 476bf215546Sopenharmony_ci } 477bf215546Sopenharmony_ci } 478bf215546Sopenharmony_ci 479bf215546Sopenharmony_ci for (unsigned i = 0; i < pCreateInfo->dependencyCount; ++i) { 480bf215546Sopenharmony_ci const VkSubpassDependency2 *dep = &pCreateInfo->pDependencies[i]; 481bf215546Sopenharmony_ci 482bf215546Sopenharmony_ci radv_render_pass_add_subpass_dep(pass, &pCreateInfo->pDependencies[i]); 483bf215546Sopenharmony_ci 484bf215546Sopenharmony_ci /* Determine if the subpass has explicit dependencies from/to 485bf215546Sopenharmony_ci * VK_SUBPASS_EXTERNAL. 486bf215546Sopenharmony_ci */ 487bf215546Sopenharmony_ci if (dep->srcSubpass == VK_SUBPASS_EXTERNAL && dep->dstSubpass != VK_SUBPASS_EXTERNAL) { 488bf215546Sopenharmony_ci pass->subpasses[dep->dstSubpass].has_ingoing_dep = true; 489bf215546Sopenharmony_ci } 490bf215546Sopenharmony_ci 491bf215546Sopenharmony_ci if (dep->dstSubpass == VK_SUBPASS_EXTERNAL && dep->srcSubpass != VK_SUBPASS_EXTERNAL) { 492bf215546Sopenharmony_ci pass->subpasses[dep->srcSubpass].has_outgoing_dep = true; 493bf215546Sopenharmony_ci } 494bf215546Sopenharmony_ci } 495bf215546Sopenharmony_ci 496bf215546Sopenharmony_ci radv_render_pass_compile(pass); 497bf215546Sopenharmony_ci 498bf215546Sopenharmony_ci radv_render_pass_add_implicit_deps(pass); 499bf215546Sopenharmony_ci 500bf215546Sopenharmony_ci *pRenderPass = radv_render_pass_to_handle(pass); 501bf215546Sopenharmony_ci 502bf215546Sopenharmony_ci return VK_SUCCESS; 503bf215546Sopenharmony_ci} 504bf215546Sopenharmony_ci 505bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 506bf215546Sopenharmony_ciradv_DestroyRenderPass(VkDevice _device, VkRenderPass _pass, 507bf215546Sopenharmony_ci const VkAllocationCallbacks *pAllocator) 508bf215546Sopenharmony_ci{ 509bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_device, device, _device); 510bf215546Sopenharmony_ci RADV_FROM_HANDLE(radv_render_pass, pass, _pass); 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci if (!_pass) 513bf215546Sopenharmony_ci return; 514bf215546Sopenharmony_ci 515bf215546Sopenharmony_ci radv_destroy_render_pass(device, pAllocator, pass); 516bf215546Sopenharmony_ci} 517bf215546Sopenharmony_ci 518bf215546Sopenharmony_ciVKAPI_ATTR void VKAPI_CALL 519bf215546Sopenharmony_ciradv_GetRenderAreaGranularity(VkDevice device, VkRenderPass renderPass, VkExtent2D *pGranularity) 520bf215546Sopenharmony_ci{ 521bf215546Sopenharmony_ci pGranularity->width = 1; 522bf215546Sopenharmony_ci pGranularity->height = 1; 523bf215546Sopenharmony_ci} 524