Skip to content
Snippets Groups Projects
Commit b68d43fe authored by Artur Wasmut's avatar Artur Wasmut
Browse files

initial implementation of a cheap renderpass struct/class.

parent 74ff8e70
No related branches found
No related tags found
4 merge requests!12Resolve "Swapchain Class",!7Resolve "Shader Program Class",!5Resolve "Pipeline State Object",!4Resolve "Renderpass Class"
Pipeline #24721 passed
...@@ -7,6 +7,9 @@ set(vkcv_sources ...@@ -7,6 +7,9 @@ set(vkcv_sources
${vkcv_include}/vkcv/Core.hpp ${vkcv_include}/vkcv/Core.hpp
${vkcv_source}/vkcv/Core.cpp ${vkcv_source}/vkcv/Core.cpp
${vkcv_include}/vkcv/Renderpass.hpp
${vkcv_source}/vkcv/Renderpass.cpp
${vkcv_include}/vkcv/Handles.hpp ${vkcv_include}/vkcv/Handles.hpp
${vkcv_source}/vkcv/Handles.cpp ${vkcv_source}/vkcv/Handles.cpp
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <vulkan/vulkan.hpp> #include <vulkan/vulkan.hpp>
#include "vkcv/Context.hpp" #include "vkcv/Context.hpp"
#include "vkcv/Renderpass.hpp"
#include "vkcv/Handles.hpp" #include "vkcv/Handles.hpp"
namespace vkcv namespace vkcv
...@@ -29,11 +30,15 @@ namespace vkcv ...@@ -29,11 +30,15 @@ namespace vkcv
Core() = delete; Core() = delete;
Context m_Context; Context m_Context;
uint64_t m_NextPassId;
std::vector<vk::RenderPass> m_Renderpasses;
public: public:
/** /**
* Destructor of #Core destroys the Vulkan objects contained in the core's context. * Destructor of #Core destroys the Vulkan objects contained in the core's context.
*/ */
~Core() noexcept = default; ~Core() noexcept;
/** /**
* Copy-constructor of #Core is deleted! * Copy-constructor of #Core is deleted!
...@@ -93,7 +98,11 @@ namespace vkcv ...@@ -93,7 +98,11 @@ namespace vkcv
// TODO: // TODO:
BufferHandle createBuffer(const Buffer &buf); BufferHandle createBuffer(const Buffer &buf);
PassHandle createRenderPass(const Renderpass &pass) ;
[[nodiscard]]
bool createRenderpass(const Renderpass &pass, RenderpassHandle &handle);
// TODO:
PipelineHandle createPipeline(const Pipeline &pipeline); PipelineHandle createPipeline(const Pipeline &pipeline);
}; };
......
...@@ -11,6 +11,6 @@ namespace vkcv ...@@ -11,6 +11,6 @@ namespace vkcv
{ {
// Handle returned for any buffer created with the core/context objects // Handle returned for any buffer created with the core/context objects
struct BufferHandle {uint64_t id;}; struct BufferHandle {uint64_t id;};
struct PassHandle {uint64_t id;}; struct RenderpassHandle {uint64_t id;};
struct PipelineHandle {uint64_t id;}; struct PipelineHandle {uint64_t id;};
} }
#pragma once
#include <vector>
namespace vkcv
{
enum class AttachmentLayout
{
UNDEFINED,
GENERAL,
COLOR_ATTACHMENT,
SHADER_READ_ONLY,
DEPTH_STENCIL_ATTACHMENT,
DEPTH_STENCIL_READ_ONLY,
TRANSFER_SRC,
TRANSFER_DST,
PRESENTATION
};
enum class AttachmentOperation
{
LOAD,
CLEAR,
STORE,
DONT_CARE
};
struct AttachmentDescription
{
AttachmentDescription() = delete;
AttachmentDescription(AttachmentLayout initial,
AttachmentLayout in_pass,
AttachmentLayout final,
AttachmentOperation store_op,
AttachmentOperation load_op) noexcept;
AttachmentLayout layout_initial;
AttachmentLayout layout_in_pass;
AttachmentLayout layout_final;
AttachmentOperation store_operation;
AttachmentOperation load_operation;
};
struct Renderpass
{
Renderpass() noexcept = default;
std::vector<AttachmentDescription> attachments{};
};
}
\ No newline at end of file
...@@ -33,6 +33,38 @@ int main(int argc, const char** argv) { ...@@ -33,6 +33,38 @@ int main(int argc, const char** argv) {
default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl; default: std::cout << "Unknown GPU vendor?! Either you're on an exotic system or your driver is broken..." << std::endl;
} }
// an example attachment for passes that output to the window
vkcv::AttachmentDescription present_color_attachment(vkcv::AttachmentLayout::UNDEFINED,
vkcv::AttachmentLayout::COLOR_ATTACHMENT,
vkcv::AttachmentLayout::PRESENTATION,
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR);
// an example attachment for passes that output to a depth buffer
vkcv::AttachmentDescription present_depth_attachment(vkcv::AttachmentLayout::UNDEFINED,
vkcv::AttachmentLayout::DEPTH_STENCIL_ATTACHMENT,
vkcv::AttachmentLayout::DEPTH_STENCIL_READ_ONLY,
vkcv::AttachmentOperation::STORE,
vkcv::AttachmentOperation::CLEAR);
// this pass will output to the window, and produce a depth buffer
vkcv::Renderpass test_pass{};
test_pass.attachments.push_back(present_color_attachment);
test_pass.attachments.push_back(present_depth_attachment);
std::vector<vkcv::RenderpassHandle> test_handles{};
// render pass creation test
for(uint32_t i = 0; i < 1000; i++)
{
vkcv::RenderpassHandle tmp_handle{};
if(!core.createRenderpass(test_pass, tmp_handle))
{
std::cout << "Oops. Something went wrong in the renderpass creation. Exiting." << std::endl;
return EXIT_FAILURE;
}
test_handles.push_back(tmp_handle);
}
std::cout << "Wow. You just made 1000 render passes. (That are all identical, though...)" << std::endl;
/* /*
* BufferHandle triangleVertices = core.createBuffer(vertices); * BufferHandle triangleVertices = core.createBuffer(vertices);
* BufferHandle triangleIndices = core.createBuffer(indices); * BufferHandle triangleIndices = core.createBuffer(indices);
......
...@@ -8,6 +8,51 @@ ...@@ -8,6 +8,51 @@
namespace vkcv namespace vkcv
{ {
static vk::ImageLayout getVkLayoutFromAttachLayout(AttachmentLayout layout)
{
switch(layout)
{
case AttachmentLayout::GENERAL:
return vk::ImageLayout::eGeneral;
case AttachmentLayout::COLOR_ATTACHMENT:
return vk::ImageLayout::eColorAttachmentOptimal;
case AttachmentLayout::SHADER_READ_ONLY:
return vk::ImageLayout::eShaderReadOnlyOptimal;
case AttachmentLayout::DEPTH_STENCIL_ATTACHMENT:
return vk::ImageLayout::eDepthStencilAttachmentOptimal;
case AttachmentLayout::DEPTH_STENCIL_READ_ONLY:
return vk::ImageLayout::eDepthStencilReadOnlyOptimal;
case AttachmentLayout::PRESENTATION:
return vk::ImageLayout::ePresentSrcKHR;
default:
return vk::ImageLayout::eUndefined;
}
}
static vk::AttachmentStoreOp getVkStoreOpFromAttachOp(AttachmentOperation op)
{
switch(op)
{
case AttachmentOperation::STORE:
return vk::AttachmentStoreOp::eStore;
default:
return vk::AttachmentStoreOp::eDontCare;
}
}
static vk::AttachmentLoadOp getVKLoadOpFromAttachOp(AttachmentOperation op)
{
switch(op)
{
case AttachmentOperation::LOAD:
return vk::AttachmentLoadOp::eLoad;
case AttachmentOperation::CLEAR:
return vk::AttachmentLoadOp::eClear;
default:
return vk::AttachmentLoadOp::eDontCare;
}
}
/** /**
* @brief The physical device is evaluated by three categories: * @brief The physical device is evaluated by three categories:
* discrete GPU vs. integrated GPU, amount of queues and its abilities, and VRAM.physicalDevice. * discrete GPU vs. integrated GPU, amount of queues and its abilities, and VRAM.physicalDevice.
...@@ -268,6 +313,85 @@ namespace vkcv ...@@ -268,6 +313,85 @@ namespace vkcv
} }
Core::Core(Context &&context) noexcept : Core::Core(Context &&context) noexcept :
m_Context(std::move(context)) m_Context(std::move(context)),
m_NextPassId(0),
m_Renderpasses{}
{} {}
Core::~Core() noexcept
{
for(const auto &pass : m_Renderpasses)
m_Context.m_Device.destroy(pass);
m_Renderpasses.clear();
m_NextPassId = 0;
}
bool Core::createRenderpass(const Renderpass &pass, RenderpassHandle &handle)
{
// description of all {color, input, depth/stencil} attachments of the render pass
std::vector<vk::AttachmentDescription> attachmentDescriptions{};
// individual references to color attachments (of a subpass)
std::vector<vk::AttachmentReference> colorAttachmentReferences{};
// individual reference to depth attachment (of a subpass)
vk::AttachmentReference depthAttachmentReference{};
for(uint32_t i = 0; i < pass.attachments.size(); i++)
{
// TODO: Renderpass struct should hold proper format information
vk::Format format;
if(pass.attachments[i].layout_in_pass == AttachmentLayout::DEPTH_STENCIL_ATTACHMENT)
{
format = vk::Format::eD16Unorm; // depth attachments;
depthAttachmentReference.attachment = i;
depthAttachmentReference.layout = getVkLayoutFromAttachLayout(pass.attachments[i].layout_in_pass);
}
else
{
format = vk::Format::eB8G8R8A8Srgb; // color attachments, compatible with swapchain
vk::AttachmentReference attachmentRef(i, getVkLayoutFromAttachLayout(pass.attachments[i].layout_in_pass));
colorAttachmentReferences.push_back(attachmentRef);
}
vk::AttachmentDescription attachmentDesc({},
format,
vk::SampleCountFlagBits::e1,
getVKLoadOpFromAttachOp(pass.attachments[i].load_operation),
getVkStoreOpFromAttachOp(pass.attachments[i].load_operation),
vk::AttachmentLoadOp::eDontCare,
vk::AttachmentStoreOp::eDontCare,
getVkLayoutFromAttachLayout(pass.attachments[i].layout_initial),
getVkLayoutFromAttachLayout(pass.attachments[i].layout_final));
attachmentDescriptions.push_back(attachmentDesc);
}
vk::SubpassDescription subpassDescription({},
vk::PipelineBindPoint::eGraphics,
0,
{},
static_cast<uint32_t>(colorAttachmentReferences.size()),
colorAttachmentReferences.data(),
{},
&depthAttachmentReference,
0,
{});
vk::RenderPassCreateInfo passInfo({},
static_cast<uint32_t>(attachmentDescriptions.size()),
attachmentDescriptions.data(),
1,
&subpassDescription,
0,
{});
vk::RenderPass vkObject{nullptr};
if(m_Context.m_Device.createRenderPass(&passInfo, nullptr, &vkObject) != vk::Result::eSuccess)
return false;
m_Renderpasses.push_back(vkObject);
handle.id = m_NextPassId++;
return true;
}
} }
#include "vkcv/Renderpass.hpp"
namespace vkcv
{
AttachmentDescription::AttachmentDescription(AttachmentLayout initial,
AttachmentLayout in_pass,
AttachmentLayout final,
AttachmentOperation store_op,
AttachmentOperation load_op) noexcept :
layout_initial{initial},
layout_in_pass{in_pass},
layout_final{final},
store_operation{store_op},
load_operation{load_op}
{};
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment