LCOV - code coverage report
Current view: top level - source/renderer/backend/vulkan - RenderPassManager.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 1 105 1.0 %
Date: 2023-01-19 00:18:29 Functions: 2 8 25.0 %

          Line data    Source code
       1             : /* Copyright (C) 2023 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "RenderPassManager.h"
      21             : 
      22             : #include "lib/hash.h"
      23             : #include "ps/containers/StaticVector.h"
      24             : #include "renderer/backend/vulkan/Device.h"
      25             : #include "renderer/backend/vulkan/Mapping.h"
      26             : #include "renderer/backend/vulkan/Texture.h"
      27             : #include "renderer/backend/vulkan/Utilities.h"
      28             : 
      29             : namespace Renderer
      30             : {
      31             : 
      32             : namespace Backend
      33             : {
      34             : 
      35             : namespace Vulkan
      36             : {
      37             : 
      38           0 : size_t CRenderPassManager::DescHash::operator()(const Desc& desc) const
      39             : {
      40           0 :     size_t seed = 0;
      41           0 :     hash_combine(seed, desc.sampleCount);
      42             : 
      43           0 :     if (desc.colorAttachment.has_value())
      44             :     {
      45           0 :         hash_combine(seed, (*desc.colorAttachment).format);
      46           0 :         hash_combine(seed, (*desc.colorAttachment).loadOp);
      47           0 :         hash_combine(seed, (*desc.colorAttachment).storeOp);
      48             :     }
      49             :     else
      50           0 :         hash_combine(seed, VK_FORMAT_UNDEFINED);
      51             : 
      52           0 :     if (desc.depthStencilAttachment.has_value())
      53             :     {
      54           0 :         hash_combine(seed, (*desc.depthStencilAttachment).format);
      55           0 :         hash_combine(seed, (*desc.depthStencilAttachment).loadOp);
      56           0 :         hash_combine(seed, (*desc.depthStencilAttachment).storeOp);
      57             :     }
      58             :     else
      59           0 :         hash_combine(seed, VK_FORMAT_UNDEFINED);
      60             : 
      61           0 :     return seed;
      62             : }
      63             : 
      64           0 : bool CRenderPassManager::DescEqual::operator()(const Desc& lhs, const Desc& rhs) const
      65             : {
      66           0 :     auto compareAttachments = [](const std::optional<Attachment>& lhs, const std::optional<Attachment>& rhs) -> bool
      67             :     {
      68           0 :         if (lhs.has_value() != rhs.has_value())
      69           0 :             return false;
      70           0 :         if (!lhs.has_value())
      71           0 :             return true;
      72             :         return
      73           0 :             (*lhs).format == (*rhs).format &&
      74           0 :             (*lhs).loadOp == (*rhs).loadOp &&
      75           0 :             (*lhs).storeOp == (*rhs).storeOp;
      76             :     };
      77           0 :     if (!compareAttachments(lhs.colorAttachment, rhs.colorAttachment))
      78           0 :         return false;
      79           0 :     if (!compareAttachments(lhs.depthStencilAttachment, rhs.depthStencilAttachment))
      80           0 :         return false;
      81           0 :     return lhs.sampleCount == rhs.sampleCount;
      82             : }
      83             : 
      84           0 : CRenderPassManager::CRenderPassManager(CDevice* device)
      85           0 :     : m_Device(device)
      86             : {
      87           0 : }
      88             : 
      89           0 : CRenderPassManager::~CRenderPassManager()
      90             : {
      91           0 :     for (const auto& it : m_RenderPassMap)
      92           0 :         if (it.second != VK_NULL_HANDLE)
      93             :         {
      94           0 :             m_Device->ScheduleObjectToDestroy(
      95           0 :                 VK_OBJECT_TYPE_RENDER_PASS, it.second, VK_NULL_HANDLE);
      96             :         }
      97           0 :     m_RenderPassMap.clear();
      98           0 : }
      99             : 
     100           0 : VkRenderPass CRenderPassManager::GetOrCreateRenderPass(
     101             :     SColorAttachment* colorAttachment,
     102             :     SDepthStencilAttachment* depthStencilAttachment)
     103             : {
     104           0 :     Desc desc{};
     105           0 :     if (colorAttachment)
     106             :     {
     107           0 :         CTexture* colorAttachmentTexture = colorAttachment->texture->As<CTexture>();
     108           0 :         desc.sampleCount = colorAttachmentTexture->GetSampleCount();
     109           0 :         desc.colorAttachment.emplace(Attachment{
     110           0 :             colorAttachmentTexture->GetVkFormat(),
     111           0 :             colorAttachment->loadOp,
     112           0 :             colorAttachment->storeOp});
     113             :     }
     114           0 :     if (depthStencilAttachment)
     115             :     {
     116           0 :         CTexture* depthStencilAttachmentTexture = depthStencilAttachment->texture->As<CTexture>();
     117           0 :         desc.sampleCount = depthStencilAttachmentTexture->GetSampleCount();
     118           0 :         desc.depthStencilAttachment.emplace(Attachment{
     119           0 :             depthStencilAttachmentTexture->GetVkFormat(),
     120           0 :             depthStencilAttachment->loadOp,
     121           0 :             depthStencilAttachment->storeOp});
     122             :     }
     123           0 :     auto it = m_RenderPassMap.find(desc);
     124           0 :     if (it != m_RenderPassMap.end())
     125           0 :         return it->second;
     126             : 
     127           0 :     uint32_t attachmentCount = 0;
     128           0 :     PS::StaticVector<VkAttachmentDescription, 4> attachmentDescs;
     129           0 :     std::optional<VkAttachmentReference> colorAttachmentRef;
     130           0 :     std::optional<VkAttachmentReference> depthStencilAttachmentRef;
     131             : 
     132           0 :     if (colorAttachment)
     133             :     {
     134           0 :         CTexture* colorAttachmentTexture = colorAttachment->texture->As<CTexture>();
     135             : 
     136           0 :         VkAttachmentDescription colorAttachmentDesc{};
     137           0 :         colorAttachmentDesc.format = colorAttachmentTexture->GetVkFormat();
     138           0 :         colorAttachmentDesc.samples = Mapping::FromSampleCount(colorAttachmentTexture->GetSampleCount());
     139           0 :         colorAttachmentDesc.loadOp = Mapping::FromAttachmentLoadOp(colorAttachment->loadOp);
     140           0 :         colorAttachmentDesc.storeOp = Mapping::FromAttachmentStoreOp(colorAttachment->storeOp);
     141           0 :         colorAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
     142           0 :         colorAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
     143             : 
     144           0 :         attachmentDescs.emplace_back(std::move(colorAttachmentDesc));
     145             : 
     146           0 :         colorAttachmentRef.emplace(VkAttachmentReference{
     147           0 :             attachmentCount++, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL});
     148             :     }
     149             : 
     150           0 :     if (depthStencilAttachment)
     151             :     {
     152           0 :         CTexture* depthStencilAttachmentTexture = depthStencilAttachment->texture->As<CTexture>();
     153             : 
     154           0 :         VkAttachmentDescription depthStencilAttachmentDesc{};
     155           0 :         depthStencilAttachmentDesc.format = depthStencilAttachmentTexture->GetVkFormat();
     156           0 :         depthStencilAttachmentDesc.samples = Mapping::FromSampleCount(depthStencilAttachmentTexture->GetSampleCount());
     157           0 :         depthStencilAttachmentDesc.loadOp = Mapping::FromAttachmentLoadOp(depthStencilAttachment->loadOp);
     158           0 :         depthStencilAttachmentDesc.storeOp = Mapping::FromAttachmentStoreOp(depthStencilAttachment->storeOp);
     159           0 :         depthStencilAttachmentDesc.stencilLoadOp = depthStencilAttachmentDesc.loadOp;
     160           0 :         depthStencilAttachmentDesc.stencilStoreOp = depthStencilAttachmentDesc.storeOp;
     161           0 :         depthStencilAttachmentDesc.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
     162           0 :         depthStencilAttachmentDesc.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
     163             : 
     164           0 :         attachmentDescs.emplace_back(std::move(depthStencilAttachmentDesc));
     165             : 
     166           0 :         depthStencilAttachmentRef.emplace(VkAttachmentReference{
     167           0 :             attachmentCount++, VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL});
     168             :     }
     169             : 
     170           0 :     VkSubpassDescription subpassDesc{};
     171           0 :     subpassDesc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
     172           0 :     if (colorAttachment)
     173             :     {
     174           0 :         subpassDesc.colorAttachmentCount = 1;
     175           0 :         subpassDesc.pColorAttachments = &(*colorAttachmentRef);
     176             :     }
     177           0 :     if (depthStencilAttachment)
     178           0 :         subpassDesc.pDepthStencilAttachment = &(*depthStencilAttachmentRef);
     179             : 
     180           0 :     VkRenderPassCreateInfo renderPassCreateInfo{};
     181           0 :     renderPassCreateInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
     182           0 :     renderPassCreateInfo.attachmentCount = attachmentDescs.size();
     183           0 :     renderPassCreateInfo.pAttachments = attachmentDescs.data();
     184           0 :     renderPassCreateInfo.subpassCount = 1;
     185           0 :     renderPassCreateInfo.pSubpasses = &subpassDesc;
     186             : 
     187           0 :     VkRenderPass renderPass = VK_NULL_HANDLE;
     188           0 :     ENSURE_VK_SUCCESS(
     189             :         vkCreateRenderPass(
     190             :             m_Device->GetVkDevice(), &renderPassCreateInfo, nullptr, &renderPass));
     191           0 :     it = m_RenderPassMap.emplace(desc, renderPass).first;
     192             : 
     193           0 :     return renderPass;
     194             : }
     195             : 
     196             : } // namespace Vulkan
     197             : 
     198             : } // namespace Backend
     199             : 
     200           3 : } // namespace Renderer

Generated by: LCOV version 1.13