core pipeline object

This commit is contained in:
PancakeTAS 2025-06-29 16:45:35 +02:00
parent ce6542a039
commit 2717f02f0f
No known key found for this signature in database
3 changed files with 111 additions and 0 deletions

54
include/core/pipeline.hpp Normal file
View file

@ -0,0 +1,54 @@
#ifndef PIPELINE_HPP
#define PIPELINE_HPP
#include "core/shadermodule.hpp"
#include "device.hpp"
#include <vulkan/vulkan_core.h>
#include <memory>
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<bool>(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<VkPipeline> pipeline;
std::shared_ptr<VkPipelineLayout> layout;
};
}
#endif // PIPELINE_HPP

55
src/core/pipeline.cpp Normal file
View file

@ -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<VkPipelineLayout>(
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<VkPipeline>(
new VkPipeline(pipelineHandle),
[dev = device.handle()](VkPipeline* pipeline) {
vkDestroyPipeline(dev, *pipeline, nullptr);
}
);
}

View file

@ -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;