Files
OpenVulkano/openVulkanoCpp/Vulkan/RenderPass.cpp

100 lines
4.5 KiB
C++

/*
* 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_useClearColor && 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<vk::AttachmentDescription> 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<vk::AttachmentReference> colorAttachmentReferences;
colorAttachmentReferences.emplace_back(0, vk::ImageLayout::eColorAttachmentOptimal);
std::vector<vk::SubpassDescription> subPasses;
subPasses.emplace_back(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 0, nullptr,
colorAttachmentReferences.size(), colorAttachmentReferences.data(), nullptr, depthReference, 0, nullptr);
std::vector<vk::SubpassDependency> 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);
}
}