Skip to content

Commit

Permalink
Framebuffers Nearly Working
Browse files Browse the repository at this point in the history
  • Loading branch information
tomheeleynz committed Sep 12, 2021
1 parent 5907cd4 commit 224acd6
Show file tree
Hide file tree
Showing 12 changed files with 331 additions and 43 deletions.
1 change: 1 addition & 0 deletions Arcane/src/Arcane.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "Arcane/Renderer/Buffer.h"
#include "Arcane/Renderer/UniformBuffer.h"
#include "Arcane/Renderer/Texture.h"
#include "Arcane/Renderer/Framebuffer.h"

/////////////////////////////////////////////////////
////////// ImGui
Expand Down
180 changes: 180 additions & 0 deletions Arcane/src/Arcane/Platform/Vulkan/VulkanFramebuffer.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,188 @@
#include "VulkanFramebuffer.h"

#include "Arcane/Core/Application.h"
#include "VulkanContext.h"

namespace Arcane {
static uint32_t FindMemoryType(uint32_t typeFilter, VkMemoryPropertyFlags properties)
{
Application& app = Application::Get();
VkDevice logicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetDevice().GetLogicalDevice();
VkPhysicalDevice physicalDevice = static_cast<VulkanContext*>(app.GetWindow().GetContext())->GetPhysicalDevice().GetPhysicalDevice();

VkPhysicalDeviceMemoryProperties memProperties;
vkGetPhysicalDeviceMemoryProperties(physicalDevice, &memProperties);

for (uint32_t i = 0; i < memProperties.memoryTypeCount; i++) {
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties) {
return i;
}
}

return -1;
}

VulkanFramebuffer::VulkanFramebuffer(FramebufferSpecifications& specs)
{
Application& app = Application::Get();
VulkanContext* context = static_cast<VulkanContext*>(app.GetWindow().GetContext());

for (FramebufferAttachmentType element : specs.AttachmentSpecs.m_Attachments) {
switch (element) {
case FramebufferAttachmentType::COLOR:
{
FrameBufferAttachment attachment = {};

// Image Create Info
VkImageCreateInfo imageCreateInfo = {};
imageCreateInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
imageCreateInfo.imageType = VK_IMAGE_TYPE_2D;
imageCreateInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
imageCreateInfo.extent.width = specs.Width;
imageCreateInfo.extent.height = specs.Height;
imageCreateInfo.extent.depth = 1;
imageCreateInfo.mipLevels = 1;
imageCreateInfo.arrayLayers = 1;
imageCreateInfo.samples = VK_SAMPLE_COUNT_1_BIT;
imageCreateInfo.tiling = VK_IMAGE_TILING_OPTIMAL;
imageCreateInfo.usage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;

// Create Image color attachment
if (vkCreateImage(context->GetDevice().GetLogicalDevice(), &imageCreateInfo, nullptr, &attachment.Image) != VK_SUCCESS) {
printf("Framebuffer Color not created\n");
}

// Get Image Memory Requirmentes
VkMemoryRequirements memRequirements;
vkGetImageMemoryRequirements(context->GetDevice().GetLogicalDevice(), attachment.Image, &memRequirements);

VkMemoryAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO;
allocInfo.allocationSize = memRequirements.size;
allocInfo.memoryTypeIndex = FindMemoryType(memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);

if (vkAllocateMemory(context->GetDevice().GetLogicalDevice(), &allocInfo, nullptr, &attachment.ImageMemory) != VK_SUCCESS) {
printf("Framebuffer Color Image Memory Not Allocated\n");
}


if (vkBindImageMemory(context->GetDevice().GetLogicalDevice(), attachment.Image, attachment.ImageMemory, 0) != VK_SUCCESS) {
printf("Framebuffer Color Image Memory Not Bound\n");
}


// Create Image View
VkImageViewCreateInfo colorImageInfo = {};
colorImageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
colorImageInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
colorImageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;
colorImageInfo.subresourceRange = {};
colorImageInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
colorImageInfo.subresourceRange.baseMipLevel = 0;
colorImageInfo.subresourceRange.levelCount = 1;
colorImageInfo.subresourceRange.baseArrayLayer = 0;
colorImageInfo.subresourceRange.layerCount = 1;
colorImageInfo.image = attachment.Image;

if (vkCreateImageView(context->GetDevice().GetLogicalDevice(), &colorImageInfo, nullptr, &attachment.ImageView) != VK_SUCCESS)
{
printf("Framebuffer Color Image View Not Created\n");
}

// Create Image
VkSamplerCreateInfo samplerInfo{};
samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
samplerInfo.magFilter = VK_FILTER_LINEAR;
samplerInfo.minFilter = VK_FILTER_LINEAR;
samplerInfo.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR;
samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE;
samplerInfo.addressModeV = samplerInfo.addressModeU;
samplerInfo.addressModeW = samplerInfo.addressModeU;
samplerInfo.mipLodBias = 0.0f;
samplerInfo.maxAnisotropy = 1.0f;
samplerInfo.minLod = 0.0f;
samplerInfo.maxLod = 1.0f;
samplerInfo.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE;

if (vkCreateSampler(context->GetDevice().GetLogicalDevice(), &samplerInfo, nullptr, &m_ImageSampler) != VK_SUCCESS)
{
printf("Color Sampler Not Created in framebuffer\n");
}

m_Attachments.push_back(attachment);

break;
}
}

// Create Framebuffer Renderpass
VkAttachmentDescription colorAttachment{};
colorAttachment.format = VK_FORMAT_R8G8B8A8_SRGB;
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;

// Subpass Dependency
VkSubpassDependency dependency{};
dependency.srcSubpass = VK_SUBPASS_EXTERNAL;
dependency.dstSubpass = 0;

dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.srcAccessMask = 0;

dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;

VkRenderPassCreateInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO;
renderPassInfo.attachmentCount = 1;
renderPassInfo.pAttachments = &colorAttachment;
renderPassInfo.subpassCount = 1;
renderPassInfo.pSubpasses = &subpass;
renderPassInfo.dependencyCount = 1;
renderPassInfo.pDependencies = &dependency;

if (vkCreateRenderPass(context->GetDevice().GetLogicalDevice(), &renderPassInfo, nullptr, &m_RenderPass) != VK_SUCCESS) {
printf("Framebuffer Renderpass not created\n");
}
else {
printf("Framebuffer Render Pass created\n");
}

VkImageView attachments[1];
attachments[0] = m_Attachments[0].ImageView;

VkFramebufferCreateInfo fbCreateInfo{};
fbCreateInfo.sType = VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO;
fbCreateInfo.renderPass = m_RenderPass;
fbCreateInfo.pAttachments = attachments;
fbCreateInfo.attachmentCount = 1;
fbCreateInfo.width = specs.Width;
fbCreateInfo.height = specs.Height;
fbCreateInfo.layers = 1;

if (vkCreateFramebuffer(context->GetDevice().GetLogicalDevice(), &fbCreateInfo, nullptr, &m_Framebuffer) != VK_SUCCESS) {
printf("Framebuffer not created\n");
}
else {
printf("Framebuffer created\n");
}
}

}
}
20 changes: 20 additions & 0 deletions Arcane/src/Arcane/Platform/Vulkan/VulkanFramebuffer.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
#pragma once

