From 703c817a10fb98173b60b04d225375489eaca9f9 Mon Sep 17 00:00:00 2001 From: Mara Vogt <mvogt@uni-koblenz.de> Date: Thu, 13 May 2021 16:38:50 +0200 Subject: [PATCH] [#11] Added Pipeline Class added a simple pipeline class modified core and added a create pipeline function --- config/Sources.cmake | 3 + include/vkcv/Core.hpp | 12 +++- include/vkcv/Pipeline.hpp | 30 +++++++++ src/vkcv/Core.cpp | 137 +++++++++++++++++++++++++++++++++++++- src/vkcv/Pipeline.cpp | 13 ++++ 5 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 include/vkcv/Pipeline.hpp create mode 100644 src/vkcv/Pipeline.cpp diff --git a/config/Sources.cmake b/config/Sources.cmake index 80fa3a09..b0c72310 100644 --- a/config/Sources.cmake +++ b/config/Sources.cmake @@ -12,4 +12,7 @@ set(vkcv_sources ${vkcv_include}/vkcv/Window.hpp ${vkcv_source}/vkcv/Window.cpp + + ${vkcv_include}/vkcv/Pipeline.hpp + ${vkcv_source}/vkcv/Pipeline.cpp ) diff --git a/include/vkcv/Core.hpp b/include/vkcv/Core.hpp index 7a7f3be7..aa5dc52e 100644 --- a/include/vkcv/Core.hpp +++ b/include/vkcv/Core.hpp @@ -7,13 +7,13 @@ #include <vulkan/vulkan.hpp> #include "vkcv/Context.hpp" #include "vkcv/Handles.hpp" +#include "vkcv/Pipeline.hpp" namespace vkcv { // TODO: class Buffer; class Renderpass; - class Pipeline; class Core final { @@ -29,6 +29,14 @@ namespace vkcv Core() = delete; Context m_Context; + + uint64_t m_NextPipelineId; + std::vector<vk::Pipeline> m_Pipelines; + std::vector<vk::PipelineLayout> m_PipelineLayouts; + + uint64_t m_NextRenderpassId; + std::vector<vk::RenderPass> m_Renderpasses; + public: /** * Destructor of #Core destroys the Vulkan objects contained in the core's context. @@ -94,7 +102,7 @@ namespace vkcv // TODO: BufferHandle createBuffer(const Buffer &buf); PassHandle createRenderPass(const Renderpass &pass) ; - PipelineHandle createPipeline(const Pipeline &pipeline); + bool createPipeline(const Pipeline &pipeline, PipelineHandle &handle); }; } diff --git a/include/vkcv/Pipeline.hpp b/include/vkcv/Pipeline.hpp new file mode 100644 index 00000000..a0b5fdd2 --- /dev/null +++ b/include/vkcv/Pipeline.hpp @@ -0,0 +1,30 @@ +/** + * @authors Mara Vogt, Mark Mints + * @file src/vkcv/Pipeline.hpp + * @brief Pipeline class to handle shader stages + */ + +#ifndef VKCV_PIPELINE_HPP +#define VKCV_PIPELINE_HPP + +#include <vector> +#include <cstdint> +#include "vkcv/Handles.hpp" + +namespace vkcv { + + class Pipeline { + + public: + Pipeline() = delete; + Pipeline(const std::vector<uint32_t> &vertexCode, const std::vector<uint32_t> &fragCode, uint32_t height, uint32_t width, PassHandle &passHandle); + + std::vector<uint32_t> m_vertexCode; + std::vector<uint32_t> m_fragCode; + uint32_t m_height; + uint32_t m_width; + PassHandle m_passHandle; + }; + +} +#endif //VKCV_PIPELINE_HPP diff --git a/src/vkcv/Core.cpp b/src/vkcv/Core.cpp index 0c32f4e4..eb3195b4 100644 --- a/src/vkcv/Core.cpp +++ b/src/vkcv/Core.cpp @@ -268,6 +268,141 @@ namespace vkcv } Core::Core(Context &&context) noexcept : - m_Context(std::move(context)) + m_Context(std::move(context)), + m_NextPipelineId(0), + m_Pipelines{}, + m_PipelineLayouts{}, + m_NextRenderpassId(0), + m_Renderpasses{} {} + + bool Core::createPipeline(const Pipeline &pipeline, PipelineHandle &handle) { + + // vertex shader stage + vk::ShaderModuleCreateInfo vertexModuleInfo({},pipeline.m_vertexCode.size(), pipeline.m_vertexCode.data()); + vk::ShaderModule vertexModule{}; + if(m_Context.m_Device.createShaderModule(&vertexModuleInfo, nullptr, &vertexModule) != vk::Result::eSuccess){ + return false; + }; + vk::PipelineShaderStageCreateInfo pipelineVertexShaderStageInfo({}, vk::ShaderStageFlagBits::eVertex,vertexModule, "main", + nullptr); + + // fragment shader stage + vk::ShaderModuleCreateInfo fragmentModuleInfo({},pipeline.m_fragCode.size(), pipeline.m_fragCode.data()); + vk::ShaderModule fragmentModule{}; + if(m_Context.m_Device.createShaderModule(&fragmentModuleInfo, nullptr, &fragmentModule) != vk::Result::eSuccess){ + return false; + }; + vk::PipelineShaderStageCreateInfo pipelineFragmentShaderStageInfo({}, vk::ShaderStageFlagBits::eFragment,fragmentModule, "main", + nullptr); + + // vertex input state + vk::VertexInputBindingDescription vertexInputBindingDescription(0,12,vk::VertexInputRate::eVertex); + vk::VertexInputAttributeDescription vertexInputAttributeDescription(0, 0, vk::Format::eR32G32B32Sfloat, 0); + + vk::PipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo({}, 1, &vertexInputBindingDescription, 1, &vertexInputAttributeDescription); + + // input assembly state + vk::PipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateCreateInfo({}, vk::PrimitiveTopology::eTriangleList, false); + + // viewport state + vk::Viewport viewport(0.f, 0.f, static_cast<float>(pipeline.m_width), static_cast<float>(pipeline.m_height), 0.f, 1.f); + vk::Rect2D scissor({0,0},{pipeline.m_width, pipeline.m_height}); + vk::PipelineViewportStateCreateInfo pipelineViewportStateCreateInfo({}, 1, &viewport, 1, &scissor); + + // rasterization state + vk::PipelineRasterizationStateCreateInfo pipelineRasterizationStateCreateInfo( + {}, + false, + false, + vk::PolygonMode::eFill, + vk::CullModeFlagBits::eNone, + vk::FrontFace::eCounterClockwise, + false, + 0.f, + 0.f, + 0.f, + 1.f + ); + + // multisample state + vk::PipelineMultisampleStateCreateInfo pipelineMultisampleStateCreateInfo( + {}, + vk::SampleCountFlagBits::e1, + false, + 0.f, + nullptr, + false, + false + ); + + // color blend state + vk::ColorComponentFlags colorWriteMask(VK_COLOR_COMPONENT_R_BIT | + VK_COLOR_COMPONENT_G_BIT | + VK_COLOR_COMPONENT_B_BIT | + VK_COLOR_COMPONENT_A_BIT); + vk::PipelineColorBlendAttachmentState colorBlendAttachmentState( + false, + vk::BlendFactor::eOne, + vk::BlendFactor::eOne, + vk::BlendOp::eAdd, + vk::BlendFactor::eOne, + vk::BlendFactor::eOne, + vk::BlendOp::eAdd, + colorWriteMask + ); + vk::PipelineColorBlendStateCreateInfo pipelineColorBlendStateCreateInfo( + {}, + false, + vk::LogicOp::eClear, + 0, + &colorBlendAttachmentState, + {1.f,1.f,1.f,1.f} + ); + + // pipeline layout + vk::PipelineLayoutCreateInfo pipelineLayoutCreateInfo( + {}, + 0, + {}, + 0, + {} + ); + vk::PipelineLayout vkPipelineLayout{}; + if(m_Context.m_Device.createPipelineLayout(&pipelineLayoutCreateInfo, nullptr, &vkPipelineLayout) != vk::Result::eSuccess){ + return false; + } + + // graphics pipeline create + std::vector<vk::PipelineShaderStageCreateInfo> shaderStages = {pipelineVertexShaderStageInfo, pipelineFragmentShaderStageInfo}; + vk::GraphicsPipelineCreateInfo graphicsPipelineCreateInfo( + {}, + static_cast<uint32_t>(shaderStages.size()), + shaderStages.data(), + &pipelineVertexInputStateCreateInfo, + &pipelineInputAssemblyStateCreateInfo, + nullptr, + &pipelineViewportStateCreateInfo, + &pipelineRasterizationStateCreateInfo, + &pipelineMultisampleStateCreateInfo, + nullptr, + &pipelineColorBlendStateCreateInfo, + nullptr, + vkPipelineLayout, + m_Renderpasses[pipeline.m_passHandle.id], + 0, + {}, + 0 + ); + + vk::Pipeline vkPipeline{}; + if(m_Context.m_Device.createGraphicsPipelines(nullptr, 1, &graphicsPipelineCreateInfo, nullptr, &vkPipeline) != vk::Result::eSuccess){ + return false; + } + + m_Pipelines.push_back(vkPipeline); + m_PipelineLayouts.push_back(vkPipelineLayout); + handle.id = m_NextPipelineId++; + return true; + } } diff --git a/src/vkcv/Pipeline.cpp b/src/vkcv/Pipeline.cpp new file mode 100644 index 00000000..b5078e95 --- /dev/null +++ b/src/vkcv/Pipeline.cpp @@ -0,0 +1,13 @@ +/** + * @authors Mara Vogt, Mark Mints + * @file src/vkcv/Pipeline.cpp + * @brief Pipeline class to handle shader stages + */ + +#include "vkcv/Pipeline.hpp" + +namespace vkcv { + + Pipeline::Pipeline(const std::vector<uint32_t> &vertexCode, const std::vector<uint32_t> &fragCode, uint32_t height, uint32_t width, PassHandle &passHandle): + m_vertexCode(vertexCode), m_fragCode(fragCode), m_height(height), m_width(width), m_passHandle(passHandle) {} +} -- GitLab