1#ifndef VULKAN_DYNAMICSET
2#define VULKAN_DYNAMICSET
23 class DynamicSet :
public Set {
29 struct DynamicSetBindingInfo :
public Set::BindingInfo {
30 DynamicSetBindingInfo(
int size,
const Buffers::UniformBuffer& buffer,
int offset,
int dynamicDistance = 0) : size{ size }, buffer{ buffer }, offset{ offset }, dynamicDistance{ dynamicDistance }{}
39 DescriptorSetBindingCreationInfo generateDescriptorSetBindingInfo(
const VkDescriptorSet& descriptorSet)
const override {
40 return DescriptorSetBindingCreationInfo{ binding, descriptorSet, size, buffer, offset, dynamicDistance };
50 const Buffers::UniformBuffer& buffer;
73 template<
typename... Structs,
template<
typename,
typename>
class... Bindings>
requires (std::same_as<Bindings<VkShaderStageFlagBits, Structs>, std::pair<VkShaderStageFlagBits, Structs>> && ...)
74 DynamicSet(
const PhysicalDevice& realGpu,
const LogicalDevice& virtualGpu,
const Buffers::UniformBuffer& buffer, Bindings<VkShaderStageFlagBits, Structs>... bindings) : Set{ virtualGpu } {
76 int alignment = realGpu.getProperties().limits.minUniformBufferOffsetAlignment;
77 int currentOffset = 0;
80 ([
this, ¤tOffset, &buffer, alignment](std::pair<VkShaderStageFlagBits, Structs> binding) {
82 auto tmp = std::make_unique<DynamicSetBindingInfo>(
sizeof(binding.second), buffer, currentOffset);
83 bindingsPerBuffer[&buffer].push_back(tmp.get());
84 this->bindingsInfo.push_back(std::move(tmp));
86 currentOffset +=
sizeof(binding.second);
87 int paddingAmount = (alignment - (currentOffset % alignment)) % alignment;
88 currentOffset += paddingAmount;
92 for (
int i = 0; i < bindingsInfo.size(); ++i) {
93 static_cast<DynamicSetBindingInfo*
>(bindingsInfo[i].get())->dynamicDistance = currentOffset;
94 bindingsInfo[i].get()->binding = i;
98 createDescriptorSetLayout(std::pair{ bindings.first, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC }...);
114 template<
typename... Structs,
typename... T>
requires
115 (std::same_as<T, std::tuple<VkShaderStageFlagBits, Structs, Buffers::UniformBuffer*, int, int>> && ...)
116 DynamicSet(
const LogicalDevice& virtualGpu, T... bindingsInfo) : Set{ virtualGpu } {
118 ([
this](T bindingInfo) {
120 auto tmp = std::make_unique<DynamicSetBindingInfo>(
sizeof(std::get<1>(bindingsInfo)), *std::get<2>(bindingsInfo), std::get<3>(bindingsInfo), std::get<4>(bindingsInfo));
121 bindingsPerBuffer[&(tmp->buffer)].push_back(tmp.get());
122 tmp->binding = bindingsInfo.size();
123 this->bindingsInfo.push_back(std::move(tmp));
124 }(bindingsInfo), ...);
127 createDescriptorSetLayout(std::pair{ std::get<0>(bindingsInfo), VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC }...);
142 std::vector<uint32_t> getDynamicDistances(
int i = 0)
const {
143 std::vector<uint32_t> res;
145 for (
const auto& binding : bindingsInfo) {
146 res.push_back(
static_cast<DynamicSetBindingInfo*
>(binding.get())->dynamicDistance * i);
166 template<
typename... Bindings,
template<
typename...>
class... T>
requires (std::same_as<std::tuple<Bindings...>, T<Bindings...>> && ...)
167 void fillBuffer(Buffers::UniformBuffer& buffer,
const T<Bindings...>&... tuplesOfData)
const {
168 fillBufferHelper(buffer, std::make_integer_sequence<
int,
sizeof...(Bindings)>{}, tuplesOfData...);
176 template<
int... TI,
typename... T>
177 void fillBufferHelper(Buffers::UniformBuffer& buffer, std::integer_sequence<int, TI...>,
const T&... tuplesOfData)
const {
178 std::vector<DynamicSetBindingInfo*> bindingsInfo;
180 bindingsInfo = bindingsPerBuffer.at(&buffer);
182 catch (
const std::out_of_range&) {
183 throw VulkanException{
"Failed to fill the uniform buffer",
"The buffer to be filled isn't used in this set" };
188 ([&bindingsInfo, &counter, &buffer](
const T& tuple) {
189 (buffer.fillBuffer(std::get<TI>(tuple), bindingsInfo[TI]->offset + bindingsInfo[TI]->dynamicDistance * counter), ...);
191 }(tuplesOfData), ...);
195 std::map<const Buffers::UniformBuffer*, std::vector<DynamicSetBindingInfo*>> bindingsPerBuffer;
Types of queue families.
Definition: Animations.h:17