minecraftvulkan/engine/xe_descriptors.cpp

185 lines
5.9 KiB
C++
Raw Normal View History

2022-09-19 01:20:51 +00:00
#include "xe_descriptors.hpp"
#include <cassert>
#include <stdexcept>
namespace xe {
2022-09-25 01:16:13 +00:00
DescriptorSetLayout::Builder &DescriptorSetLayout::Builder::addBinding(
2022-09-19 01:20:51 +00:00
uint32_t binding,
VkDescriptorType descriptorType,
VkShaderStageFlags stageFlags,
2022-09-21 02:02:58 +00:00
VkSampler *sampler) {
2022-09-19 01:20:51 +00:00
assert(bindings.count(binding) == 0 && "Binding already in use");
2022-09-21 02:02:58 +00:00
uint32_t count = 1;
2022-09-19 01:20:51 +00:00
VkDescriptorSetLayoutBinding layoutBinding{};
layoutBinding.binding = binding;
layoutBinding.descriptorType = descriptorType;
layoutBinding.descriptorCount = count;
layoutBinding.stageFlags = stageFlags;
2022-09-21 02:02:58 +00:00
layoutBinding.pImmutableSamplers = sampler;
2022-09-19 01:20:51 +00:00
bindings[binding] = layoutBinding;
return *this;
}
2022-09-25 01:16:13 +00:00
std::unique_ptr<DescriptorSetLayout> DescriptorSetLayout::Builder::build() const {
return std::make_unique<DescriptorSetLayout>(xeDevice, bindings);
2022-09-19 01:20:51 +00:00
}
2022-09-25 01:16:13 +00:00
DescriptorSetLayout::DescriptorSetLayout(
Device &xeDevice, std::unordered_map<uint32_t, VkDescriptorSetLayoutBinding> bindings)
2022-09-19 01:20:51 +00:00
: xeDevice{xeDevice}, bindings{bindings} {
std::vector<VkDescriptorSetLayoutBinding> setLayoutBindings{};
for (auto kv : bindings) {
setLayoutBindings.push_back(kv.second);
}
VkDescriptorSetLayoutCreateInfo descriptorSetLayoutInfo{};
descriptorSetLayoutInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO;
descriptorSetLayoutInfo.bindingCount = static_cast<uint32_t>(setLayoutBindings.size());
descriptorSetLayoutInfo.pBindings = setLayoutBindings.data();
if (vkCreateDescriptorSetLayout(
xeDevice.device(),
&descriptorSetLayoutInfo,
nullptr,
&descriptorSetLayout) != VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor set layout!");
}
}
2022-09-25 01:16:13 +00:00
DescriptorSetLayout::~DescriptorSetLayout() {
2022-09-19 01:20:51 +00:00
vkDestroyDescriptorSetLayout(xeDevice.device(), descriptorSetLayout, nullptr);
}
2022-09-25 01:16:13 +00:00
DescriptorPool::Builder &DescriptorPool::Builder::addPoolSize(
2022-09-19 01:20:51 +00:00
VkDescriptorType descriptorType, uint32_t count) {
poolSizes.push_back({descriptorType, count});
return *this;
}
2022-09-25 01:16:13 +00:00
DescriptorPool::Builder &DescriptorPool::Builder::setPoolFlags(
2022-09-19 01:20:51 +00:00
VkDescriptorPoolCreateFlags flags) {
poolFlags = flags;
return *this;
}
2022-09-25 01:16:13 +00:00
DescriptorPool::Builder &DescriptorPool::Builder::setMaxSets(uint32_t count) {
2022-09-19 01:20:51 +00:00
maxSets = count;
return *this;
}
2022-09-25 01:16:13 +00:00
std::unique_ptr<DescriptorPool> DescriptorPool::Builder::build() const {
return std::make_unique<DescriptorPool>(xeDevice, maxSets, poolFlags, poolSizes);
2022-09-19 01:20:51 +00:00
}
2022-09-25 01:16:13 +00:00
DescriptorPool::DescriptorPool(
Device &xeDevice,
2022-09-19 01:20:51 +00:00
uint32_t maxSets,
VkDescriptorPoolCreateFlags poolFlags,
const std::vector<VkDescriptorPoolSize> &poolSizes)
: xeDevice{xeDevice} {
VkDescriptorPoolCreateInfo descriptorPoolInfo{};
descriptorPoolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
descriptorPoolInfo.poolSizeCount = static_cast<uint32_t>(poolSizes.size());
descriptorPoolInfo.pPoolSizes = poolSizes.data();
descriptorPoolInfo.maxSets = maxSets;
descriptorPoolInfo.flags = poolFlags;
if (vkCreateDescriptorPool(xeDevice.device(), &descriptorPoolInfo, nullptr, &descriptorPool) !=
VK_SUCCESS) {
throw std::runtime_error("failed to create descriptor pool!");
}
}
2022-09-25 01:16:13 +00:00
DescriptorPool::~DescriptorPool() {
2022-09-19 01:20:51 +00:00
vkDestroyDescriptorPool(xeDevice.device(), descriptorPool, nullptr);
}
2022-09-25 01:16:13 +00:00
bool DescriptorPool::allocateDescriptor(
2022-09-19 01:20:51 +00:00
const VkDescriptorSetLayout descriptorSetLayout, VkDescriptorSet &descriptor) const {
VkDescriptorSetAllocateInfo allocInfo{};
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
allocInfo.descriptorPool = descriptorPool;
allocInfo.pSetLayouts = &descriptorSetLayout;
allocInfo.descriptorSetCount = 1;
if (vkAllocateDescriptorSets(xeDevice.device(), &allocInfo, &descriptor) != VK_SUCCESS) {
return false;
}
return true;
}
2022-09-25 01:16:13 +00:00
void DescriptorPool::freeDescriptors(std::vector<VkDescriptorSet> &descriptors) const {
2022-09-19 01:20:51 +00:00
vkFreeDescriptorSets(
xeDevice.device(),
descriptorPool,
static_cast<uint32_t>(descriptors.size()),
descriptors.data());
}
2022-09-25 01:16:13 +00:00
void DescriptorPool::resetPool() {
2022-09-19 01:20:51 +00:00
vkResetDescriptorPool(xeDevice.device(), descriptorPool, 0);
}
2022-09-25 01:16:13 +00:00
DescriptorWriter::DescriptorWriter(DescriptorSetLayout &setLayout, DescriptorPool &pool)
2022-09-19 01:20:51 +00:00
: setLayout{setLayout}, pool{pool} {}
2022-09-25 01:16:13 +00:00
DescriptorWriter &DescriptorWriter::writeBuffer(
2022-09-19 01:20:51 +00:00
uint32_t binding, VkDescriptorBufferInfo *bufferInfo) {
assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding");
auto &bindingDescription = setLayout.bindings[binding];
assert(
bindingDescription.descriptorCount == 1 &&
"Binding single descriptor info, but binding expects multiple");
VkWriteDescriptorSet write{};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.descriptorType = bindingDescription.descriptorType;
write.dstBinding = binding;
write.pBufferInfo = bufferInfo;
write.descriptorCount = 1;
writes.push_back(write);
return *this;
}
2022-09-25 01:16:13 +00:00
DescriptorWriter &DescriptorWriter::writeImage(
2022-09-19 01:20:51 +00:00
uint32_t binding, VkDescriptorImageInfo *imageInfo) {
assert(setLayout.bindings.count(binding) == 1 && "Layout does not contain specified binding");
auto &bindingDescription = setLayout.bindings[binding];
assert(
bindingDescription.descriptorCount == 1 &&
"Binding single descriptor info, but binding expects multiple");
VkWriteDescriptorSet write{};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.descriptorType = bindingDescription.descriptorType;
write.dstBinding = binding;
write.pImageInfo = imageInfo;
write.descriptorCount = 1;
writes.push_back(write);
return *this;
}
2022-09-25 01:16:13 +00:00
bool DescriptorWriter::build(VkDescriptorSet &set) {
2022-09-19 01:20:51 +00:00
bool success = pool.allocateDescriptor(setLayout.getDescriptorSetLayout(), set);
if (!success) {
return false;
}
overwrite(set);
return true;
}
2022-09-25 01:16:13 +00:00
void DescriptorWriter::overwrite(VkDescriptorSet &set) {
2022-09-19 01:20:51 +00:00
for (auto &write : writes) {
write.dstSet = set;
}
vkUpdateDescriptorSets(pool.xeDevice.device(), writes.size(), writes.data(), 0, nullptr);
}
}