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