mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2026-04-26 20:31:46 +00:00
refactor: add multiset helper
This commit is contained in:
parent
29ee02f080
commit
32d35c25fc
8 changed files with 322 additions and 112 deletions
|
|
@ -94,8 +94,8 @@ namespace VK::Core {
|
|||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(
|
||||
const std::vector<VkImage>& readableImages,
|
||||
const std::vector<VkImage>& writableImages) const;
|
||||
const std::vector<std::optional<Core::Image>>& readableImages,
|
||||
const std::vector<Core::Image>& writableImages) const;
|
||||
|
||||
///
|
||||
/// Copy a buffer to an image.
|
||||
|
|
|
|||
|
|
@ -14,52 +14,6 @@
|
|||
|
||||
namespace VK::Core {
|
||||
|
||||
/// Helper class to wrap VkDescriptorImageInfo
|
||||
class ImageInfo {
|
||||
public:
|
||||
ImageInfo() noexcept = default; // skipping images is allowed
|
||||
|
||||
ImageInfo(const Image& image) noexcept
|
||||
: info{
|
||||
.imageView = image.getView(),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||
} {}
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return &this->info; }
|
||||
private:
|
||||
VkDescriptorImageInfo info{};
|
||||
};
|
||||
|
||||
/// Helper class to wrap VkDescriptorImageInfo for samplers
|
||||
class SamplerInfo {
|
||||
public:
|
||||
SamplerInfo(const Sampler& sampler) noexcept
|
||||
: info{
|
||||
.sampler = sampler.handle(),
|
||||
} {}
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return &this->info; }
|
||||
private:
|
||||
VkDescriptorImageInfo info{};
|
||||
};
|
||||
|
||||
/// Helper class to wrap VkDescriptorBufferInfo
|
||||
class BufferInfo {
|
||||
public:
|
||||
BufferInfo(const Buffer& buffer) noexcept
|
||||
: info{
|
||||
.buffer = buffer.handle(),
|
||||
.range = buffer.getSize()
|
||||
} {}
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return &this->info; }
|
||||
private:
|
||||
VkDescriptorBufferInfo info{};
|
||||
};
|
||||
|
||||
///
|
||||
/// C++ wrapper class for a Vulkan descriptor set.
|
||||
///
|
||||
|
|
@ -74,16 +28,20 @@ namespace VK::Core {
|
|||
///
|
||||
/// @param device Vulkan device
|
||||
/// @param pool Descriptor pool to allocate from
|
||||
/// @param shaderModule Shader module to use for the descriptor set
|
||||
/// @param shaderModule Shader module this descriptor is for
|
||||
/// @param sampledImages Sampled images to bind
|
||||
/// @param storageImages Storage images to bind
|
||||
/// @param samplers Samplers to bind
|
||||
/// @param buffer Buffer to bind
|
||||
///
|
||||
/// @throws VK::vulkan_error if object creation fails.
|
||||
///
|
||||
DescriptorSet(const Device& device,
|
||||
const DescriptorPool& pool, const ShaderModule& shaderModule,
|
||||
const std::vector<ImageInfo>& sampledImages,
|
||||
const std::vector<ImageInfo>& storageImages,
|
||||
const std::vector<SamplerInfo>& samplers,
|
||||
const std::vector<BufferInfo>& uniformBuffers);
|
||||
const std::vector<std::optional<Core::Image>>& sampledImages,
|
||||
const std::vector<Core::Image>& storageImages,
|
||||
const std::vector<Core::Sampler>& samplers,
|
||||
const std::optional<Core::Buffer>& buffer);
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return *this->descriptorSet; }
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
|
|
@ -26,12 +25,18 @@ namespace VK::Core {
|
|||
///
|
||||
/// @param device Vulkan device
|
||||
/// @param code SPIR-V bytecode for the shader.
|
||||
/// @param descriptorTypes Descriptor types used in the shader.
|
||||
/// @param sampledImages Number of sampled images in the shader.
|
||||
/// @param storageImages Number of storage images in the shader.
|
||||
/// @param buffers Number of uniform/storage buffers in the shader.
|
||||
/// @param samplers Number of samplers in the shader.
|
||||
///
|
||||
/// @throws VK::vulkan_error if object creation fails.
|
||||
///
|
||||
ShaderModule(const Device& device, const std::vector<uint8_t>& code,
|
||||
const std::vector<std::pair<size_t, VkDescriptorType>>& descriptorTypes);
|
||||
size_t sampledImages,
|
||||
size_t storageImages,
|
||||
size_t buffers,
|
||||
size_t samplers);
|
||||
|
||||
/// Get the Vulkan handle.
|
||||
[[nodiscard]] auto handle() const { return *this->shaderModule; }
|
||||
|
|
|
|||
195
framegen/include/vk/helper/multiset.hpp
Normal file
195
framegen/include/vk/helper/multiset.hpp
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#pragma once
|
||||
|
||||
#include "vk/helper/mipmapped_image.hpp"
|
||||
#include "vk/helper/temporal_image.hpp"
|
||||
#include "vk/helper/image_group.hpp"
|
||||
#include "vk/core/descriptorpool.hpp"
|
||||
#include "vk/core/descriptorset.hpp"
|
||||
#include "vk/core/shadermodule.hpp"
|
||||
#include "vk/core/sampler.hpp"
|
||||
#include "vk/core/buffer.hpp"
|
||||
#include "vk/core/image.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace VK::Helper {
|
||||
|
||||
///
|
||||
/// A list of descriptor sets across multiple frames.
|
||||
///
|
||||
class MultiSet {
|
||||
friend class MultiSetBuilder;
|
||||
public:
|
||||
MultiSet() noexcept = default;
|
||||
|
||||
/// Get the amount of descriptor sets.
|
||||
[[nodiscard]] auto size() const noexcept { return this->sets.size(); }
|
||||
/// Get all the descriptor sets.
|
||||
[[nodiscard]] const auto& all() const { return this->sets; }
|
||||
|
||||
/// Get the descriptor set for a specific frame index.
|
||||
[[nodiscard]] const auto& at(size_t index) const {
|
||||
return this->set(index).sets;
|
||||
}
|
||||
/// Get the readable images for a specific frame index.
|
||||
[[nodiscard]] const auto& readablesAt(size_t index) const {
|
||||
return this->set(index).readables;
|
||||
}
|
||||
/// Get the writable images for a specific frame index.
|
||||
[[nodiscard]] const auto& writablesAt(size_t index) const {
|
||||
return this->set(index).writables;
|
||||
}
|
||||
private:
|
||||
struct Set {
|
||||
Core::DescriptorSet sets;
|
||||
std::vector<std::optional<Core::Image>> readables;
|
||||
std::vector<Core::Image> writables;
|
||||
};
|
||||
std::vector<Set> sets;
|
||||
|
||||
/// Get the set at a specific index.
|
||||
[[nodiscard]] const Set& set(size_t index) const {
|
||||
return this->sets.at(index % this->sets.size());
|
||||
}
|
||||
};
|
||||
|
||||
///
|
||||
/// Builder class for a shader descriptors across multiple frames.
|
||||
///
|
||||
class MultiSetBuilder {
|
||||
public:
|
||||
MultiSetBuilder() noexcept = default;
|
||||
|
||||
///
|
||||
/// Create a new descriptor builder.
|
||||
///
|
||||
/// @param count Amount of sets to create.
|
||||
///
|
||||
MultiSetBuilder(size_t count) noexcept : recipes(count) {}
|
||||
|
||||
/// Add a buffer to the descriptor.
|
||||
MultiSetBuilder& withBuffer(const Core::Buffer& buffer) {
|
||||
this->buffer = buffer;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a sampler to the descriptor.
|
||||
MultiSetBuilder& withSampler(const Core::Sampler& sampler) {
|
||||
this->samplers = { sampler };
|
||||
return *this;
|
||||
}
|
||||
/// Add two samplers to the descriptor.
|
||||
MultiSetBuilder& withSamplers(
|
||||
const Core::Sampler& sampler1, const Core::Sampler& sampler2) {
|
||||
this->samplers = { sampler1, sampler2 };
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add an input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const Core::Image& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add an optional input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const std::optional<Core::Image>& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add multiple input images to the descriptor.
|
||||
MultiSetBuilder& addInput(const std::vector<Core::Image>& images) {
|
||||
for (auto& recipe : this->recipes)
|
||||
for (const auto& img : images)
|
||||
recipe.inImages.emplace_back(img);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a temporal input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(temporalImage.at(offset++));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a group of input images to the descriptor.
|
||||
MultiSetBuilder& addInput(const ImageGroup& imageGroup) {
|
||||
this->addInput(imageGroup.into());
|
||||
return *this;
|
||||
}
|
||||
/// Add a subgroup of input images to the descriptor.
|
||||
MultiSetBuilder& addInput(const ImageGroup& imageGroup, size_t start, size_t length) {
|
||||
this->addInput(imageGroup.subGroup(start, length));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add all mipmapped images to the descriptor.
|
||||
MultiSetBuilder& addInput(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addInput(mipmappedImage.into());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add an output image to the descriptor.
|
||||
MultiSetBuilder& addOutput(const Core::Image& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.outImages.push_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add multiple output images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const std::vector<Core::Image>& images) {
|
||||
for (auto& recipe : this->recipes)
|
||||
for (const auto& img : images)
|
||||
recipe.outImages.push_back(img);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a temporal output image to the descriptor.
|
||||
MultiSetBuilder& addOutput(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.outImages.push_back(temporalImage.at(offset++));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a group of output images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const ImageGroup& imageGroup) {
|
||||
this->addOutput(imageGroup.into());
|
||||
return *this;
|
||||
}
|
||||
/// Add a subgroup of output images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const ImageGroup& imageGroup, size_t start, size_t length) {
|
||||
this->addOutput(imageGroup.subGroup(start, length));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add all mipmapped images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addOutput(mipmappedImage.into());
|
||||
return *this;
|
||||
}
|
||||
|
||||
///
|
||||
/// Build the descriptor sets.
|
||||
///
|
||||
/// @param device The Vulkan device.
|
||||
/// @param descriptorPool The descriptor pool to allocate from.
|
||||
/// @param shaderModule The shader module this descriptor is for.
|
||||
/// @return The built descriptor sets.
|
||||
///
|
||||
[[nodiscard]] MultiSet build(
|
||||
const Core::Device& device,
|
||||
const Core::DescriptorPool& descriptorPool,
|
||||
const Core::ShaderModule& shaderModule) const;
|
||||
|
||||
private:
|
||||
std::optional<Core::Buffer> buffer;
|
||||
std::vector<Core::Sampler> samplers;
|
||||
struct SetRecipe {
|
||||
std::vector<std::optional<Core::Image>> inImages;
|
||||
std::vector<Core::Image> outImages;
|
||||
};
|
||||
std::vector<SetRecipe> recipes;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -106,8 +106,8 @@ void CommandBuffer::insertBarrier(
|
|||
}
|
||||
|
||||
void CommandBuffer::insertBarrier(
|
||||
const std::vector<VkImage>& readableImages,
|
||||
const std::vector<VkImage>& writableImages) const {
|
||||
const std::vector<std::optional<Core::Image>>& readableImages,
|
||||
const std::vector<Core::Image>& writableImages) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
||||
|
|
@ -123,22 +123,24 @@ void CommandBuffer::insertBarrier(
|
|||
}
|
||||
};
|
||||
|
||||
const size_t totalImages =
|
||||
readableImages.size() + writableImages.size();
|
||||
std::vector<VkImageMemoryBarrier2> barriers(totalImages);
|
||||
const size_t totalImages = readableImages.size() + writableImages.size();
|
||||
std::vector<VkImageMemoryBarrier2> barriers;
|
||||
barriers.reserve(totalImages);
|
||||
|
||||
for (const auto& image : readableImages) {
|
||||
if (!image.has_value())
|
||||
continue;
|
||||
VkImageMemoryBarrier2& barrier = barriers.emplace_back(dummyBarrier);
|
||||
barrier.srcAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
|
||||
barrier.image = image;
|
||||
barrier.image = image->handle();
|
||||
}
|
||||
|
||||
for (const auto& image : writableImages) {
|
||||
VkImageMemoryBarrier2& barrier = barriers.emplace_back(dummyBarrier);
|
||||
barrier.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
|
||||
barrier.image = image;
|
||||
barrier.image = image.handle();
|
||||
}
|
||||
|
||||
// insert barriers
|
||||
|
|
|
|||
|
|
@ -4,9 +4,13 @@
|
|||
#include "vk/core/descriptorpool.hpp"
|
||||
#include "vk/core/descriptorset.hpp"
|
||||
#include "vk/core/shadermodule.hpp"
|
||||
#include "vk/core/sampler.hpp"
|
||||
#include "vk/core/buffer.hpp"
|
||||
#include "vk/core/device.hpp"
|
||||
#include "vk/core/image.hpp"
|
||||
#include "vk/exception.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
|
@ -16,10 +20,10 @@ using namespace VK::Core;
|
|||
|
||||
DescriptorSet::DescriptorSet(const Device& device,
|
||||
const DescriptorPool& pool, const ShaderModule& shaderModule,
|
||||
const std::vector<ImageInfo>& sampledImages,
|
||||
const std::vector<ImageInfo>& storageImages,
|
||||
const std::vector<SamplerInfo>& samplers,
|
||||
const std::vector<BufferInfo>& uniformBuffers) {
|
||||
const std::vector<std::optional<Core::Image>>& sampledImages,
|
||||
const std::vector<Core::Image>& storageImages,
|
||||
const std::vector<Core::Sampler>& samplers,
|
||||
const std::optional<Core::Buffer>& buffer) {
|
||||
// create descriptor set
|
||||
VkDescriptorSetLayout layout = shaderModule.getLayout();
|
||||
const VkDescriptorSetAllocateInfo desc{
|
||||
|
|
@ -33,22 +37,30 @@ DescriptorSet::DescriptorSet(const Device& device,
|
|||
if (res != VK_SUCCESS || descriptorSetHandle == VK_NULL_HANDLE)
|
||||
throw VK::vulkan_error(res, "Unable to allocate descriptor set");
|
||||
|
||||
// create descriptor writes
|
||||
const size_t totalEntries =
|
||||
storageImages.size() + samplers.size() + uniformBuffers.size() + sampledImages.size();
|
||||
std::vector<VkWriteDescriptorSet> entries(totalEntries);
|
||||
const size_t bindingCount = samplers.size() + sampledImages.size()
|
||||
+ storageImages.size() + (buffer.has_value() ? 1 : 0);
|
||||
|
||||
size_t bufferIdx{0};
|
||||
for (const auto& buf : uniformBuffers)
|
||||
// create descriptor writes
|
||||
std::vector<VkWriteDescriptorSet> entries;
|
||||
entries.reserve(bindingCount);
|
||||
|
||||
std::optional<VkDescriptorBufferInfo> bufferInfos;
|
||||
|
||||
if (buffer.has_value())
|
||||
entries.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSetHandle,
|
||||
.dstBinding = static_cast<uint32_t>(bufferIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.pBufferInfo = buf.handle()
|
||||
.pBufferInfo = &(bufferInfos = VkDescriptorBufferInfo{
|
||||
.buffer = buffer->handle(),
|
||||
.range = buffer->getSize()
|
||||
}).value()
|
||||
});
|
||||
|
||||
std::vector<VkDescriptorImageInfo> imageInfos;
|
||||
imageInfos.reserve(bindingCount);
|
||||
|
||||
size_t samplerIdx{16};
|
||||
for (const auto& samp : samplers)
|
||||
entries.push_back({
|
||||
|
|
@ -57,19 +69,26 @@ DescriptorSet::DescriptorSet(const Device& device,
|
|||
.dstBinding = static_cast<uint32_t>(samplerIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.pImageInfo = samp.handle()
|
||||
.pImageInfo = &(imageInfos.emplace_back(VkDescriptorImageInfo{
|
||||
.sampler = samp.handle(),
|
||||
}))
|
||||
});
|
||||
|
||||
size_t inputIdx{32};
|
||||
for (const auto& img : sampledImages)
|
||||
for (const auto& img : sampledImages) {
|
||||
entries.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSetHandle,
|
||||
.dstBinding = static_cast<uint32_t>(inputIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = img.handle()
|
||||
.pImageInfo = &(imageInfos.emplace_back(VkDescriptorImageInfo{
|
||||
.imageView = img.has_value() ? img->getView() : nullptr,
|
||||
.imageLayout = img.has_value() ?
|
||||
VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED
|
||||
}))
|
||||
});
|
||||
}
|
||||
|
||||
size_t outputIdx{48};
|
||||
for (const auto& img : storageImages)
|
||||
|
|
@ -79,7 +98,10 @@ DescriptorSet::DescriptorSet(const Device& device,
|
|||
.dstBinding = static_cast<uint32_t>(outputIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = img.handle()
|
||||
.pImageInfo = &(imageInfos.emplace_back(VkDescriptorImageInfo{
|
||||
.imageView = img.getView(),
|
||||
.imageLayout = VK_IMAGE_LAYOUT_GENERAL
|
||||
}))
|
||||
});
|
||||
|
||||
// update descriptor set
|
||||
|
|
|
|||
|
|
@ -7,14 +7,16 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
using namespace VK::Core;
|
||||
|
||||
ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& code,
|
||||
const std::vector<std::pair<size_t, VkDescriptorType>>& descriptorTypes) {
|
||||
size_t sampledImages,
|
||||
size_t storageImages,
|
||||
size_t buffers,
|
||||
size_t samplers) {
|
||||
// create shader module
|
||||
const uint8_t* data_ptr = code.data();
|
||||
const VkShaderModuleCreateInfo createInfo{
|
||||
|
|
@ -29,39 +31,39 @@ ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& cod
|
|||
|
||||
// create descriptor set layout
|
||||
std::vector<VkDescriptorSetLayoutBinding> layoutBindings;
|
||||
size_t bufferIdx{0};
|
||||
size_t samplerIdx{16};
|
||||
size_t inputIdx{32};
|
||||
size_t outputIdx{48};
|
||||
for (const auto &[count, type] : descriptorTypes)
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
size_t* bindIdx{};
|
||||
switch (type) {
|
||||
case VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER:
|
||||
bindIdx = &bufferIdx;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLER:
|
||||
bindIdx = &samplerIdx;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE:
|
||||
bindIdx = &inputIdx;
|
||||
break;
|
||||
case VK_DESCRIPTOR_TYPE_STORAGE_IMAGE:
|
||||
bindIdx = &outputIdx;
|
||||
break;
|
||||
default:
|
||||
throw VK::vulkan_error(VK_ERROR_UNKNOWN, "Unsupported descriptor type");
|
||||
}
|
||||
layoutBindings.reserve(buffers + samplers + sampledImages + storageImages);
|
||||
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
.binding = static_cast<uint32_t>(*bindIdx),
|
||||
.descriptorType = type,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
});
|
||||
for (size_t i = 0; i < buffers; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
.binding = static_cast<uint32_t>(i),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
});
|
||||
|
||||
(*bindIdx)++;
|
||||
}
|
||||
for (size_t i = 0; i < samplers; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
.binding = static_cast<uint32_t>(i + 16),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
});
|
||||
|
||||
for (size_t i = 0; i < sampledImages; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
.binding = static_cast<uint32_t>(i + 32),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
});
|
||||
|
||||
for (size_t i = 0; i < storageImages; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
.binding = static_cast<uint32_t>(i + 48),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
.stageFlags = VK_SHADER_STAGE_COMPUTE_BIT
|
||||
});
|
||||
|
||||
const VkDescriptorSetLayoutCreateInfo layoutDesc{
|
||||
.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO,
|
||||
|
|
|
|||
26
framegen/src/vk/helper/multiset.cpp
Normal file
26
framegen/src/vk/helper/multiset.cpp
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#include "vk/helper/multiset.hpp"
|
||||
#include "vk/core/descriptorpool.hpp"
|
||||
#include "vk/core/shadermodule.hpp"
|
||||
#include "vk/core/device.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace VK::Helper;
|
||||
|
||||
MultiSet MultiSetBuilder::build(
|
||||
const Core::Device& device,
|
||||
const Core::DescriptorPool& pool,
|
||||
const Core::ShaderModule& shader) const {
|
||||
MultiSet multiset{};
|
||||
multiset.sets.reserve(this->recipes.size());
|
||||
|
||||
for (const auto& recipe : this->recipes)
|
||||
multiset.sets.push_back({
|
||||
.sets = Core::DescriptorSet(device, pool, shader,
|
||||
recipe.inImages, recipe.outImages, this->samplers, this->buffer),
|
||||
.readables = recipe.inImages,
|
||||
.writables = recipe.outImages
|
||||
});
|
||||
|
||||
return multiset;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue