1/* 2 * Copyright © 2021 Collabora Ltd. 3 * 4 * Derived from tu_pass.c which is: 5 * Copyright © 2016 Red Hat. 6 * Copyright © 2016 Bas Nieuwenhuizen 7 * Copyright © 2015 Intel Corporation 8 * 9 * Permission is hereby granted, free of charge, to any person obtaining a 10 * copy of this software and associated documentation files (the "Software"), 11 * to deal in the Software without restriction, including without limitation 12 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 13 * and/or sell copies of the Software, and to permit persons to whom the 14 * Software is furnished to do so, subject to the following conditions: 15 * 16 * The above copyright notice and this permission notice (including the next 17 * paragraph) shall be included in all copies or substantial portions of the 18 * Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 23 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 25 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 26 * DEALINGS IN THE SOFTWARE. 27 */ 28#include "panvk_private.h" 29 30#include "vk_format.h" 31#include "vk_util.h" 32 33VkResult 34panvk_CreateRenderPass2(VkDevice _device, 35 const VkRenderPassCreateInfo2 *pCreateInfo, 36 const VkAllocationCallbacks *pAllocator, 37 VkRenderPass *pRenderPass) 38{ 39 VK_FROM_HANDLE(panvk_device, device, _device); 40 struct panvk_render_pass *pass; 41 size_t size; 42 size_t attachments_offset; 43 VkRenderPassMultiviewCreateInfo *multiview_info = NULL; 44 45 assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2); 46 47 size = sizeof(*pass); 48 size += pCreateInfo->subpassCount * sizeof(pass->subpasses[0]); 49 attachments_offset = size; 50 size += pCreateInfo->attachmentCount * sizeof(pass->attachments[0]); 51 52 pass = vk_object_zalloc(&device->vk, pAllocator, size, 53 VK_OBJECT_TYPE_RENDER_PASS); 54 if (pass == NULL) 55 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 56 57 pass->attachment_count = pCreateInfo->attachmentCount; 58 pass->subpass_count = pCreateInfo->subpassCount; 59 pass->attachments = (void *) pass + attachments_offset; 60 61 vk_foreach_struct_const(ext, pCreateInfo->pNext) { 62 switch (ext->sType) { 63 case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: 64 multiview_info = (VkRenderPassMultiviewCreateInfo *) ext; 65 break; 66 default: 67 break; 68 } 69 } 70 71 for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 72 struct panvk_render_pass_attachment *att = &pass->attachments[i]; 73 74 att->format = vk_format_to_pipe_format(pCreateInfo->pAttachments[i].format); 75 att->samples = pCreateInfo->pAttachments[i].samples; 76 att->load_op = pCreateInfo->pAttachments[i].loadOp; 77 att->stencil_load_op = pCreateInfo->pAttachments[i].stencilLoadOp; 78 att->initial_layout = pCreateInfo->pAttachments[i].initialLayout; 79 att->final_layout = pCreateInfo->pAttachments[i].finalLayout; 80 att->store_op = pCreateInfo->pAttachments[i].storeOp; 81 att->stencil_store_op = pCreateInfo->pAttachments[i].stencilStoreOp; 82 att->first_used_in_subpass = ~0; 83 } 84 85 uint32_t subpass_attachment_count = 0; 86 struct panvk_subpass_attachment *p; 87 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 88 const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; 89 90 subpass_attachment_count += 91 desc->inputAttachmentCount + desc->colorAttachmentCount + 92 (desc->pResolveAttachments ? desc->colorAttachmentCount : 0) + 93 (desc->pDepthStencilAttachment != NULL); 94 } 95 96 if (subpass_attachment_count) { 97 pass->subpass_attachments = 98 vk_alloc2(&device->vk.alloc, pAllocator, 99 subpass_attachment_count * 100 sizeof(struct panvk_subpass_attachment), 101 8, VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); 102 if (pass->subpass_attachments == NULL) { 103 vk_object_free(&device->vk, pAllocator, pass); 104 return vk_error(device, VK_ERROR_OUT_OF_HOST_MEMORY); 105 } 106 } 107 108 p = pass->subpass_attachments; 109 for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 110 const VkSubpassDescription2 *desc = &pCreateInfo->pSubpasses[i]; 111 struct panvk_subpass *subpass = &pass->subpasses[i]; 112 113 subpass->input_count = desc->inputAttachmentCount; 114 subpass->color_count = desc->colorAttachmentCount; 115 if (multiview_info) 116 subpass->view_mask = multiview_info->pViewMasks[i]; 117 118 if (desc->inputAttachmentCount > 0) { 119 subpass->input_attachments = p; 120 p += desc->inputAttachmentCount; 121 122 for (uint32_t j = 0; j < desc->inputAttachmentCount; j++) { 123 subpass->input_attachments[j] = (struct panvk_subpass_attachment) { 124 .idx = desc->pInputAttachments[j].attachment, 125 .layout = desc->pInputAttachments[j].layout, 126 }; 127 if (desc->pInputAttachments[j].attachment != VK_ATTACHMENT_UNUSED) 128 pass->attachments[desc->pInputAttachments[j].attachment] 129 .view_mask |= subpass->view_mask; 130 } 131 } 132 133 if (desc->colorAttachmentCount > 0) { 134 subpass->color_attachments = p; 135 p += desc->colorAttachmentCount; 136 137 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 138 uint32_t idx = desc->pColorAttachments[j].attachment; 139 140 subpass->color_attachments[j] = (struct panvk_subpass_attachment) { 141 .idx = idx, 142 .layout = desc->pColorAttachments[j].layout, 143 }; 144 145 if (idx != VK_ATTACHMENT_UNUSED) { 146 pass->attachments[idx].view_mask |= subpass->view_mask; 147 if (pass->attachments[idx].first_used_in_subpass == ~0) { 148 pass->attachments[idx].first_used_in_subpass = i; 149 if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 150 subpass->color_attachments[j].clear = true; 151 else if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) 152 subpass->color_attachments[j].preload = true; 153 } else { 154 subpass->color_attachments[j].preload = true; 155 } 156 } 157 } 158 } 159 160 if (desc->pResolveAttachments) { 161 subpass->resolve_attachments = p; 162 p += desc->colorAttachmentCount; 163 164 for (uint32_t j = 0; j < desc->colorAttachmentCount; j++) { 165 uint32_t idx = desc->pResolveAttachments[j].attachment; 166 167 subpass->resolve_attachments[j] = (struct panvk_subpass_attachment) { 168 .idx = idx, 169 .layout = desc->pResolveAttachments[j].layout, 170 }; 171 172 if (idx != VK_ATTACHMENT_UNUSED) 173 pass->attachments[idx].view_mask |= subpass->view_mask; 174 } 175 } 176 177 unsigned idx = desc->pDepthStencilAttachment ? 178 desc->pDepthStencilAttachment->attachment : 179 VK_ATTACHMENT_UNUSED; 180 subpass->zs_attachment.idx = idx; 181 if (idx != VK_ATTACHMENT_UNUSED) { 182 subpass->zs_attachment.layout = desc->pDepthStencilAttachment->layout; 183 pass->attachments[idx].view_mask |= subpass->view_mask; 184 185 if (pass->attachments[idx].first_used_in_subpass == ~0) { 186 pass->attachments[idx].first_used_in_subpass = i; 187 if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_CLEAR) 188 subpass->zs_attachment.clear = true; 189 else if (pass->attachments[idx].load_op == VK_ATTACHMENT_LOAD_OP_LOAD) 190 subpass->zs_attachment.preload = true; 191 } else { 192 subpass->zs_attachment.preload = true; 193 } 194 } 195 } 196 197 *pRenderPass = panvk_render_pass_to_handle(pass); 198 return VK_SUCCESS; 199} 200 201void 202panvk_DestroyRenderPass(VkDevice _device, 203 VkRenderPass _pass, 204 const VkAllocationCallbacks *pAllocator) 205{ 206 VK_FROM_HANDLE(panvk_device, device, _device); 207 VK_FROM_HANDLE(panvk_render_pass, pass, _pass); 208 209 if (!pass) 210 return; 211 212 vk_free2(&device->vk.alloc, pAllocator, pass->subpass_attachments); 213 vk_object_free(&device->vk, pAllocator, pass); 214} 215 216void 217panvk_GetRenderAreaGranularity(VkDevice _device, 218 VkRenderPass renderPass, 219 VkExtent2D *pGranularity) 220{ 221 /* TODO: Return the actual tile size for the render pass? */ 222 *pGranularity = (VkExtent2D) { 1, 1 }; 223} 224