Extended pipeline to support adding vertex bindings Vertex bindings can now be added via a template function that assumes that the type implements the following; - A function matching the signature of PFN_GetVertexInputBindingDescription and with the name get_binding_description - A function matching the signature of PFN_GetVertexAttributeDescriptions and with the name get_attribute_descriptions GetVertexAttributeDescriptions should set the num_attachments to the number of attachments if and only if the attachment output pointer is nullptr. If the output pointer is not nullptr, num_attachments should be treated as a size. Return VK_SUCCESS on success, or a different value otherwise.
92 lines
3.9 KiB
C++
92 lines
3.9 KiB
C++
#pragma once
|
|
#include "vulkan/basalt_render_pass.h"
|
|
|
|
namespace basalt
|
|
{
|
|
typedef VkVertexInputBindingDescription (*PFN_GetVertexInputBindingDescription)(void);
|
|
typedef VkResult(*PFN_GetVertexAttributeDescriptions)(VkVertexInputAttributeDescription* out_attachments, u32* num_attachments);
|
|
|
|
|
|
class Pipeline
|
|
{
|
|
public:
|
|
Pipeline(const Pipeline& src) = delete;
|
|
Pipeline& operator =(const Pipeline& src) = delete;
|
|
Pipeline(Pipeline&& other) noexcept;
|
|
Pipeline& operator =(Pipeline&& other) noexcept;
|
|
|
|
Pipeline(basalt::Device& device, VkPipeline pipeline, VkPipelineLayout layout);
|
|
~Pipeline();
|
|
|
|
void swap(Pipeline& other) noexcept;
|
|
|
|
VkPipeline vk = VK_NULL_HANDLE;
|
|
VkPipelineLayout layout = VK_NULL_HANDLE;
|
|
basalt::Device* device = nullptr;
|
|
bool should_free = true;
|
|
};
|
|
|
|
class PipelineBuilder
|
|
{
|
|
public:
|
|
PipelineBuilder(basalt::Device& device, VkExtent2D extent, VkPipeline previous_pipeline=VK_NULL_HANDLE);
|
|
~PipelineBuilder();
|
|
|
|
PipelineBuilder& add_shader(const char* fpath, VkShaderStageFlagBits stage, const char* entry="main");
|
|
PipelineBuilder& add_dynamic_state(const VkDynamicState state);
|
|
PipelineBuilder& add_dynamic_states(const VkDynamicState* states, const u32 num_states);
|
|
PipelineBuilder& add_dynamic_states(const basalt::darray<VkDynamicState>& states);
|
|
PipelineBuilder& set_render_pass(VkRenderPass render_pass);
|
|
PipelineBuilder& add_colour_attachment(VkPipelineColorBlendAttachmentState attachment);
|
|
PipelineBuilder& add_vertex_binding(VkVertexInputBindingDescription binding, VkVertexInputAttributeDescription* attributes, u32 num_attributes);
|
|
|
|
template <typename T>
|
|
PipelineBuilder& add_vertex_binding(void);
|
|
|
|
Pipeline build();
|
|
|
|
|
|
VkPipelineRasterizationStateCreateInfo raster_ci;
|
|
VkPipelineColorBlendStateCreateInfo colour_blend_ci;
|
|
VkPipelineLayoutCreateInfo layout_ci;
|
|
VkPipelineVertexInputStateCreateInfo vertex_ci;
|
|
VkPipelineMultisampleStateCreateInfo multisample_ci;
|
|
VkPipelineViewportStateCreateInfo viewport_ci;
|
|
VkPipelineInputAssemblyStateCreateInfo assembly_ci;
|
|
VkPipelineDynamicStateCreateInfo dynamic_state_ci;
|
|
basalt::darray<VkVertexInputAttributeDescription> vertex_input_attributes;
|
|
basalt::darray<VkVertexInputBindingDescription> vertex_binding_description;
|
|
basalt::darray<VkShaderModule> shader_modules;
|
|
basalt::darray<VkPipelineShaderStageCreateInfo> shader_stages;
|
|
basalt::darray<VkPipelineColorBlendAttachmentState> colour_attachments;
|
|
basalt::darray<VkDynamicState> dynamic_states;
|
|
VkViewport viewport;
|
|
VkRect2D scissor;
|
|
basalt::Device& device;
|
|
VkRenderPass render_pass = VK_NULL_HANDLE;
|
|
VkPipeline previous_pipeline = VK_NULL_HANDLE;
|
|
protected:
|
|
/// <summary>
|
|
/// Will read all of the contents of a file into outptr
|
|
/// Should outptr not be big enough or nullptr, it will be allocated
|
|
/// If it is not big enough it will be reallocated
|
|
/// </summary>
|
|
/// <param name="fpath">Path to the file to read</param>
|
|
/// <param name="outptr">A reference to a pointer that may be updated</param>
|
|
/// <param name="size">Size of an existing allocation associated with outptr</param>
|
|
/// <returns>Number of bytes read from the file</returns>
|
|
static size_t read_file(const char* fpath, char*& outptr, size_t& outptr_size);
|
|
};
|
|
template<typename T>
|
|
inline PipelineBuilder& PipelineBuilder::add_vertex_binding(void)
|
|
{
|
|
VkResult err = VK_SUCCESS;
|
|
this->vertex_binding_description.push_back(T::get_binding_description());
|
|
u32 sz = 0;
|
|
VK_ASSERT(T::get_attribute_descriptions(nullptr, &sz), "Failed to get number of vertex attribute descriptions for object\n\tAt %s:%d\n\tError %s\n\tObject %s\n", typeid(T).name());
|
|
this->vertex_input_attributes.expand(sz);
|
|
VK_ASSERT(T::get_attribute_descriptions(this->vertex_input_attributes.end(), &sz), "Failed to get vertex attribute descriptions for object\n\tAt %s:%d\n\tError %s\n\tObject %s\n", typeid(T).name());
|
|
this->vertex_input_attributes.resize(this->vertex_input_attributes.m_nelements + sz);
|
|
return *this;
|
|
}
|
|
} |