diff options
author | tylermurphy534 <tylermurphy534@gmail.com> | 2022-09-18 21:20:51 -0400 |
---|---|---|
committer | tylermurphy534 <tylermurphy534@gmail.com> | 2022-09-18 21:20:51 -0400 |
commit | 8045b8ba04aae39a4cf9733e72413f648b6ebe2b (patch) | |
tree | f90a9bd50a2316d5077df99c9e8584afc76ed656 /engine/xe_descriptors.cpp | |
download | minecraftvulkan-8045b8ba04aae39a4cf9733e72413f648b6ebe2b.tar.gz minecraftvulkan-8045b8ba04aae39a4cf9733e72413f648b6ebe2b.tar.bz2 minecraftvulkan-8045b8ba04aae39a4cf9733e72413f648b6ebe2b.zip |
stanford dragon rendering
Diffstat (limited to 'engine/xe_descriptors.cpp')
-rw-r--r-- | engine/xe_descriptors.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/engine/xe_descriptors.cpp b/engine/xe_descriptors.cpp new file mode 100644 index 0000000..ef6dc2c --- /dev/null +++ b/engine/xe_descriptors.cpp @@ -0,0 +1,183 @@ +#include "xe_descriptors.hpp" + +#include <cassert> +#include <stdexcept> + +namespace xe { + +XeDescriptorSetLayout::Builder &XeDescriptorSetLayout::Builder::addBinding( + uint32_t binding, + VkDescriptorType descriptorType, + VkShaderStageFlags stageFlags, + uint32_t count) { + assert(bindings.count(binding) == 0 && "Binding already in use"); + VkDescriptorSetLayoutBinding layoutBinding{}; + layoutBinding.binding = binding; + layoutBinding.descriptorType = descriptorType; + layoutBinding.descriptorCount = count; + layoutBinding.stageFlags = stageFlags; + bindings[binding] = layoutBinding; + return *this; +} + +std::unique_ptr<XeDescriptorSetLayout> XeDescriptorSetLayout::Builder::build() const { + return std::make_unique<XeDescriptorSetLayout>(xeDevice, bindings); +} + +XeDescriptorSetLayout::XeDescriptorSetLayout( + XeDevice &xeDevice, std::unordered_map<uint32_t, VkDescriptorSetLayoutBinding> bindings) + : 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!"); + } +} + +XeDescriptorSetLayout::~XeDescriptorSetLayout() { + vkDestroyDescriptorSetLayout(xeDevice.device(), descriptorSetLayout, nullptr); +} + +XeDescriptorPool::Builder &XeDescriptorPool::Builder::addPoolSize( + VkDescriptorType descriptorType, uint32_t count) { + poolSizes.push_back({descriptorType, count}); + return *this; +} + +XeDescriptorPool::Builder &XeDescriptorPool::Builder::setPoolFlags( + VkDescriptorPoolCreateFlags flags) { + poolFlags = flags; + return *this; +} +XeDescriptorPool::Builder &XeDescriptorPool::Builder::setMaxSets(uint32_t count) { + maxSets = count; + return *this; +} + +std::unique_ptr<XeDescriptorPool> XeDescriptorPool::Builder::build() const { + return std::make_unique<XeDescriptorPool>(xeDevice, maxSets, poolFlags, poolSizes); +} + +XeDescriptorPool::XeDescriptorPool( + XeDevice &xeDevice, + 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!"); + } +} + +XeDescriptorPool::~XeDescriptorPool() { + vkDestroyDescriptorPool(xeDevice.device(), descriptorPool, nullptr); +} + +bool XeDescriptorPool::allocateDescriptor( + 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; +} + +void XeDescriptorPool::freeDescriptors(std::vector<VkDescriptorSet> &descriptors) const { + vkFreeDescriptorSets( + xeDevice.device(), + descriptorPool, + static_cast<uint32_t>(descriptors.size()), + descriptors.data()); +} + +void XeDescriptorPool::resetPool() { + vkResetDescriptorPool(xeDevice.device(), descriptorPool, 0); +} + +XeDescriptorWriter::XeDescriptorWriter(XeDescriptorSetLayout &setLayout, XeDescriptorPool &pool) + : setLayout{setLayout}, pool{pool} {} + +XeDescriptorWriter &XeDescriptorWriter::writeBuffer( + 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; +} + +XeDescriptorWriter &XeDescriptorWriter::writeImage( + 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; +} + +bool XeDescriptorWriter::build(VkDescriptorSet &set) { + bool success = pool.allocateDescriptor(setLayout.getDescriptorSetLayout(), set); + if (!success) { + return false; + } + overwrite(set); + return true; +} + +void XeDescriptorWriter::overwrite(VkDescriptorSet &set) { + for (auto &write : writes) { + write.dstSet = set; + } + vkUpdateDescriptorSets(pool.xeDevice.device(), writes.size(), writes.data(), 0, nullptr); +} + +}
\ No newline at end of file |