Refactor RenderPass logic
This commit is contained in:
@@ -30,7 +30,7 @@ namespace openVulkanoCpp::Vulkan
|
||||
|
||||
|
||||
swapChain.Init(device.get(), surface, window);
|
||||
swapChainRenderPass.Init(device.get(), &swapChain);
|
||||
swapChainRenderPass.Init(device.get(), &swapChain, true, true);
|
||||
|
||||
pipeline.Init(device->device);
|
||||
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* 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 "FrameBuffer.hpp"
|
||||
#include "RenderPass.hpp"
|
||||
|
||||
@@ -14,12 +20,17 @@ void openVulkanoCpp::Vulkan::FrameBuffer::Init(Device* device, vk::Extent3D size
|
||||
}
|
||||
}
|
||||
|
||||
void openVulkanoCpp::Vulkan::FrameBuffer::InitRenderPass(RenderPass* renderPass)
|
||||
void openVulkanoCpp::Vulkan::FrameBuffer::RegisterRenderPass(RenderPass* renderPass)
|
||||
{
|
||||
if (!device) throw std::
|
||||
runtime_error("The frame buffer needs to be initialized before binding it to a render pass");
|
||||
this->renderPass = renderPass;
|
||||
CreateFrameBuffer();
|
||||
if (!renderPasses.empty())
|
||||
{
|
||||
//TODO check compatibility
|
||||
// https://registry.khronos.org/vulkan/specs/1.3-extensions/html/vkspec.html#renderpass-compatibility
|
||||
}
|
||||
renderPasses.push_back(renderPass);
|
||||
if (renderPasses.size() == 1) CreateFrameBuffer();
|
||||
}
|
||||
|
||||
void openVulkanoCpp::Vulkan::FrameBuffer::Resize(vk::Extent3D size)
|
||||
@@ -29,7 +40,10 @@ void openVulkanoCpp::Vulkan::FrameBuffer::Resize(vk::Extent3D size)
|
||||
if (depthBuffer) depthBuffer.Close();
|
||||
if (useDepthBuffer) CreateDepthStencil();
|
||||
CreateFrameBuffer();
|
||||
renderPass->UpdateBeginInfo();
|
||||
for(RenderPass* renderPass : renderPasses)
|
||||
{
|
||||
renderPass->Resize(size);
|
||||
}
|
||||
}
|
||||
|
||||
void openVulkanoCpp::Vulkan::FrameBuffer::CreateDepthStencil()
|
||||
@@ -54,7 +68,7 @@ void openVulkanoCpp::Vulkan::FrameBuffer::CreateFrameBuffer()
|
||||
{
|
||||
vk::ImageView attachments[2]; // First attachment is the color buffer, second (optional) the depth buffer
|
||||
if (useDepthBuffer) attachments[1] = depthBuffer.view; //Depth buffer is the same for all frame buffers
|
||||
const vk::FramebufferCreateInfo fbCreateInfo({}, renderPass->renderPass, useDepthBuffer ? 2 : 1, attachments, size.width,
|
||||
const vk::FramebufferCreateInfo fbCreateInfo({}, renderPasses[0]->renderPass, useDepthBuffer ? 2 : 1, attachments, size.width,
|
||||
size.height, 1);
|
||||
|
||||
auto images = GetImages();
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
/*
|
||||
* 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/.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
#include "Base/ICloseable.hpp"
|
||||
#include "Image.hpp"
|
||||
#include "Device.hpp"
|
||||
#include <cstdint>
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace openVulkanoCpp
|
||||
{
|
||||
namespace Vulkan
|
||||
|
||||
namespace openVulkanoCpp::Vulkan
|
||||
{
|
||||
class RenderPass;
|
||||
|
||||
@@ -17,7 +23,7 @@ namespace openVulkanoCpp
|
||||
std::vector<vk::Framebuffer> frameBuffers;
|
||||
vk::Format depthBufferFormat = vk::Format::eUndefined, colorFormat = vk::Format::eUndefined;
|
||||
vk::Extent3D size;
|
||||
RenderPass* renderPass;
|
||||
std::vector<RenderPass*> renderPasses;
|
||||
bool useDepthBuffer;
|
||||
Device* device = nullptr;
|
||||
protected:
|
||||
@@ -43,7 +49,7 @@ namespace openVulkanoCpp
|
||||
}
|
||||
|
||||
public:
|
||||
void InitRenderPass(RenderPass* renderPass);
|
||||
void RegisterRenderPass(RenderPass* renderPass);
|
||||
|
||||
protected:
|
||||
void Resize(vk::Extent3D size);
|
||||
@@ -104,4 +110,3 @@ namespace openVulkanoCpp
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
100
openVulkanoCpp/Vulkan/RenderPass.cpp
Normal file
100
openVulkanoCpp/Vulkan/RenderPass.cpp
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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<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::eUndefined, 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::eUndefined, 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);
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vulkan/vulkan.hpp>
|
||||
#include "Device.hpp"
|
||||
#include "FrameBuffer.hpp"
|
||||
#include "Base/EngineConfiguration.hpp"
|
||||
#include <vulkan/vulkan.hpp>
|
||||
|
||||
namespace openVulkanoCpp
|
||||
{
|
||||
namespace Vulkan
|
||||
namespace openVulkanoCpp::Vulkan
|
||||
{
|
||||
class FrameBuffer;
|
||||
|
||||
class RenderPass : virtual public ICloseable
|
||||
{
|
||||
{ //TODO allow to control the render rect size
|
||||
protected:
|
||||
vk::Device device;
|
||||
vk::RenderPassBeginInfo beginInfo;
|
||||
vk::ClearColorValue clearColor;
|
||||
vk::ClearDepthStencilValue clearDepth;
|
||||
std::vector<vk::ClearValue> clearValues;
|
||||
FrameBuffer* frameBuffer = nullptr;
|
||||
bool useClearColor = false, useClearDepth = true;
|
||||
vk::Device m_device;
|
||||
vk::RenderPassBeginInfo m_beginInfo;
|
||||
std::array<vk::ClearValue, 2> m_clearValues;
|
||||
FrameBuffer* m_frameBuffer = nullptr;
|
||||
bool m_useClearColor = false, m_useClearDepth = true;
|
||||
|
||||
public:
|
||||
vk::RenderPass renderPass;
|
||||
@@ -33,123 +29,72 @@ namespace openVulkanoCpp
|
||||
|
||||
~RenderPass() override
|
||||
{
|
||||
if (frameBuffer) RenderPass::Close();
|
||||
if (m_frameBuffer) RenderPass::Close();
|
||||
}
|
||||
|
||||
void Init(Device* device, FrameBuffer* frameBuffer)
|
||||
{
|
||||
this->device = device->device;
|
||||
this->frameBuffer = frameBuffer;
|
||||
CreateRenderPass();
|
||||
frameBuffer->InitRenderPass(this);
|
||||
SetClearColor(EngineConfiguration::GetEngineConfiguration()->GetFrameBufferClearColor());
|
||||
SetClearDepth();
|
||||
}
|
||||
void Init(Device* device, FrameBuffer* frameBuffer, bool clearColor = false, bool clearDepth = false);
|
||||
|
||||
void Close() override
|
||||
{
|
||||
device.destroy(renderPass);
|
||||
frameBuffer = nullptr;
|
||||
clearValues.clear();
|
||||
}
|
||||
void Close() override;
|
||||
|
||||
void SetClearColor(vk::ClearColorValue clearColor = vk::ClearColorValue(std::array<float, 4>{ 0.39f, 0.58f, 0.93f, 1.0f }))
|
||||
{
|
||||
this->clearColor = clearColor;
|
||||
useClearColor = true;
|
||||
m_clearValues[0] = clearColor;
|
||||
if (!m_useClearColor)
|
||||
{
|
||||
m_useClearColor = true;
|
||||
//TODO recreate
|
||||
}
|
||||
UpdateBeginInfo();
|
||||
}
|
||||
|
||||
void DisableClearColor()
|
||||
{
|
||||
useClearColor = false;
|
||||
if (m_useClearColor)
|
||||
{
|
||||
m_useClearColor = false;
|
||||
//TODO recreate
|
||||
UpdateBeginInfo();
|
||||
}
|
||||
}
|
||||
|
||||
void SetClearDepth(vk::ClearDepthStencilValue clearDepth = vk::ClearDepthStencilValue(1, 0))
|
||||
{
|
||||
this->clearDepth = clearDepth;
|
||||
useClearDepth = true;
|
||||
m_clearValues[1] = clearDepth;
|
||||
if (!m_useClearDepth)
|
||||
{
|
||||
m_useClearDepth = true;
|
||||
//TODO recreate
|
||||
}
|
||||
UpdateBeginInfo();
|
||||
}
|
||||
|
||||
void DisableClearDepth()
|
||||
{
|
||||
useClearDepth = false;
|
||||
}
|
||||
|
||||
virtual void UpdateBeginInfo()
|
||||
{ //TODO allow to control the render rect size
|
||||
clearValues.clear();
|
||||
if (useClearColor) clearValues.emplace_back(clearColor);
|
||||
if(frameBuffer->UseDepthBuffer() && useClearDepth) clearValues.emplace_back(clearDepth);
|
||||
|
||||
beginInfo = vk::RenderPassBeginInfo(renderPass, vk::Framebuffer(),
|
||||
vk::Rect2D(vk::Offset2D(), frameBuffer->GetSize2D()),
|
||||
clearValues.size(), clearValues.data());
|
||||
}
|
||||
|
||||
virtual void Begin(vk::CommandBuffer& commandBuffer)
|
||||
if (m_useClearDepth)
|
||||
{
|
||||
beginInfo.framebuffer = frameBuffer->GetCurrentFrameBuffer();
|
||||
commandBuffer.beginRenderPass(beginInfo, vk::SubpassContents::eSecondaryCommandBuffers);
|
||||
m_useClearDepth = false;
|
||||
//TODO recreate
|
||||
UpdateBeginInfo();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void End(vk::CommandBuffer& commandBuffer)
|
||||
void Resize(vk::Extent3D size)
|
||||
{
|
||||
commandBuffer.endRenderPass();
|
||||
m_beginInfo.renderArea.extent.width = size.width;
|
||||
m_beginInfo.renderArea.extent.height = size.height;
|
||||
}
|
||||
|
||||
FrameBuffer* GetFrameBuffer() const
|
||||
{
|
||||
return frameBuffer;
|
||||
}
|
||||
virtual void UpdateBeginInfo();
|
||||
|
||||
virtual void Begin(vk::CommandBuffer& commandBuffer, bool primaryBuffer = false);
|
||||
|
||||
virtual void End(vk::CommandBuffer& commandBuffer);
|
||||
|
||||
[[nodiscard]] FrameBuffer* GetFrameBuffer() const { return m_frameBuffer; }
|
||||
|
||||
protected:
|
||||
virtual void CreateRenderPass()
|
||||
{
|
||||
std::vector<vk::AttachmentDescription> attachments;
|
||||
attachments.reserve(frameBuffer->UseDepthBuffer() ? 2 : 1);
|
||||
virtual void CreateRenderPass();
|
||||
|
||||
// Color attachment
|
||||
attachments.emplace_back(vk::AttachmentDescriptionFlags(), frameBuffer->GetColorFormat(), vk::SampleCountFlagBits::e1,
|
||||
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eLoad,
|
||||
vk::AttachmentStoreOp::eStore, vk::ImageLayout::eUndefined, vk::ImageLayout::ePresentSrcKHR);
|
||||
|
||||
vk::AttachmentReference* depthReference = nullptr;;
|
||||
if (frameBuffer->UseDepthBuffer())
|
||||
{ // Depth attachment
|
||||
attachments.emplace_back(vk::AttachmentDescriptionFlags(), frameBuffer->GetDepthFormat(), vk::SampleCountFlagBits::e1,
|
||||
vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eDontCare, vk::AttachmentLoadOp::eClear,
|
||||
vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eUndefined, 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 CreateRenderPass(const vk::RenderPassCreateInfo& renderPassCreateInfo)
|
||||
{
|
||||
renderPass = device.createRenderPass(renderPassCreateInfo);
|
||||
}
|
||||
void CreateRenderPass(const vk::RenderPassCreateInfo& renderPassCreateInfo);
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user