diff --git a/include/core/descriptorset.hpp b/include/core/descriptorset.hpp index bfd110f..b2c2bf7 100644 --- a/include/core/descriptorset.hpp +++ b/include/core/descriptorset.hpp @@ -1,12 +1,16 @@ #ifndef DESCRIPTORSET_HPP #define DESCRIPTORSET_HPP +#include "core/buffer.hpp" #include "core/commandbuffer.hpp" #include "core/descriptorpool.hpp" +#include "core/image.hpp" #include "core/pipeline.hpp" +#include "core/sampler.hpp" #include "core/shadermodule.hpp" #include "device.hpp" +#include #include #include @@ -33,13 +37,26 @@ namespace Vulkan::Core { DescriptorSet(const Device& device, DescriptorPool pool, const ShaderModule& shaderModule); + using ResourcePair = std::pair>; + + /// + /// Update the descriptor set with resources. + /// + /// @param device Vulkan device + /// @param resources Resources to update the descriptor set with + /// + /// @throws std::invalid_argument if the device or resources are invalid. + /// + void update(const Device& device, + const std::vector>& resources) const; + /// /// Bind a descriptor set to a command buffer. /// /// @param commandBuffer Command buffer to bind the descriptor set to. /// @param pipeline Pipeline to bind the descriptor set to. /// - /// @throws std::invalid_argument if the command buffer is invalid. + /// @throws std::invalid_argument if the command buffer or pipeline is invalid. /// void bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const; diff --git a/src/core/descriptorset.cpp b/src/core/descriptorset.cpp index 73a0a60..a483b36 100644 --- a/src/core/descriptorset.cpp +++ b/src/core/descriptorset.cpp @@ -30,6 +30,66 @@ DescriptorSet::DescriptorSet(const Device& device, ); } +void DescriptorSet::update(const Device& device, + const std::vector>& resources) const { + if (!device) + throw std::invalid_argument("Invalid Vulkan device"); + + std::vector writeDescriptorSets; + uint32_t bindingIndex = 0; + for (const auto& list : resources) { + for (const auto& [type, resource] : list) { + VkWriteDescriptorSet writeDesc{ + .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, + .dstSet = this->handle(), + .dstBinding = bindingIndex++, + .descriptorCount = 1, + .descriptorType = type, + }; + + if (std::holds_alternative(resource)) { + const auto& image = std::get(resource); + if (!image) + throw std::invalid_argument("Invalid image resource"); + + const VkDescriptorImageInfo imageInfo{ + .imageView = image.getView(), + .imageLayout = VK_IMAGE_LAYOUT_GENERAL + }; + writeDesc.pImageInfo = &imageInfo; + } else if (std::holds_alternative(resource)) { + const auto& sampler = std::get(resource); + if (!sampler) + throw std::invalid_argument("Invalid sampler resource"); + + const VkDescriptorImageInfo imageInfo{ + .sampler = sampler.handle() + }; + writeDesc.pImageInfo = &imageInfo; + } else if (std::holds_alternative(resource)) { + const auto& buffer = std::get(resource); + if (!buffer) + throw std::invalid_argument("Invalid buffer resource"); + + const VkDescriptorBufferInfo bufferInfo{ + .buffer = buffer.handle(), + .range = buffer.getSize() + }; + writeDesc.pBufferInfo = &bufferInfo; + } else { + throw std::invalid_argument("Unsupported resource type"); + } + + writeDescriptorSets.push_back(writeDesc); + } + } + + vkUpdateDescriptorSets(device.handle(), + static_cast(writeDescriptorSets.size()), + writeDescriptorSets.data(), + 0, nullptr); +} + void DescriptorSet::bind(const CommandBuffer& commandBuffer, const Pipeline& pipeline) const { if (!commandBuffer) throw std::invalid_argument("Invalid command buffer");