Files
inferno-hart/src/graphics/renderpass.cpp
2023-11-23 12:14:40 +00:00

137 lines
4.9 KiB
C++

#include "renderpass.hpp"
#include "device.hpp"
#include "pipeline.hpp"
#include "swapchain.hpp"
#include "preview_renderer/shader.hpp"
#include "yolo/yolo.hpp"
#include <vulkan/vulkan_core.h>
namespace inferno::graphics {
RenderPass* renderpass_create(GraphicsDevice* device)
{
RenderPass* renderpass = new RenderPass;
renderpass->Device = device;
// TODO: this can be done at the end to reduce the complexity of the pipeline creation
renderpass->RenderPipeline = pipeline_create(device);
VkAttachmentDescription colorAttachment = {};
colorAttachment.format = renderpass->RenderPipeline->Swap->ImageFormat;
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
colorAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
colorAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
colorAttachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
colorAttachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
colorAttachment.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
colorAttachment.finalLayout = VK_IMAGE_LAYOUT_PRESENT_SRC_KHR;
VkAttachmentReference colorAttachmentRef {};
colorAttachmentRef.attachment = 0;
colorAttachmentRef.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
VkSubpassDescription subpass {};
subpass.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
subpass.colorAttachmentCount = 1;
subpass.pColorAttachments = &colorAttachmentRef; // index = gl_colour in glsl
VkRenderPassCreateInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
if (vkCreateRenderPass(
device->VulkanDevice, &renderPassInfo, nullptr, &renderpass->VulkanRenderPass)
!= VK_SUCCESS) {
yolo::error("failed to create render pass!");
return nullptr;
}
Shader* shader = shader_create(device);
shader_load(shader, "res/shaders/vulkan_test");
pipeline_configure_to_renderpass(renderpass->RenderPipeline, shader, renderpass);
return renderpass;
}
void rendepass_cleanup(RenderPass* renderpass)
{
pipeline_cleanup(renderpass->RenderPipeline);
vkDestroyRenderPass(
renderpass->Device->VulkanDevice, renderpass->VulkanRenderPass, nullptr);
vkDestroyCommandPool(
renderpass->Device->VulkanDevice, renderpass->CommandPool, nullptr);
delete renderpass;
}
void renderpass_configure_command_buffer(RenderPass* renderpass)
{
QueueFamilyIndices i = device_get_queue_families(
renderpass->Device, renderpass->Device->VulkanPhysicalDevice);
VkCommandPoolCreateInfo poolInfo {};
poolInfo.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO;
poolInfo.queueFamilyIndex = i.graphicsFamily.value();
poolInfo.flags = 0; // Optional
if (vkCreateCommandPool(renderpass->Device->VulkanDevice, &poolInfo, nullptr,
&renderpass->CommandPool)
!= VK_SUCCESS) {
yolo::error("failed to create command pool!");
}
VkCommandBufferAllocateInfo allocInfo {};
allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO;
allocInfo.commandPool = renderpass->CommandPool;
allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY;
allocInfo.commandBufferCount = 1;
if (vkAllocateCommandBuffers(
renderpass->Device->VulkanDevice, &allocInfo, &renderpass->CommandBuffer)
!= VK_SUCCESS) {
yolo::error("failed to allocate command buffers!");
}
yolo::debug("Command buffer created");
}
void renderpass_begin(RenderPass* renderpass, uint32_t imageIndex)
{
VkCommandBufferBeginInfo beginInfo {};
beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO;
beginInfo.flags = 0; // Optional
beginInfo.pInheritanceInfo = nullptr; // Optional
if (vkBeginCommandBuffer(renderpass->CommandBuffer, &beginInfo) != VK_SUCCESS) {
yolo::error("failed to begin recording command buffer!");
}
VkRenderPassBeginInfo renderPassInfo {};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = renderpass->VulkanRenderPass;
renderPassInfo.framebuffer
= renderpass->RenderPipeline->Swap->SwapFramebuffers[imageIndex];
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = renderpass->RenderPipeline->Swap->Extent;
VkClearValue clearColor = { { { 0.0f, 0.3f, 0.3f, 1.0f } } };
renderPassInfo.clearValueCount = 1;
renderPassInfo.pClearValues = &clearColor;
vkCmdBeginRenderPass(
renderpass->CommandBuffer, &renderPassInfo, VK_SUBPASS_CONTENTS_INLINE);
}
void renderpass_end(RenderPass* renderpass)
{
vkCmdEndRenderPass(renderpass->CommandBuffer);
if (vkEndCommandBuffer(renderpass->CommandBuffer) != VK_SUCCESS) {
yolo::error("failed to record command buffer!");
}
}
}