initial
This commit is contained in:
@@ -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;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user