/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ #include "RenderPass.hpp" #include "FrameBuffer.hpp" #include "Base/EngineConfiguration.hpp" namespace openVulkanoCpp::Vulkan { void RenderPass::Init(Device* device, FrameBuffer* frameBuffer, bool clearColor, bool clearDepth) { m_device = device->device; m_frameBuffer = frameBuffer; m_useClearColor = clearColor; m_useClearDepth = clearDepth; CreateRenderPass(); frameBuffer->RegisterRenderPass(this); m_beginInfo.renderPass = renderPass; m_beginInfo.renderArea = vk::Rect2D(vk::Offset2D(), m_frameBuffer->GetSize2D()); if (clearColor) SetClearColor(EngineConfiguration::GetEngineConfiguration()->GetFrameBufferClearColor()); if (clearDepth) SetClearDepth(); } void RenderPass::Close() { m_device.destroy(renderPass); m_frameBuffer = nullptr; } void RenderPass::UpdateBeginInfo() { uint32_t size = 0; vk::ClearValue* clearValues = nullptr; if (m_useClearColor) { size++; clearValues = m_clearValues.data(); } else if (m_useClearDepth) clearValues = &m_clearValues[1]; if (m_useClearDepth) size++; m_beginInfo.clearValueCount = size; m_beginInfo.pClearValues = clearValues; } void RenderPass::Begin(vk::CommandBuffer& commandBuffer, bool primaryBuffer) { m_beginInfo.framebuffer = m_frameBuffer->GetCurrentFrameBuffer(); commandBuffer.beginRenderPass(m_beginInfo, primaryBuffer ? vk::SubpassContents::eInline : vk::SubpassContents::eSecondaryCommandBuffers); } void RenderPass::End(vk::CommandBuffer& commandBuffer) { commandBuffer.endRenderPass(); } void RenderPass::CreateRenderPass() { std::vector attachments; attachments.reserve(m_frameBuffer->UseDepthBuffer() ? 2 : 1); // Color attachment attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetColorFormat(), vk::SampleCountFlagBits::e1, m_useClearColor ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eStore, vk::ImageLayout::ePresentSrcKHR, vk::ImageLayout::ePresentSrcKHR); vk::AttachmentReference* depthReference = nullptr; if (m_frameBuffer->UseDepthBuffer()) { // Depth attachment attachments.emplace_back(vk::AttachmentDescriptionFlags(), m_frameBuffer->GetDepthFormat(), vk::SampleCountFlagBits::e1, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare, m_useClearDepth ? vk::AttachmentLoadOp::eClear : vk::AttachmentLoadOp::eLoad, vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eDepthStencilAttachmentOptimal, vk::ImageLayout::eDepthStencilAttachmentOptimal); depthReference = new vk::AttachmentReference(1, vk::ImageLayout::eDepthStencilAttachmentOptimal); } std::vector colorAttachmentReferences; colorAttachmentReferences.emplace_back(0, vk::ImageLayout::eColorAttachmentOptimal); std::vector subPasses; subPasses.emplace_back(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 0, nullptr, colorAttachmentReferences.size(), colorAttachmentReferences.data(), nullptr, depthReference, 0, nullptr); std::vector subPassDependencies; subPassDependencies.emplace_back(0, VK_SUBPASS_EXTERNAL, vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::PipelineStageFlagBits::eBottomOfPipe, vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite, vk::AccessFlagBits::eMemoryRead, vk::DependencyFlagBits::eByRegion); subPassDependencies.emplace_back(VK_SUBPASS_EXTERNAL, 0, vk::PipelineStageFlagBits::eBottomOfPipe, vk::PipelineStageFlagBits::eColorAttachmentOutput, vk::AccessFlagBits::eMemoryRead, vk::AccessFlagBits::eColorAttachmentRead | vk::AccessFlagBits::eColorAttachmentWrite, vk::DependencyFlagBits::eByRegion); const vk::RenderPassCreateInfo createInfo(vk::RenderPassCreateFlags(), attachments.size(), attachments.data(), subPasses.size(), subPasses.data(), subPassDependencies.size(), subPassDependencies.data()); CreateRenderPass(createInfo); delete depthReference; } void RenderPass::CreateRenderPass(const vk::RenderPassCreateInfo& renderPassCreateInfo) { renderPass = m_device.createRenderPass(renderPassCreateInfo); } }