#include <vulkan/vulkan.h>
#include <vector>

#include "Arcane/Renderer/Framebuffer.h"

namespace Arcane {
class VulkanFramebuffer : public Framebuffer
{
public:
VulkanFramebuffer(FramebufferSpecifications& specs);

VkFramebuffer GetVulkanFramebuffer() { return m_Framebuffer; }

VkRenderPass GetFramebufferRenderPass() { return m_RenderPass; }
private:
struct FrameBufferAttachment
{
VkImage Image;
VkDeviceMemory ImageMemory;
VkImageView ImageView;
};

std::vector<FrameBufferAttachment> m_Attachments;

uint32_t m_Width;
uint32_t m_Height;

VkRenderPass m_RenderPass;
VkFramebuffer m_Framebuffer;
VkDescriptorImageInfo m_ImageDescriptor;
VkSampler m_ImageSampler;
};
}
10 changes: 9 additions & 1 deletion Arcane/src/Arcane/Platform/Vulkan/VulkanRenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@

namespace Arcane {

VulkanRenderPass::VulkanRenderPass()
VulkanRenderPass::VulkanRenderPass(RenderPassSpecs specs)
{
Application& app = Application::Get();
Window& window = app.GetWindow();
VulkanContext* _context = static_cast<VulkanContext*>(window.GetContext());
VkDevice logicalDevice = _context->GetDevice().GetLogicalDevice();


m_Specifications = specs;

VkAttachmentDescription colorAttachment{};
colorAttachment.format = _context->GetSwapChain().GetFormat();
colorAttachment.samples = VK_SAMPLE_COUNT_1_BIT;
Expand Down Expand Up @@ -59,4 +62,9 @@ namespace Arcane {
printf("Render Pass created\n");
}
}

RenderPassSpecs& VulkanRenderPass::GetRenderPassSpecs()
{
return m_Specifications;
}
}
6 changes: 5 additions & 1 deletion Arcane/src/Arcane/Platform/Vulkan/VulkanRenderPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,15 @@ namespace Arcane {
class VulkanRenderPass : public RenderPass
{
public:
VulkanRenderPass();
VulkanRenderPass(RenderPassSpecs specs);

VkRenderPass GetRenderPass() { return m_RenderPass; }

// Inherited via RenderPass
virtual RenderPassSpecs& GetRenderPassSpecs() override;
private:
VkRenderPass m_RenderPass;
RenderPassSpecs m_Specifications;

};
}
13 changes: 8 additions & 5 deletions Arcane/src/Arcane/Platform/Vulkan/VulkanRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "VulkanBuffer.h"
#include "VulkanUniformBuffer.h"
#include "VulkanRenderPass.h"
#include "VulkanFramebuffer.h"
#include "Arcane/Core/Application.h"

