This commit is contained in:
Martin Slachta
2026-07-18 14:31:15 +02:00
commit a04f0dc262
3343 changed files with 1140208 additions and 0 deletions
@@ -0,0 +1,25 @@
#pragma once
#include <vulkan/vulkan.h>
/**
* Defines blending operations for a graphics pipeline.
*/
struct BlendingInfo {
VkBlendOp colorBlendOp;
VkBlendFactor srcColorBlendFactor;
VkBlendFactor dstColorBlendFactor;
VkBlendOp alphaBlendOp;
VkBlendFactor srcAlphaBlendFactor;
VkBlendFactor dstAlphaBlendFactor;
BlendingInfo() :
colorBlendOp(VK_BLEND_OP_ADD),
srcColorBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA),
dstColorBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA),
alphaBlendOp(VK_BLEND_OP_ADD),
srcAlphaBlendFactor(VK_BLEND_FACTOR_SRC_ALPHA),
dstAlphaBlendFactor(VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA) {
}
};
@@ -0,0 +1,21 @@
#pragma once
#include "Shader.hpp"
#include "Pipeline.hpp"
#include <volk.h>
namespace lft {
class ComputePipelineBuilder {
private:
const Shader* m_shader;
VkPipelineLayout m_layout;
public:
ComputePipelineBuilder(const Shader* shader, VkPipelineLayout layout);
Pipeline build(const Gpu* gpu);
};
}
@@ -0,0 +1,8 @@
#pragma once
#include "ShaderBuilder.hpp"
class GlslShaderBuilder : public ShaderBuilder {
public:
Shader from_file(std::string path) override;
};
+66
View File
@@ -0,0 +1,66 @@
#pragma once
#include <volk.h>
#include <vector>
#include <optional>
#include "RenderContext.hpp"
#include "Shader.hpp"
#include "Gpu.hpp"
/**
* Abstracts a Vulkan pipeline
*/
class Pipeline {
VkPipeline m_pipeline;
VkPipelineLayout m_layout;
public:
/**
* Wraps new pipeline with layout
* @param layout pipeline layout
* @param pipeline pipeline
*/
Pipeline(VkPipelineLayout layout, VkPipeline pipeline) :
m_layout(layout), m_pipeline(pipeline) {
}
VkPipeline pipeline() const {
return m_pipeline;
}
VkPipelineLayout pipeline_layout() const {
return m_layout;
}
Pipeline& use(RenderContext *pRenderContext) {
vkCmdBindPipeline(pRenderContext->command_buffer(),
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_pipeline);
return *this;
}
Pipeline& bind_input_set(RenderContext *pRenderContext, uint32_t idx, uint32_t num, VkDescriptorSet *pSets) {
vkCmdBindDescriptorSets(pRenderContext->command_buffer(),
VK_PIPELINE_BIND_POINT_GRAPHICS,
m_layout,
idx, num, pSets,
0, nullptr);
return *this;
}
inline void set_debug_name(const Gpu* gpu, const std::string name) const {
#if LOFT_DEBUG
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_PIPELINE,
.objectHandle = (uint64_t)pipeline(),
.pObjectName = name.c_str(),
};
vkSetDebugUtilsObjectNameEXT(gpu->dev(), &nameInfo);
#endif
}
};
@@ -0,0 +1,147 @@
#pragma once
#include "Gpu.hpp"
#include "Shader.hpp"
#include "VertexBinding.h"
#include "VertexAttribute.h"
#include "BlendingInfo.h"
#include "Pipeline.hpp"
#include <volk.h>
#include <stdexcept>
#include <algorithm>
#include <utility>
class PipelineLayoutBuilder {
private:
std::vector<VkDescriptorSetLayout> m_layouts;
std::vector<VkPushConstantRange> m_pushConstantRanges;
uint32_t m_numLayouts;
public:
PipelineLayoutBuilder() :
m_layouts(4), m_pushConstantRanges(), m_numLayouts(0) {
}
PipelineLayoutBuilder& input_set(uint32_t idx, VkDescriptorSetLayout setLayout) {
if(idx >= m_layouts.size()) {
throw std::runtime_error("As of now, only 4 descriptor set layouts are supported");
}
m_layouts[idx] = setLayout;
m_numLayouts = std::max(m_numLayouts, idx + 1);
return *this;
}
PipelineLayoutBuilder& push_constant_range(uint32_t offset, uint32_t size, VkShaderStageFlags stages) {
m_pushConstantRanges.push_back({
.stageFlags = stages,
.offset = offset,
.size = size,
});
return *this;
}
VkPipelineLayout build(const Gpu* gpu) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = m_numLayouts,
.pSetLayouts = m_layouts.data(),
.pushConstantRangeCount = (uint32_t)m_pushConstantRanges.size(),
.pPushConstantRanges = m_pushConstantRanges.data(),
};
VkPipelineLayout inputLayout = VK_NULL_HANDLE;
if (vkCreatePipelineLayout(gpu->dev(), &pipelineLayoutInfo, nullptr, &inputLayout)) {
throw std::runtime_error("Failed to build pipeline layout");
}
return inputLayout;
}
};
class PipelineBuilder {
private:
const Gpu* m_gpu;
VkPipelineLayout m_layout;
VkRenderPass m_renderpass;
VkViewport m_viewport;
VkRect2D m_scissor;
VkPipelineRasterizationStateCreateInfo m_rasterInfo;
VkPipelineInputAssemblyStateCreateInfo m_inputAssemblyInfo;
VkPipelineDepthStencilStateCreateInfo m_depthStencilInfo;
VkPipelineVertexInputStateCreateInfo m_vertexInputInfo;
std::vector<VkPipelineColorBlendAttachmentState> m_blendingInfo;
std::vector<VkPipelineShaderStageCreateInfo> stages;
std::vector<VertexBinding> m_vertexBindings;
std::vector<VertexAttribute> m_vertexAttributes;
public:
inline size_t num_attachments() { return m_blendingInfo.size(); }
PipelineBuilder(const Gpu* gpu, const VkViewport& viewport,
VkPipelineLayout layout, VkRenderPass outputLayout,
uint32_t numAttachments,
const Shader* vertexShader, const Shader* fragmentShader);
inline PipelineBuilder& set_vertex_input_info(std::vector<VertexBinding> bindings,
std::vector<VertexAttribute> attributes) {
m_vertexBindings = std::move(bindings);
m_vertexAttributes = std::move(attributes);
return *this;
}
/* Rasterization */
inline PipelineBuilder& polygon_mode(VkPolygonMode mode) {
this->m_rasterInfo.polygonMode = mode;
return *this;
}
inline PipelineBuilder& cull_mode(VkCullModeFlags flags) {
this->m_rasterInfo.cullMode = flags;
return *this;
}
inline PipelineBuilder& topology(VkPrimitiveTopology topology) {
this->m_inputAssemblyInfo.topology = topology;
return *this;
}
inline PipelineBuilder& set_depth_bias(float depthBiasConstantFactor, float depthBiasClamp,
float depthBiasSlopeFactor) {
m_rasterInfo.depthBiasEnable = true,
m_rasterInfo.depthBiasConstantFactor = depthBiasConstantFactor;
m_rasterInfo.depthBiasClamp = depthBiasClamp;
m_rasterInfo.depthBiasSlopeFactor = depthBiasSlopeFactor;
return *this;
}
inline PipelineBuilder& unset_blending(uint32_t attachmentIdx) {
m_blendingInfo[attachmentIdx].blendEnable = false;
return *this;
}
inline PipelineBuilder& set_blending(uint32_t attachmentIdx, BlendingInfo blendingInfo) {
m_blendingInfo[attachmentIdx] = {
.blendEnable = true,
.srcColorBlendFactor = blendingInfo.srcColorBlendFactor,
.dstColorBlendFactor = blendingInfo.dstColorBlendFactor,
.colorBlendOp = blendingInfo.colorBlendOp,
.srcAlphaBlendFactor = blendingInfo.srcAlphaBlendFactor,
.dstAlphaBlendFactor = blendingInfo.dstAlphaBlendFactor,
.alphaBlendOp = blendingInfo.alphaBlendOp,
.colorWriteMask = VK_COLOR_COMPONENT_R_BIT |
VK_COLOR_COMPONENT_G_BIT |
VK_COLOR_COMPONENT_B_BIT |
VK_COLOR_COMPONENT_A_BIT
};
return *this;
}
Pipeline build();
};
@@ -0,0 +1,59 @@
#pragma once
#include <vector>
#include <stdexcept>
#include <volk.h>
#include "Gpu.hpp"
namespace lft {
class PipelineLayoutBuilder {
private:
std::vector<VkDescriptorSetLayout> m_layouts;
std::vector<VkPushConstantRange> m_pushConstantRanges;
uint32_t m_numLayouts;
public:
PipelineLayoutBuilder() :
m_layouts(4), m_pushConstantRanges(), m_numLayouts(0) {
}
PipelineLayoutBuilder& input_set(uint32_t idx, VkDescriptorSetLayout setLayout) {
if(idx >= m_layouts.size()) {
throw std::runtime_error("As of now, only 4 descriptor set layouts are supported");
}
m_layouts[idx] = setLayout;
m_numLayouts = std::max(m_numLayouts, idx + 1);
return *this;
}
PipelineLayoutBuilder& push_constant_range(uint32_t offset, uint32_t size, VkShaderStageFlags stages) {
m_pushConstantRanges.push_back({
.stageFlags = stages,
.offset = offset,
.size = size,
});
return *this;
}
VkPipelineLayout build(const Gpu* gpu) {
VkPipelineLayoutCreateInfo pipelineLayoutInfo = {
.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
.setLayoutCount = m_numLayouts,
.pSetLayouts = m_layouts.data(),
.pushConstantRangeCount = (uint32_t)m_pushConstantRanges.size(),
.pPushConstantRanges = m_pushConstantRanges.data(),
};
VkPipelineLayout inputLayout = VK_NULL_HANDLE;
if (vkCreatePipelineLayout(gpu->dev(), &pipelineLayoutInfo, nullptr, &inputLayout)) {
throw std::runtime_error("Failed to build pipeline layout");
}
return inputLayout;
}
};
}
@@ -0,0 +1,72 @@
#pragma once
#include <volk.h>
#include <memory>
#include <vulkan/vulkan_core.h>
#include "Gpu.hpp"
namespace lft {
class SamplerBuilder {
VkSamplerCreateInfo m_sampler_info = {};
public:
SamplerBuilder() {
m_sampler_info.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO;
}
inline SamplerBuilder& mag_filter(VkFilter filter) {
m_sampler_info.magFilter = filter;
return *this;
}
inline SamplerBuilder& min_filter(VkFilter filter) {
m_sampler_info.minFilter = filter;
return *this;
}
inline SamplerBuilder& filter(VkFilter filter) {
mag_filter(filter);
min_filter(filter);
return *this;
}
inline SamplerBuilder& address_mode_u(VkSamplerAddressMode address_mode) {
m_sampler_info.addressModeU = address_mode;
return *this;
}
inline SamplerBuilder& address_mode_v(VkSamplerAddressMode address_mode) {
m_sampler_info.addressModeV = address_mode;
return *this;
}
inline SamplerBuilder& address_mode_w(VkSamplerAddressMode address_mode) {
m_sampler_info.addressModeW = address_mode;
return *this;
}
inline SamplerBuilder& address_mode(VkSamplerAddressMode address_mode) {
address_mode_u(address_mode);
address_mode_v(address_mode);
address_mode_w(address_mode);
return *this;
}
inline SamplerBuilder& border_color(VkBorderColor border_color) {
m_sampler_info.borderColor = border_color;
return *this;
}
VkSampler build(std::shared_ptr<Gpu> gpu) {
VkSampler sampler = VK_NULL_HANDLE;
if(vkCreateSampler(gpu->dev(), &m_sampler_info, nullptr, &sampler)) {
throw std::runtime_error("failed to create sampler");
}
return sampler;
}
};
}
+49
View File
@@ -0,0 +1,49 @@
//
// Created by martin on 10/24/23.
//
#ifndef LOFT_SHADER_HPP
#define LOFT_SHADER_HPP
#include "Gpu.hpp"
#include "io/ShaderBinary.h"
#include <volk.h>
#include <utility>
struct Shader {
private:
VkShaderModule m_module;
public:
Shader(Shader&& s) :
m_module(s.m_module) {
}
Shader(VkShaderModule m) :
m_module(m) {
}
const inline Shader& set_name(const Gpu* gpu, const std::string &name) {
#if LOFT_DEBUG
VkDebugUtilsObjectNameInfoEXT nameInfo = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
.objectType = VK_OBJECT_TYPE_SHADER_MODULE,
.objectHandle = (uint64_t) m_module,
.pObjectName = name.c_str(),
};
vkSetDebugUtilsObjectNameEXT(gpu->dev(), &nameInfo);
#endif
return *this;
}
[[nodiscard]] inline VkShaderModule module() const {
return m_module;
}
};
#endif //LOFT_SHADER_HPP
@@ -0,0 +1,17 @@
//
// Created by martin on 10/24/23.
//
#ifndef LOFT_SHADERBUILDER_HPP
#define LOFT_SHADERBUILDER_HPP
#include <string>
#include "Shader.hpp"
class ShaderBuilder {
public:
virtual Shader from_file(std::string path) = 0;
};
#endif //LOFT_SHADERBUILDER_HPP
@@ -0,0 +1,279 @@
#pragma once
#include <cstdint>
#include <string>
#include <utility>
#include <vector>
#include <volk.h>
#include <memory>
#include <exception>
#include <assert.h>
#include <stdexcept>
#include <print>
#include "resources/Buffer.hpp"
#include "resources/Image.hpp"
#include "Gpu.hpp"
/**
* ShaderInputSetBufferWrite
* For having uniform buffer
*/
struct ShaderInputSetBufferWrite {
private:
VkDescriptorType m_type;
uint32_t m_binding;
VkDescriptorBufferInfo m_bufferInfo;
public:
/**
* Creates new shader input set write for Buffer
*/
ShaderInputSetBufferWrite(VkDescriptorType type, uint32_t binding, const Buffer& buffer,
uint32_t offset, uint32_t size) :
m_bufferInfo(
{
.buffer = buffer.buf,
.offset = offset,
.range = size
}
),
m_binding(binding),
m_type(type) {
}
const VkDescriptorBufferInfo* info() {
return &m_bufferInfo;
}
};
struct ShaderInputSetImageWrite {
private:
VkDescriptorType m_type;
uint32_t m_binding;
VkDescriptorImageInfo m_imageInfo;
public:
ShaderInputSetImageWrite(uint32_t binding, const ImageView& view, VkSampler sampler) :
m_imageInfo(
{
.sampler = sampler,
.imageView = view.view,
.imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL,
}
),
m_binding(binding),
m_type(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER) {
}
const VkDescriptorImageInfo* info() {
return &m_imageInfo;
}
};
union ShaderInputSetWrite {
private:
struct {
VkDescriptorType type;
uint32_t binding;
} common;
ShaderInputSetBufferWrite buffer;
ShaderInputSetImageWrite image;
public:
ShaderInputSetWrite() :
common() {
}
explicit ShaderInputSetWrite(ShaderInputSetBufferWrite bufferWrite) :
buffer(bufferWrite) {
}
explicit ShaderInputSetWrite(ShaderInputSetImageWrite imageWrite) :
image(imageWrite) {
}
uint32_t is_buffer_write(VkDescriptorType type) {
return type > VK_DESCRIPTOR_TYPE_STORAGE_TEXEL_BUFFER;
}
VkWriteDescriptorSet to_write(VkDescriptorSet set) {
return {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = set,
.dstBinding = common.binding,
.dstArrayElement = 0,
.descriptorCount = 1,
.descriptorType = common.type,
.pImageInfo = is_buffer_write(common.type) ? nullptr : image.info(),
.pBufferInfo = is_buffer_write(common.type) ? buffer.info() : nullptr,
};
}
};
/**
* ShaderInputSetBuilder
*
* Builds descriptor sets
*/
struct ShaderInputSetBuilder {
private:
std::vector<ShaderInputSetWrite> m_writes;
public:
explicit ShaderInputSetBuilder() :
m_writes() {
}
ShaderInputSetBuilder& image(uint32_t binding, const ImageView& imageView, VkSampler sampler) {
assert(imageView.view != VK_NULL_HANDLE);
assert(sampler != VK_NULL_HANDLE);
m_writes.push_back(ShaderInputSetWrite(ShaderInputSetImageWrite(binding, imageView, sampler)));
return *this;
}
ShaderInputSetBuilder& buffer(const VkDescriptorType type, const uint32_t binding, const Buffer& buffer, const uint32_t offset, const uint32_t size) {
assert(buffer.buf != VK_NULL_HANDLE);
m_writes.push_back(ShaderInputSetWrite(ShaderInputSetBufferWrite(type, binding, buffer, offset, size)));
return *this;
}
/**
* Allocates new descriptor sets from layout.
* All the writes must be set already.
* @param pGpu Gpu on which to perform
* @param layout Descriptor set layout
* @return Allocated descriptor set with all the writes.
*/
VkDescriptorSet build(const Gpu* gpu, VkDescriptorSetLayout layout) {
VkDescriptorSetAllocateInfo descriptorInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = gpu->descriptor_pool(),
.descriptorSetCount = 1,
.pSetLayouts = &layout
};
VkDescriptorSet set = VK_NULL_HANDLE;
if(vkAllocateDescriptorSets(gpu->dev(), &descriptorInfo, &set)) {
throw std::runtime_error("Failed to allocate descriptor set");
}
std::vector<VkWriteDescriptorSet> writes(m_writes.size());
for(uint32_t i = 0; i < m_writes.size(); i++) {
writes[i] = m_writes[i].to_write(set);
}
vkUpdateDescriptorSets(gpu->dev(), writes.size(), writes.data(),
0, nullptr);
return set;
}
};
struct ShaderInputSet {
private:
VkDescriptorSet m_descriptorSet;
public:
inline const VkDescriptorSet descriptor_set() const {
return m_descriptorSet;
}
ShaderInputSet(VkDescriptorSet descriptorSet) :
m_descriptorSet(descriptorSet) {
}
ShaderInputSet(const Gpu* gpu, VkDescriptorSetLayout layout) :
m_descriptorSet(VK_NULL_HANDLE) {
VkDescriptorSetAllocateInfo descriptorInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO,
.descriptorPool = gpu->descriptor_pool(),
.descriptorSetCount = 1,
.pSetLayouts = &layout
};
if(vkAllocateDescriptorSets(gpu->dev(), &descriptorInfo, &m_descriptorSet)) {
throw std::runtime_error("Failed to allocate descriptor set");
}
}
};
enum ShaderInputWriteType {
};
class ShaderInputSetWriter {
private:
const Gpu* m_gpu;
std::vector<VkWriteDescriptorSet> m_writes;
std::vector<std::vector<VkDescriptorImageInfo>> m_imageWrites;
std::vector<std::vector<VkDescriptorBufferInfo>> m_bufferWrites;
public:
explicit ShaderInputSetWriter(const Gpu* gpu) :
m_gpu(gpu) {
}
ShaderInputSetWriter& write_images(const ShaderInputSet& dstInputSet,
const uint32_t dstBinding,
const uint32_t dstArrayElement,
const VkDescriptorType type,
const std::vector<VkDescriptorImageInfo>& writes) {
/* copy write data, to not lose it */
m_imageWrites.push_back(writes);
m_writes.push_back({
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = dstInputSet.descriptor_set(),
.dstBinding = dstBinding,
.dstArrayElement = dstArrayElement,
.descriptorCount = (uint32_t)writes.size(),
.descriptorType = type,
.pImageInfo = m_imageWrites[m_imageWrites.size() - 1].data()
});
return *this;
}
ShaderInputSetWriter& write_buffer(const ShaderInputSet& dstInputSet,
const uint32_t dstBinding,
const uint32_t dstArrayElement,
const VkDescriptorType type,
const std::vector<VkDescriptorBufferInfo>& writes) {
/* copy write data, to not lose it */
m_bufferWrites.push_back(writes);
m_writes.push_back({
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
.dstSet = dstInputSet.descriptor_set(),
.dstBinding = dstBinding,
.dstArrayElement = dstArrayElement,
.descriptorCount = (uint32_t)writes.size(),
.descriptorType = type,
.pBufferInfo = m_bufferWrites[m_bufferWrites.size() - 1].data()
});
return *this;
}
ShaderInputSetWriter& write() {
vkUpdateDescriptorSets(m_gpu->dev(), m_writes.size(), m_writes.data(), 0, nullptr);
return *this;
}
};
@@ -0,0 +1,98 @@
#pragma once
#include "Gpu.hpp"
#include <vector>
#include <volk.h>
#include <assert.h>
#include <stdexcept>
class ShaderInputSetLayoutBuilder {
private:
std::vector<VkDescriptorSetLayoutBinding> m_bindings;
public:
ShaderInputSetLayoutBuilder() :
m_bindings() {
}
ShaderInputSetLayoutBuilder(std::vector<VkDescriptorSetLayoutBinding> bindings) :
m_bindings(bindings) {
}
ShaderInputSetLayoutBuilder& uniform_buffer(
uint32_t binding,
VkShaderStageFlags shader_stages = VK_SHADER_STAGE_ALL
) {
m_bindings.push_back({
.binding = binding,
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
.descriptorCount = 1,
.stageFlags = shader_stages,
});
return *this;
}
ShaderInputSetLayoutBuilder& image(
uint32_t binding,
VkShaderStageFlags shader_stages = VK_SHADER_STAGE_ALL
) {
m_bindings.push_back({
.binding = binding,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = 1,
.stageFlags = shader_stages,
});
return *this;
}
ShaderInputSetLayoutBuilder& n_images(
uint32_t binding,
uint32_t count,
VkShaderStageFlags shader_stages = VK_SHADER_STAGE_ALL
) {
m_bindings.push_back({
.binding = binding,
.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER,
.descriptorCount = count,
.stageFlags = shader_stages,
});
return *this;
}
ShaderInputSetLayoutBuilder& binding(
uint32_t binding,
VkDescriptorType type,
uint32_t count,
VkShaderStageFlags stages
) {
m_bindings.push_back({
.binding = binding,
.descriptorType = type,
.descriptorCount = count,
.stageFlags = stages,
});
return *this;
}
VkDescriptorSetLayout build(const Gpu* gpu) const {
VkDescriptorSetLayoutCreateInfo layoutInfo = {
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
.bindingCount = (uint32_t)m_bindings.size(),
.pBindings = m_bindings.data(),
};
VkDescriptorSetLayout layout = VK_NULL_HANDLE;
if(vkCreateDescriptorSetLayout(gpu->dev(), &layoutInfo, nullptr, &layout)) {
throw std::runtime_error("Failed to create descriptor set layout");
}
return layout;
}
};
@@ -0,0 +1,23 @@
//
// Created by martin on 10/24/23.
//
#ifndef LOFT_SPIRVSHADERBUILDER_HPP
#define LOFT_SPIRVSHADERBUILDER_HPP
#include "ShaderBuilder.hpp"
#include "Gpu.hpp"
class SpirvShaderBuilder : public ShaderBuilder {
private:
const Gpu* m_gpu;
public:
SpirvShaderBuilder(const Gpu* gpu);
Shader from_binary(const std::vector<uint32_t>& code) const;
Shader from_file(std::string path) override;
};
#endif //LOFT_SPIRVSHADERBUILDER_HPP
@@ -0,0 +1,15 @@
#pragma once
#include <cstdint>
#include <volk.h>
struct VertexAttribute {
uint32_t location;
uint32_t binding;
VkFormat format;
uint32_t offset;
VkVertexInputAttributeDescription get_vk() {
return *(VkVertexInputAttributeDescription*)this;
}
};
@@ -0,0 +1,13 @@
#pragma once
#include <volk.h>
struct VertexBinding {
uint32_t binding;
uint32_t stride;
VkVertexInputRate inputRate;
VkVertexInputBindingDescription get_vk() {
return *(VkVertexInputBindingDescription*)this;
}
};