From 2717f02f0ffdaa370c20cc34aa8c3d48170826ea Mon Sep 17 00:00:00 2001 From: PancakeTAS Date: Sun, 29 Jun 2025 16:45:35 +0200 Subject: [PATCH] core pipeline object --- include/core/pipeline.hpp | 54 ++++++++++++++++++++++++++++++++++++++ src/core/pipeline.cpp | 55 +++++++++++++++++++++++++++++++++++++++ src/main.cpp | 2 ++ 3 files changed, 111 insertions(+) create mode 100644 include/core/pipeline.hpp create mode 100644 src/core/pipeline.cpp diff --git a/include/core/pipeline.hpp b/include/core/pipeline.hpp new file mode 100644 index 0000000..d951359 --- /dev/null +++ b/include/core/pipeline.hpp @@ -0,0 +1,54 @@ +#ifndef PIPELINE_HPP +#define PIPELINE_HPP + +#include "core/shadermodule.hpp" +#include "device.hpp" + +#include + +#include + +namespace Vulkan::Core { + + /// + /// C++ wrapper class for a Vulkan pipeline. + /// + /// This class manages the lifetime of a Vulkan pipeline. + /// + class Pipeline { + public: + /// + /// Create a compute pipeline. + /// + /// @param device Vulkan device + /// @param shader Shader module to use for the pipeline. + /// + /// @throws std::invalid_argument if the device is invalid. + /// @throws ls::vulkan_error if object creation fails. + /// + Pipeline(const Device& device, const ShaderModule& shader); + + /// Get the Vulkan handle. + [[nodiscard]] auto handle() const { return *this->pipeline; } + /// Get the pipeline layout. + [[nodiscard]] auto getLayout() const { return *this->layout; } + + /// Check whether the object is valid. + [[nodiscard]] bool isValid() const { return static_cast(this->pipeline); } + /// if (obj) operator. Checks if the object is valid. + explicit operator bool() const { return this->isValid(); } + + /// Trivially copyable, moveable and destructible + Pipeline(const Pipeline&) noexcept = default; + Pipeline& operator=(const Pipeline&) noexcept = default; + Pipeline(Pipeline&&) noexcept = default; + Pipeline& operator=(Pipeline&&) noexcept = default; + ~Pipeline() = default; + private: + std::shared_ptr pipeline; + std::shared_ptr layout; + }; + +} + +#endif // PIPELINE_HPP diff --git a/src/core/pipeline.cpp b/src/core/pipeline.cpp new file mode 100644 index 0000000..b60fb7b --- /dev/null +++ b/src/core/pipeline.cpp @@ -0,0 +1,55 @@ +#include "core/pipeline.hpp" +#include "utils/exceptions.hpp" + +using namespace Vulkan::Core; + +Pipeline::Pipeline(const Device& device, const ShaderModule& shader) { + if (!device) + throw std::invalid_argument("Invalid Vulkan device"); + + // create pipeline layout + VkDescriptorSetLayout shaderLayout = shader.getDescriptorSetLayout(); + const VkPipelineLayoutCreateInfo layoutDesc{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, + .setLayoutCount = 1, + .pSetLayouts = &shaderLayout, + }; + VkPipelineLayout layoutHandle{}; + auto res = vkCreatePipelineLayout(device.handle(), &layoutDesc, nullptr, &layoutHandle); + if (res != VK_SUCCESS || !layoutHandle) + throw ls::vulkan_error(res, "Failed to create pipeline layout"); + + // store layout in shared ptr + this->layout = std::shared_ptr( + new VkPipelineLayout(layoutHandle), + [dev = device.handle()](VkPipelineLayout* layout) { + vkDestroyPipelineLayout(dev, *layout, nullptr); + } + ); + + // create pipeline + const VkPipelineShaderStageCreateInfo shaderStageInfo{ + .sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, + .stage = VK_SHADER_STAGE_COMPUTE_BIT, + .module = shader.handle(), + .pName = "main", + }; + const VkComputePipelineCreateInfo pipelineDesc{ + .sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, + .stage = shaderStageInfo, + .layout = layoutHandle, + }; + VkPipeline pipelineHandle{}; + res = vkCreateComputePipelines(device.handle(), + VK_NULL_HANDLE, 1, &pipelineDesc, nullptr, &pipelineHandle); + if (res != VK_SUCCESS || !pipelineHandle) + throw ls::vulkan_error(res, "Failed to create compute pipeline"); + + // store pipeline in shared ptr + this->pipeline = std::shared_ptr( + new VkPipeline(pipelineHandle), + [dev = device.handle()](VkPipeline* pipeline) { + vkDestroyPipeline(dev, *pipeline, nullptr); + } + ); +} diff --git a/src/main.cpp b/src/main.cpp index ca594f8..b4df0a9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,3 +1,4 @@ +#include "core/pipeline.hpp" #include "core/shadermodule.hpp" #include "device.hpp" #include "instance.hpp" @@ -23,6 +24,7 @@ int main() { VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER } ); + const Vulkan::Core::Pipeline computePipeline(device, computeShader); std::cerr << "Application finished" << '\n'; return 0;