17ec681f3Smrg/* 27ec681f3Smrg * Copyright © 2020 Valve Corporation 37ec681f3Smrg * 47ec681f3Smrg * Permission is hereby granted, free of charge, to any person obtaining a 57ec681f3Smrg * copy of this software and associated documentation files (the "Software"), 67ec681f3Smrg * to deal in the Software without restriction, including without limitation 77ec681f3Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 87ec681f3Smrg * and/or sell copies of the Software, and to permit persons to whom the 97ec681f3Smrg * Software is furnished to do so, subject to the following conditions: 107ec681f3Smrg * 117ec681f3Smrg * The above copyright notice and this permission notice (including the next 127ec681f3Smrg * paragraph) shall be included in all copies or substantial portions of the 137ec681f3Smrg * Software. 147ec681f3Smrg * 157ec681f3Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 167ec681f3Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 177ec681f3Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 187ec681f3Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 197ec681f3Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 207ec681f3Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 217ec681f3Smrg * IN THE SOFTWARE. 227ec681f3Smrg */ 237ec681f3Smrg 247ec681f3Smrg#include "vk_alloc.h" 257ec681f3Smrg#include "vk_common_entrypoints.h" 267ec681f3Smrg#include "vk_device.h" 277ec681f3Smrg#include "vk_format.h" 287ec681f3Smrg#include "vk_util.h" 297ec681f3Smrg 307ec681f3Smrg#include "util/log.h" 317ec681f3Smrg 327ec681f3Smrgstatic void 337ec681f3Smrgtranslate_references(VkAttachmentReference2 **reference_ptr, 347ec681f3Smrg uint32_t reference_count, 357ec681f3Smrg const VkAttachmentReference *reference, 367ec681f3Smrg const VkRenderPassCreateInfo *pass_info, 377ec681f3Smrg bool is_input_attachment) 387ec681f3Smrg{ 397ec681f3Smrg VkAttachmentReference2 *reference2 = *reference_ptr; 407ec681f3Smrg *reference_ptr += reference_count; 417ec681f3Smrg for (uint32_t i = 0; i < reference_count; i++) { 427ec681f3Smrg reference2[i] = (VkAttachmentReference2) { 437ec681f3Smrg .sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2, 447ec681f3Smrg .pNext = NULL, 457ec681f3Smrg .attachment = reference[i].attachment, 467ec681f3Smrg .layout = reference[i].layout, 477ec681f3Smrg }; 487ec681f3Smrg 497ec681f3Smrg if (is_input_attachment && 507ec681f3Smrg reference2[i].attachment != VK_ATTACHMENT_UNUSED) { 517ec681f3Smrg assert(reference2[i].attachment < pass_info->attachmentCount); 527ec681f3Smrg const VkAttachmentDescription *att = 537ec681f3Smrg &pass_info->pAttachments[reference2[i].attachment]; 547ec681f3Smrg reference2[i].aspectMask = vk_format_aspects(att->format); 557ec681f3Smrg } 567ec681f3Smrg } 577ec681f3Smrg} 587ec681f3Smrg 597ec681f3SmrgVKAPI_ATTR VkResult VKAPI_CALL 607ec681f3Smrgvk_common_CreateRenderPass(VkDevice _device, 617ec681f3Smrg const VkRenderPassCreateInfo *pCreateInfo, 627ec681f3Smrg const VkAllocationCallbacks *pAllocator, 637ec681f3Smrg VkRenderPass *pRenderPass) 647ec681f3Smrg{ 657ec681f3Smrg VK_FROM_HANDLE(vk_device, device, _device); 667ec681f3Smrg 677ec681f3Smrg uint32_t reference_count = 0; 687ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 697ec681f3Smrg reference_count += pCreateInfo->pSubpasses[i].inputAttachmentCount; 707ec681f3Smrg reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount; 717ec681f3Smrg if (pCreateInfo->pSubpasses[i].pResolveAttachments) 727ec681f3Smrg reference_count += pCreateInfo->pSubpasses[i].colorAttachmentCount; 737ec681f3Smrg if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) 747ec681f3Smrg reference_count += 1; 757ec681f3Smrg } 767ec681f3Smrg 777ec681f3Smrg VK_MULTIALLOC(ma); 787ec681f3Smrg VK_MULTIALLOC_DECL(&ma, VkRenderPassCreateInfo2, create_info, 1); 797ec681f3Smrg VK_MULTIALLOC_DECL(&ma, VkSubpassDescription2, subpasses, 807ec681f3Smrg pCreateInfo->subpassCount); 817ec681f3Smrg VK_MULTIALLOC_DECL(&ma, VkAttachmentDescription2, attachments, 827ec681f3Smrg pCreateInfo->attachmentCount); 837ec681f3Smrg VK_MULTIALLOC_DECL(&ma, VkSubpassDependency2, dependencies, 847ec681f3Smrg pCreateInfo->dependencyCount); 857ec681f3Smrg VK_MULTIALLOC_DECL(&ma, VkAttachmentReference2, references, 867ec681f3Smrg reference_count); 877ec681f3Smrg if (!vk_multialloc_alloc2(&ma, &device->alloc, pAllocator, 887ec681f3Smrg VK_SYSTEM_ALLOCATION_SCOPE_COMMAND)) 897ec681f3Smrg return VK_ERROR_OUT_OF_HOST_MEMORY; 907ec681f3Smrg 917ec681f3Smrg VkAttachmentReference2 *reference_ptr = references; 927ec681f3Smrg 937ec681f3Smrg const VkRenderPassMultiviewCreateInfo *multiview_info = NULL; 947ec681f3Smrg const VkRenderPassInputAttachmentAspectCreateInfo *aspect_info = NULL; 957ec681f3Smrg vk_foreach_struct(ext, pCreateInfo->pNext) { 967ec681f3Smrg switch (ext->sType) { 977ec681f3Smrg case VK_STRUCTURE_TYPE_RENDER_PASS_INPUT_ATTACHMENT_ASPECT_CREATE_INFO: 987ec681f3Smrg aspect_info = (const VkRenderPassInputAttachmentAspectCreateInfo *)ext; 997ec681f3Smrg /* We don't care about this information */ 1007ec681f3Smrg break; 1017ec681f3Smrg 1027ec681f3Smrg case VK_STRUCTURE_TYPE_RENDER_PASS_MULTIVIEW_CREATE_INFO: 1037ec681f3Smrg multiview_info = (const VkRenderPassMultiviewCreateInfo*) ext; 1047ec681f3Smrg break; 1057ec681f3Smrg 1067ec681f3Smrg default: 1077ec681f3Smrg mesa_logd("%s: ignored VkStructureType %u\n", __func__, ext->sType); 1087ec681f3Smrg break; 1097ec681f3Smrg } 1107ec681f3Smrg } 1117ec681f3Smrg 1127ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->attachmentCount; i++) { 1137ec681f3Smrg attachments[i] = (VkAttachmentDescription2) { 1147ec681f3Smrg .sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2, 1157ec681f3Smrg .pNext = NULL, 1167ec681f3Smrg .flags = pCreateInfo->pAttachments[i].flags, 1177ec681f3Smrg .format = pCreateInfo->pAttachments[i].format, 1187ec681f3Smrg .samples = pCreateInfo->pAttachments[i].samples, 1197ec681f3Smrg .loadOp = pCreateInfo->pAttachments[i].loadOp, 1207ec681f3Smrg .storeOp = pCreateInfo->pAttachments[i].storeOp, 1217ec681f3Smrg .stencilLoadOp = pCreateInfo->pAttachments[i].stencilLoadOp, 1227ec681f3Smrg .stencilStoreOp = pCreateInfo->pAttachments[i].stencilStoreOp, 1237ec681f3Smrg .initialLayout = pCreateInfo->pAttachments[i].initialLayout, 1247ec681f3Smrg .finalLayout = pCreateInfo->pAttachments[i].finalLayout, 1257ec681f3Smrg }; 1267ec681f3Smrg } 1277ec681f3Smrg 1287ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->subpassCount; i++) { 1297ec681f3Smrg subpasses[i] = (VkSubpassDescription2) { 1307ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2, 1317ec681f3Smrg .pNext = NULL, 1327ec681f3Smrg .flags = pCreateInfo->pSubpasses[i].flags, 1337ec681f3Smrg .pipelineBindPoint = pCreateInfo->pSubpasses[i].pipelineBindPoint, 1347ec681f3Smrg .viewMask = 0, 1357ec681f3Smrg .inputAttachmentCount = pCreateInfo->pSubpasses[i].inputAttachmentCount, 1367ec681f3Smrg .colorAttachmentCount = pCreateInfo->pSubpasses[i].colorAttachmentCount, 1377ec681f3Smrg .preserveAttachmentCount = pCreateInfo->pSubpasses[i].preserveAttachmentCount, 1387ec681f3Smrg .pPreserveAttachments = pCreateInfo->pSubpasses[i].pPreserveAttachments, 1397ec681f3Smrg }; 1407ec681f3Smrg 1417ec681f3Smrg if (multiview_info && multiview_info->subpassCount) { 1427ec681f3Smrg assert(multiview_info->subpassCount == pCreateInfo->subpassCount); 1437ec681f3Smrg subpasses[i].viewMask = multiview_info->pViewMasks[i]; 1447ec681f3Smrg } 1457ec681f3Smrg 1467ec681f3Smrg subpasses[i].pInputAttachments = reference_ptr; 1477ec681f3Smrg translate_references(&reference_ptr, 1487ec681f3Smrg subpasses[i].inputAttachmentCount, 1497ec681f3Smrg pCreateInfo->pSubpasses[i].pInputAttachments, 1507ec681f3Smrg pCreateInfo, true); 1517ec681f3Smrg subpasses[i].pColorAttachments = reference_ptr; 1527ec681f3Smrg translate_references(&reference_ptr, 1537ec681f3Smrg subpasses[i].colorAttachmentCount, 1547ec681f3Smrg pCreateInfo->pSubpasses[i].pColorAttachments, 1557ec681f3Smrg pCreateInfo, false); 1567ec681f3Smrg subpasses[i].pResolveAttachments = NULL; 1577ec681f3Smrg if (pCreateInfo->pSubpasses[i].pResolveAttachments) { 1587ec681f3Smrg subpasses[i].pResolveAttachments = reference_ptr; 1597ec681f3Smrg translate_references(&reference_ptr, 1607ec681f3Smrg subpasses[i].colorAttachmentCount, 1617ec681f3Smrg pCreateInfo->pSubpasses[i].pResolveAttachments, 1627ec681f3Smrg pCreateInfo, false); 1637ec681f3Smrg } 1647ec681f3Smrg subpasses[i].pDepthStencilAttachment = NULL; 1657ec681f3Smrg if (pCreateInfo->pSubpasses[i].pDepthStencilAttachment) { 1667ec681f3Smrg subpasses[i].pDepthStencilAttachment = reference_ptr; 1677ec681f3Smrg translate_references(&reference_ptr, 1, 1687ec681f3Smrg pCreateInfo->pSubpasses[i].pDepthStencilAttachment, 1697ec681f3Smrg pCreateInfo, false); 1707ec681f3Smrg } 1717ec681f3Smrg } 1727ec681f3Smrg 1737ec681f3Smrg assert(reference_ptr == references + reference_count); 1747ec681f3Smrg 1757ec681f3Smrg if (aspect_info != NULL) { 1767ec681f3Smrg for (uint32_t i = 0; i < aspect_info->aspectReferenceCount; i++) { 1777ec681f3Smrg const VkInputAttachmentAspectReference *ref = 1787ec681f3Smrg &aspect_info->pAspectReferences[i]; 1797ec681f3Smrg 1807ec681f3Smrg assert(ref->subpass < pCreateInfo->subpassCount); 1817ec681f3Smrg VkSubpassDescription2 *subpass = &subpasses[ref->subpass]; 1827ec681f3Smrg 1837ec681f3Smrg assert(ref->inputAttachmentIndex < subpass->inputAttachmentCount); 1847ec681f3Smrg VkAttachmentReference2 *att = (VkAttachmentReference2 *) 1857ec681f3Smrg &subpass->pInputAttachments[ref->inputAttachmentIndex]; 1867ec681f3Smrg 1877ec681f3Smrg att->aspectMask = ref->aspectMask; 1887ec681f3Smrg } 1897ec681f3Smrg } 1907ec681f3Smrg 1917ec681f3Smrg for (uint32_t i = 0; i < pCreateInfo->dependencyCount; i++) { 1927ec681f3Smrg dependencies[i] = (VkSubpassDependency2) { 1937ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2, 1947ec681f3Smrg .pNext = NULL, 1957ec681f3Smrg .srcSubpass = pCreateInfo->pDependencies[i].srcSubpass, 1967ec681f3Smrg .dstSubpass = pCreateInfo->pDependencies[i].dstSubpass, 1977ec681f3Smrg .srcStageMask = pCreateInfo->pDependencies[i].srcStageMask, 1987ec681f3Smrg .dstStageMask = pCreateInfo->pDependencies[i].dstStageMask, 1997ec681f3Smrg .srcAccessMask = pCreateInfo->pDependencies[i].srcAccessMask, 2007ec681f3Smrg .dstAccessMask = pCreateInfo->pDependencies[i].dstAccessMask, 2017ec681f3Smrg .dependencyFlags = pCreateInfo->pDependencies[i].dependencyFlags, 2027ec681f3Smrg .viewOffset = 0, 2037ec681f3Smrg }; 2047ec681f3Smrg 2057ec681f3Smrg if (multiview_info && multiview_info->dependencyCount) { 2067ec681f3Smrg assert(multiview_info->dependencyCount == pCreateInfo->dependencyCount); 2077ec681f3Smrg dependencies[i].viewOffset = multiview_info->pViewOffsets[i]; 2087ec681f3Smrg } 2097ec681f3Smrg } 2107ec681f3Smrg 2117ec681f3Smrg *create_info = (VkRenderPassCreateInfo2) { 2127ec681f3Smrg .sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2, 2137ec681f3Smrg .pNext = pCreateInfo->pNext, 2147ec681f3Smrg .flags = pCreateInfo->flags, 2157ec681f3Smrg .attachmentCount = pCreateInfo->attachmentCount, 2167ec681f3Smrg .pAttachments = attachments, 2177ec681f3Smrg .subpassCount = pCreateInfo->subpassCount, 2187ec681f3Smrg .pSubpasses = subpasses, 2197ec681f3Smrg .dependencyCount = pCreateInfo->dependencyCount, 2207ec681f3Smrg .pDependencies = dependencies, 2217ec681f3Smrg }; 2227ec681f3Smrg 2237ec681f3Smrg if (multiview_info && multiview_info->correlationMaskCount > 0) { 2247ec681f3Smrg create_info->correlatedViewMaskCount = multiview_info->correlationMaskCount; 2257ec681f3Smrg create_info->pCorrelatedViewMasks = multiview_info->pCorrelationMasks; 2267ec681f3Smrg } 2277ec681f3Smrg 2287ec681f3Smrg VkResult result = 2297ec681f3Smrg device->dispatch_table.CreateRenderPass2(_device, create_info, 2307ec681f3Smrg pAllocator, pRenderPass); 2317ec681f3Smrg 2327ec681f3Smrg vk_free2(&device->alloc, pAllocator, create_info); 2337ec681f3Smrg 2347ec681f3Smrg return result; 2357ec681f3Smrg} 2367ec681f3Smrg 2377ec681f3SmrgVKAPI_ATTR void VKAPI_CALL 2387ec681f3Smrgvk_common_CmdBeginRenderPass(VkCommandBuffer commandBuffer, 2397ec681f3Smrg const VkRenderPassBeginInfo* pRenderPassBegin, 2407ec681f3Smrg VkSubpassContents contents) 2417ec681f3Smrg{ 2427ec681f3Smrg /* We don't have a vk_command_buffer object but we can assume, since we're 2437ec681f3Smrg * using common dispatch, that it's a vk_object of some sort. 2447ec681f3Smrg */ 2457ec681f3Smrg struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 2467ec681f3Smrg 2477ec681f3Smrg VkSubpassBeginInfo info = { 2487ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, 2497ec681f3Smrg .contents = contents, 2507ec681f3Smrg }; 2517ec681f3Smrg 2527ec681f3Smrg disp->device->dispatch_table.CmdBeginRenderPass2(commandBuffer, 2537ec681f3Smrg pRenderPassBegin, &info); 2547ec681f3Smrg} 2557ec681f3Smrg 2567ec681f3SmrgVKAPI_ATTR void VKAPI_CALL 2577ec681f3Smrgvk_common_CmdEndRenderPass(VkCommandBuffer commandBuffer) 2587ec681f3Smrg{ 2597ec681f3Smrg /* We don't have a vk_command_buffer object but we can assume, since we're 2607ec681f3Smrg * using common dispatch, that it's a vk_object of some sort. 2617ec681f3Smrg */ 2627ec681f3Smrg struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 2637ec681f3Smrg 2647ec681f3Smrg VkSubpassEndInfo info = { 2657ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, 2667ec681f3Smrg }; 2677ec681f3Smrg 2687ec681f3Smrg disp->device->dispatch_table.CmdEndRenderPass2(commandBuffer, &info); 2697ec681f3Smrg} 2707ec681f3Smrg 2717ec681f3SmrgVKAPI_ATTR void VKAPI_CALL 2727ec681f3Smrgvk_common_CmdNextSubpass(VkCommandBuffer commandBuffer, 2737ec681f3Smrg VkSubpassContents contents) 2747ec681f3Smrg{ 2757ec681f3Smrg /* We don't have a vk_command_buffer object but we can assume, since we're 2767ec681f3Smrg * using common dispatch, that it's a vk_object of some sort. 2777ec681f3Smrg */ 2787ec681f3Smrg struct vk_object_base *disp = (struct vk_object_base *)commandBuffer; 2797ec681f3Smrg 2807ec681f3Smrg VkSubpassBeginInfo begin_info = { 2817ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_BEGIN_INFO, 2827ec681f3Smrg .contents = contents, 2837ec681f3Smrg }; 2847ec681f3Smrg 2857ec681f3Smrg VkSubpassEndInfo end_info = { 2867ec681f3Smrg .sType = VK_STRUCTURE_TYPE_SUBPASS_END_INFO, 2877ec681f3Smrg }; 2887ec681f3Smrg 2897ec681f3Smrg disp->device->dispatch_table.CmdNextSubpass2(commandBuffer, &begin_info, 2907ec681f3Smrg &end_info); 2917ec681f3Smrg} 292