namespace Arcane {
Expand Down Expand Up @@ -31,7 +32,10 @@ namespace Arcane {
Application& app = Application::Get();
VulkanContext* _context = static_cast<VulkanContext*>(app.GetWindow().GetContext());
VulkanSwapChain& swapChain = _context->GetSwapChain();
VulkanRenderPass* vulkanRenderPass = static_cast<VulkanRenderPass*>(renderPass);

RenderPassSpecs& renderSpecs = renderPass->GetRenderPassSpecs();
VulkanFramebuffer* frameBuffer = static_cast<VulkanFramebuffer*>(renderSpecs.TargetFramebuffer);


auto swapChainCommandBuffers = swapChain.GetCommandBuffers();
auto swapChainFramebuffers = swapChain.GetSwapChainFramebuffers();
Expand All @@ -49,10 +53,10 @@ namespace Arcane {

VkRenderPassBeginInfo renderPassInfo{};
renderPassInfo.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO;
renderPassInfo.renderPass = vulkanRenderPass->GetRenderPass();
renderPassInfo.framebuffer = swapChainFramebuffers[i];
renderPassInfo.renderPass = frameBuffer->GetFramebufferRenderPass();
renderPassInfo.framebuffer = frameBuffer->GetVulkanFramebuffer();
renderPassInfo.renderArea.offset = { 0, 0 };
renderPassInfo.renderArea.extent = swapChain.GetExtent();
renderPassInfo.renderArea.extent = { 512, 512 };

VkClearValue clearColor = { 0.2f, 0.3f, 0.3f, 1.0f };
renderPassInfo.clearValueCount = 1;
Expand All @@ -67,7 +71,6 @@ namespace Arcane {
Application& app = Application::Get();
VulkanContext* _context = static_cast<VulkanContext*>(app.GetWindow().GetContext());
VulkanSwapChain& swapChain = _context->GetSwapChain();
VulkanRenderPass* vulkanRenderPass = static_cast<VulkanRenderPass*>(renderPass);

auto swapChainCommandBuffers = swapChain.GetCommandBuffers();
auto swapChainFramebuffers = swapChain.GetSwapChainFramebuffers();
Expand Down
23 changes: 21 additions & 2 deletions Arcane/src/Arcane/Renderer/Framebuffer.h
Original file line number Diff line number Diff line change
@@ -1,13 +1,32 @@
#pragma once

#include <iostream>
#include <glm/glm.hpp>
#include <initializer_list>

namespace Arcane {

enum class FramebufferAttachmentType
{
COLOR,
DEPTH
};

struct FrameBufferAttachmentSpecs
{
FrameBufferAttachmentSpecs() = default;
FrameBufferAttachmentSpecs(std::initializer_list<FramebufferAttachmentType> attachments)
: m_Attachments(attachments) {}

std::initializer_list<FramebufferAttachmentType> m_Attachments;
};

struct FramebufferSpecifications
{
uint32_t width = 0;
uint32_t height = 0;
uint32_t Width = 0;
uint32_t Height = 0;
glm::vec4 ClearColor = {0.0f, 0.0f, 0.0f, 1.0f};
FrameBufferAttachmentSpecs AttachmentSpecs;
};

class Framebuffer
Expand Down
4 changes: 2 additions & 2 deletions Arcane/src/Arcane/Renderer/RenderPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace Arcane {

RenderPass* RenderPass::Create()
RenderPass* RenderPass::Create(RenderPassSpecs specs)
{
switch (RendererAPI::Current())
{
case RendererAPIType::Vulkan: return new VulkanRenderPass();
case RendererAPIType::Vulkan: return new VulkanRenderPass(specs);
default:
break;
}
Expand Down
11 changes: 8 additions & 3 deletions Arcane/src/Arcane/Renderer/RenderPass.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
#pragma once

#include <glm/glm.hpp>
#include "Framebuffer.h"

namespace Arcane {
struct RenderPassSpecs
{
Framebuffer* TargetFramebuffer;
};

class RenderPass
{
public:


static RenderPass* Create();
virtual RenderPassSpecs& GetRenderPassSpecs() = 0;
static RenderPass* Create(RenderPassSpecs specs);
private:

};
Expand Down

0 comments on commit 224acd6

Please sign in to comment.