Files
Seele/src/Engine/Graphics/Vulkan/RenderPass.cpp
T

231 lines
9.7 KiB
C++
Raw Normal View History

2023-10-26 18:37:29 +02:00
#include "RenderPass.h"
#include "Graphics.h"
#include "Framebuffer.h"
#include "Texture.h"
2023-12-02 10:55:00 +01:00
#include "Resources.h"
#include "Command.h"
2020-04-12 15:47:19 +02:00
using namespace Seele;
using namespace Seele::Vulkan;
2023-11-08 23:27:21 +01:00
RenderPass::RenderPass(PGraphics graphics, Gfx::ORenderTargetLayout _layout, Gfx::PViewport viewport)
: Gfx::RenderPass(std::move(_layout))
2020-05-05 01:51:13 +02:00
, graphics(graphics)
2020-04-12 15:47:19 +02:00
{
2023-11-15 00:06:00 +01:00
renderArea.extent.width = viewport->getWidth();
renderArea.extent.height = viewport->getHeight();
2021-09-23 10:10:39 +02:00
renderArea.offset.x = viewport->getOffsetX();
renderArea.offset.y = viewport->getOffsetY();
2020-10-03 11:00:10 +02:00
subpassContents = VK_SUBPASS_CONTENTS_SECONDARY_COMMAND_BUFFERS;
2023-12-10 22:27:59 +01:00
Array<VkAttachmentDescription2> attachments;
Array<VkAttachmentReference2> inputRefs;
Array<VkAttachmentReference2> colorRefs;
Array<VkAttachmentReference2> resolveRefs;
VkAttachmentReference2 depthRef;
VkAttachmentReference2 depthResolveRef;
2020-04-12 15:47:19 +02:00
uint32 attachmentCounter = 0;
2023-11-08 23:27:21 +01:00
for (auto& inputAttachment : layout->inputAttachments)
2020-04-12 15:47:19 +02:00
{
PTexture2D image = inputAttachment->getTexture().cast<Texture2D>();
2023-12-10 22:27:59 +01:00
VkAttachmentDescription2& desc = attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.flags = 0,
.format = cast(image->getFormat()),
.loadOp = cast(inputAttachment->getLoadOp()),
.storeOp = cast(inputAttachment->getStoreOp()),
.stencilLoadOp = cast(inputAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(inputAttachment->getStencilStoreOp()),
.initialLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2023-12-10 22:27:59 +01:00
.finalLayout = image->isDepthStencil() ? VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL : VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
2023-11-15 17:42:57 +01:00
};
inputRefs.add() = {
.attachment = attachmentCounter++,
.layout = desc.initialLayout,
};
2020-04-12 15:47:19 +02:00
}
2023-11-08 23:27:21 +01:00
for (auto& colorAttachment : layout->colorAttachments)
2020-04-12 15:47:19 +02:00
{
2023-11-15 17:42:57 +01:00
attachments.add() = {
2023-12-10 22:27:59 +01:00
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.flags = 0,
.format = cast(colorAttachment->getFormat()),
.samples = (VkSampleCountFlagBits)colorAttachment->getNumSamples(),
.loadOp = cast(colorAttachment->getLoadOp()),
.storeOp = cast(colorAttachment->getStoreOp()),
.stencilLoadOp = cast(colorAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(colorAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
2020-10-23 01:47:56 +02:00
VkClearValue& clearValue = clearValues.add();
2023-11-15 17:42:57 +01:00
if(attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
2020-10-23 01:47:56 +02:00
{
clearValue = cast(colorAttachment->clear);
}
2023-11-15 17:42:57 +01:00
colorRefs.add() = {
2023-12-10 22:27:59 +01:00
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
.pNext = nullptr,
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
}
for (auto& resolveAttachment : layout->resolveAttachments)
{
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
.flags = 0,
.format = cast(resolveAttachment->getFormat()),
.samples = (VkSampleCountFlagBits)resolveAttachment->getNumSamples(),
.loadOp = cast(resolveAttachment->getLoadOp()),
.storeOp = cast(resolveAttachment->getStoreOp()),
.stencilLoadOp = cast(resolveAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(resolveAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
VkClearValue& clearValue = clearValues.add();
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
{
clearValue = cast(resolveAttachment->clear);
}
resolveRefs.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
};
2020-04-12 15:47:19 +02:00
}
if (layout->depthAttachment != nullptr)
{
PTexture2D image = layout->depthAttachment->getTexture().cast<Texture2D>();
2023-11-15 17:42:57 +01:00
attachments.add() = {
2023-12-10 22:27:59 +01:00
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.flags = 0,
.format = cast(image->getFormat()),
.samples = (VkSampleCountFlagBits)image->getNumSamples(),
.loadOp = cast(layout->depthAttachment->getLoadOp()),
.storeOp = cast(layout->depthAttachment->getStoreOp()),
.stencilLoadOp = cast(layout->depthAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(layout->depthAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
2023-12-10 22:27:59 +01:00
2020-10-23 01:47:56 +02:00
VkClearValue& clearValue = clearValues.add();
2023-12-10 22:27:59 +01:00
if (attachments.back().loadOp == VK_ATTACHMENT_LOAD_OP_CLEAR)
2020-10-23 01:47:56 +02:00
{
clearValue = cast(layout->depthAttachment->clear);
}
2023-11-15 17:42:57 +01:00
depthRef = {
2023-12-10 22:27:59 +01:00
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
2020-04-12 15:47:19 +02:00
}
2023-12-10 22:27:59 +01:00
if (layout->depthResolveAttachment != nullptr)
{
PTexture2D image = layout->depthResolveAttachment->getTexture().cast<Texture2D>();
attachments.add() = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_DESCRIPTION_2,
.pNext = nullptr,
.flags = 0,
.format = cast(image->getFormat()),
.samples = (VkSampleCountFlagBits)image->getNumSamples(),
.loadOp = cast(layout->depthResolveAttachment->getLoadOp()),
.storeOp = cast(layout->depthResolveAttachment->getStoreOp()),
.stencilLoadOp = cast(layout->depthResolveAttachment->getStencilLoadOp()),
.stencilStoreOp = cast(layout->depthResolveAttachment->getStencilStoreOp()),
.initialLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
.finalLayout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
depthResolveRef = {
.sType = VK_STRUCTURE_TYPE_ATTACHMENT_REFERENCE_2,
.pNext = nullptr,
.attachment = attachmentCounter++,
.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL,
};
}
VkSubpassDescriptionDepthStencilResolve depthResolve = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_DEPTH_STENCIL_RESOLVE,
.pNext = nullptr,
.depthResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT,
.stencilResolveMode = VK_RESOLVE_MODE_AVERAGE_BIT,
.pDepthStencilResolveAttachment = &depthResolveRef,
};
VkSubpassDescription2 subPassDesc = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_DESCRIPTION_2,
.pNext = layout->depthResolveAttachment != nullptr ? &depthResolve : nullptr,
2023-11-15 17:42:57 +01:00
.flags = 0,
.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS,
.inputAttachmentCount = (uint32)inputRefs.size(),
.pInputAttachments = inputRefs.data(),
.colorAttachmentCount = (uint32)colorRefs.size(),
.pColorAttachments = colorRefs.data(),
2023-12-10 22:27:59 +01:00
.pResolveAttachments = resolveRefs.size() > 0 ? resolveRefs.data() : nullptr,
2023-11-15 17:42:57 +01:00
.pDepthStencilAttachment = &depthRef,
};
2023-12-10 22:27:59 +01:00
VkSubpassDependency2 dependency = {
.sType = VK_STRUCTURE_TYPE_SUBPASS_DEPENDENCY_2,
.pNext = nullptr,
2023-11-15 17:42:57 +01:00
.srcSubpass = VK_SUBPASS_EXTERNAL,
.dstSubpass = 0,
.srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
.srcAccessMask = VK_ACCESS_MEMORY_READ_BIT,
.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
};
2023-12-10 22:27:59 +01:00
VkRenderPassCreateInfo2 info = {
.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO_2,
2023-11-15 17:42:57 +01:00
.pNext = nullptr,
.attachmentCount = (uint32)attachments.size(),
.pAttachments = attachments.data(),
.subpassCount = 1,
.pSubpasses = &subPassDesc,
.dependencyCount = 1,
.pDependencies = &dependency,
};
2020-04-12 15:47:19 +02:00
2023-12-10 22:27:59 +01:00
VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass));
2023-11-16 22:58:47 +01:00
}
2020-04-12 15:47:19 +02:00
2023-11-16 22:58:47 +01:00
RenderPass::~RenderPass()
{
2023-12-02 10:55:00 +01:00
graphics->getDestructionManager()->queueRenderPass(graphics->getGraphicsCommands()->getCommands(), renderPass);
2023-11-16 22:58:47 +01:00
}
uint32 RenderPass::getFramebufferHash()
{
2020-04-12 15:47:19 +02:00
FramebufferDescription description;
std::memset(&description, 0, sizeof(FramebufferDescription));
2023-11-01 23:12:30 +01:00
for (auto& inputAttachment : layout->inputAttachments)
2020-04-12 15:47:19 +02:00
{
PTexture2D tex = inputAttachment->getTexture().cast<Texture2D>();
description.inputAttachments[description.numInputAttachments++] = tex->getView();
}
2023-11-01 23:12:30 +01:00
for (auto& colorAttachment : layout->colorAttachments)
2020-04-12 15:47:19 +02:00
{
PTexture2D tex = colorAttachment->getTexture().cast<Texture2D>();
2020-05-05 01:51:13 +02:00
description.colorAttachments[description.numColorAttachments++] = tex->getView();
2020-04-12 15:47:19 +02:00
}
2020-05-05 01:51:13 +02:00
if (layout->depthAttachment != nullptr)
2020-04-12 15:47:19 +02:00
{
PTexture2D tex = layout->depthAttachment->getTexture().cast<Texture2D>();
description.depthAttachment = tex->getView();
}
2023-11-16 22:58:47 +01:00
return CRC::Calculate(&description, sizeof(FramebufferDescription), CRC::CRC_32());
2023-11-15 17:42:57 +01:00
}