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