mirror of
https://github.com/PancakeTAS/lsfg-vk.git
synced 2025-10-30 07:01:10 +00:00
refactor: convenience changes
This commit is contained in:
parent
32d35c25fc
commit
41c0083a04
6 changed files with 84 additions and 79 deletions
|
|
@ -83,19 +83,19 @@ namespace VK::Core {
|
|||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(const std::vector<VkImage>& images) const;
|
||||
void insertBarrier(const std::vector<Core::Image>& images) const;
|
||||
|
||||
///
|
||||
/// Insert memory barriers for images in the command buffer.
|
||||
///
|
||||
/// @param readableImages Images that will be transitioned from rw to read-only
|
||||
/// @param writableImages Images that will be transitioned from read-only to rw
|
||||
/// @param sampledImages Images that will be transitioned from rw to read-only
|
||||
/// @param storageImages Images that will be transitioned from read-only to rw
|
||||
///
|
||||
/// @throws std::logic_error if the command buffer is not in Recording state
|
||||
///
|
||||
void insertBarrier(
|
||||
const std::vector<std::optional<Core::Image>>& readableImages,
|
||||
const std::vector<Core::Image>& writableImages) const;
|
||||
const std::vector<std::optional<Core::Image>>& sampledImages,
|
||||
const std::vector<Core::Image>& storageImages) const;
|
||||
|
||||
///
|
||||
/// Copy a buffer to an image.
|
||||
|
|
|
|||
|
|
@ -30,22 +30,22 @@ namespace VK::Helper {
|
|||
[[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 {
|
||||
[[nodiscard]] const auto& getSetAt(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 sampled images for a specific frame index.
|
||||
[[nodiscard]] const auto& getSampledImagesAt(size_t index) const {
|
||||
return this->set(index).sampled;
|
||||
}
|
||||
/// Get the writable images for a specific frame index.
|
||||
[[nodiscard]] const auto& writablesAt(size_t index) const {
|
||||
return this->set(index).writables;
|
||||
/// Get the storage images for a specific frame index.
|
||||
[[nodiscard]] const auto& getStorageImagesAt(size_t index) const {
|
||||
return this->set(index).storage;
|
||||
}
|
||||
private:
|
||||
struct Set {
|
||||
Core::DescriptorSet sets;
|
||||
std::vector<std::optional<Core::Image>> readables;
|
||||
std::vector<Core::Image> writables;
|
||||
std::vector<std::optional<Core::Image>> sampled;
|
||||
std::vector<Core::Image> storage;
|
||||
};
|
||||
std::vector<Set> sets;
|
||||
|
||||
|
|
@ -87,85 +87,85 @@ namespace VK::Helper {
|
|||
return *this;
|
||||
}
|
||||
|
||||
/// Add an input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const Core::Image& image) {
|
||||
/// Add a sampled image to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const Core::Image& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(image);
|
||||
recipe.sampled.emplace_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add an optional input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const std::optional<Core::Image>& image) {
|
||||
/// Add an optional sampled image to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const std::optional<Core::Image>& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(image);
|
||||
recipe.sampled.emplace_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add multiple input images to the descriptor.
|
||||
MultiSetBuilder& addInput(const std::vector<Core::Image>& images) {
|
||||
/// Add multiple sampled images to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const std::vector<Core::Image>& images) {
|
||||
for (auto& recipe : this->recipes)
|
||||
for (const auto& img : images)
|
||||
recipe.inImages.emplace_back(img);
|
||||
recipe.sampled.emplace_back(img);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a temporal input image to the descriptor.
|
||||
MultiSetBuilder& addInput(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
/// Add a temporal sampled image to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.inImages.emplace_back(temporalImage.at(offset++));
|
||||
recipe.sampled.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());
|
||||
/// Add a group of sampled images to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const ImageGroup& imageGroup) {
|
||||
this->addSampledImage(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));
|
||||
/// Add a subgroup of sampled images to the descriptor.
|
||||
MultiSetBuilder& addSampledImage(const ImageGroup& imageGroup, size_t start, size_t length) {
|
||||
this->addSampledImage(imageGroup.subGroup(start, length));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add all mipmapped images to the descriptor.
|
||||
MultiSetBuilder& addInput(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addInput(mipmappedImage.into());
|
||||
MultiSetBuilder& addSampledImage(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addSampledImage(mipmappedImage.into());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add an output image to the descriptor.
|
||||
MultiSetBuilder& addOutput(const Core::Image& image) {
|
||||
/// Add a storage image to the descriptor.
|
||||
MultiSetBuilder& addStorageImage(const Core::Image& image) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.outImages.push_back(image);
|
||||
recipe.storage.push_back(image);
|
||||
return *this;
|
||||
}
|
||||
/// Add multiple output images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const std::vector<Core::Image>& images) {
|
||||
/// Add multiple storage images to the descriptor.
|
||||
MultiSetBuilder& addStorageImage(const std::vector<Core::Image>& images) {
|
||||
for (auto& recipe : this->recipes)
|
||||
for (const auto& img : images)
|
||||
recipe.outImages.push_back(img);
|
||||
recipe.storage.push_back(img);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add a temporal output image to the descriptor.
|
||||
MultiSetBuilder& addOutput(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
/// Add a temporal storage image to the descriptor.
|
||||
MultiSetBuilder& addStorageImage(const TemporalImage& temporalImage, size_t offset = 0) {
|
||||
for (auto& recipe : this->recipes)
|
||||
recipe.outImages.push_back(temporalImage.at(offset++));
|
||||
recipe.storage.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());
|
||||
/// Add a group of storage images to the descriptor.
|
||||
MultiSetBuilder& addStorageImage(const ImageGroup& imageGroup) {
|
||||
this->addStorageImage(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));
|
||||
/// Add a subgroup of storage images to the descriptor.
|
||||
MultiSetBuilder& addStorageImage(const ImageGroup& imageGroup, size_t start, size_t length) {
|
||||
this->addStorageImage(imageGroup.subGroup(start, length));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add all mipmapped images to the descriptor.
|
||||
MultiSetBuilder& addOutput(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addOutput(mipmappedImage.into());
|
||||
MultiSetBuilder& addStorageImage(const Helper::MipmappedImage& mipmappedImage) {
|
||||
this->addStorageImage(mipmappedImage.into());
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -186,8 +186,8 @@ namespace VK::Helper {
|
|||
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<std::optional<Core::Image>> sampled;
|
||||
std::vector<Core::Image> storage;
|
||||
};
|
||||
std::vector<SetRecipe> recipes;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -78,23 +78,24 @@ void CommandBuffer::bindDescriptorSet(const Pipeline& pipeline, const Descriptor
|
|||
}
|
||||
|
||||
void CommandBuffer::insertBarrier(
|
||||
const std::vector<VkImage>& images) const {
|
||||
const std::vector<Core::Image>& images) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
||||
std::vector<VkImageMemoryBarrier2> barriers(images.size());
|
||||
for (size_t i = 0; i < images.size(); i++) {
|
||||
barriers[i] = {
|
||||
std::vector<VkImageMemoryBarrier2> barriers;
|
||||
barriers.reserve(images.size());
|
||||
for (const auto& image : images) {
|
||||
barriers.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER_2,
|
||||
.oldLayout = VK_IMAGE_LAYOUT_UNDEFINED,
|
||||
.newLayout = VK_IMAGE_LAYOUT_GENERAL,
|
||||
.image = images[i],
|
||||
.image = image.handle(),
|
||||
.subresourceRange = {
|
||||
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
|
||||
.levelCount = 1,
|
||||
.layerCount = 1
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const VkDependencyInfo dependencyInfo = {
|
||||
|
|
@ -106,8 +107,8 @@ void CommandBuffer::insertBarrier(
|
|||
}
|
||||
|
||||
void CommandBuffer::insertBarrier(
|
||||
const std::vector<std::optional<Core::Image>>& readableImages,
|
||||
const std::vector<Core::Image>& writableImages) const {
|
||||
const std::vector<std::optional<Core::Image>>& sampledImages,
|
||||
const std::vector<Core::Image>& storageImages) const {
|
||||
if (*this->state != CommandBufferState::Recording)
|
||||
throw std::logic_error("Command buffer is not in Recording state");
|
||||
|
||||
|
|
@ -123,11 +124,11 @@ void CommandBuffer::insertBarrier(
|
|||
}
|
||||
};
|
||||
|
||||
const size_t totalImages = readableImages.size() + writableImages.size();
|
||||
const size_t totalImages = sampledImages.size() + storageImages.size();
|
||||
std::vector<VkImageMemoryBarrier2> barriers;
|
||||
barriers.reserve(totalImages);
|
||||
|
||||
for (const auto& image : readableImages) {
|
||||
for (const auto& image : sampledImages) {
|
||||
if (!image.has_value())
|
||||
continue;
|
||||
VkImageMemoryBarrier2& barrier = barriers.emplace_back(dummyBarrier);
|
||||
|
|
@ -136,7 +137,7 @@ void CommandBuffer::insertBarrier(
|
|||
barrier.image = image->handle();
|
||||
}
|
||||
|
||||
for (const auto& image : writableImages) {
|
||||
for (const auto& image : storageImages) {
|
||||
VkImageMemoryBarrier2& barrier = barriers.emplace_back(dummyBarrier);
|
||||
barrier.srcAccessMask = VK_ACCESS_2_SHADER_READ_BIT;
|
||||
barrier.dstAccessMask = VK_ACCESS_2_SHADER_WRITE_BIT;
|
||||
|
|
@ -215,8 +216,10 @@ void CommandBuffer::submit(const Device& device, std::optional<Fence> fence,
|
|||
throw std::logic_error("Command buffer is not in Full state");
|
||||
|
||||
// create wait semaphores and values
|
||||
std::vector<VkSemaphore> waitSemaphores(waitTimelines.size() + wait.size());
|
||||
std::vector<uint64_t> waitSemaphoreValues(waitTimelines.size() + wait.size());
|
||||
std::vector<VkSemaphore> waitSemaphores;
|
||||
waitSemaphores.reserve(waitTimelines.size() + wait.size());
|
||||
std::vector<uint64_t> waitSemaphoreValues;
|
||||
waitSemaphoreValues.reserve(waitTimelines.size() + wait.size());
|
||||
for (const auto& entry : waitTimelines) {
|
||||
waitSemaphores.push_back(entry.first.handle());
|
||||
waitSemaphoreValues.push_back(entry.second);
|
||||
|
|
@ -225,8 +228,10 @@ void CommandBuffer::submit(const Device& device, std::optional<Fence> fence,
|
|||
waitSemaphores.push_back(semaphore.handle());
|
||||
|
||||
// create signal semaphores and values
|
||||
std::vector<VkSemaphore> signalSemaphores(signalTimelines.size() + signal.size());
|
||||
std::vector<uint64_t> signalSemaphoreValues(signalTimelines.size() + signal.size());
|
||||
std::vector<VkSemaphore> signalSemaphores;
|
||||
signalSemaphores.reserve(signalTimelines.size() + signal.size());
|
||||
std::vector<uint64_t> signalSemaphoreValues;
|
||||
signalSemaphoreValues.reserve(signalTimelines.size() + signal.size());
|
||||
for (const auto& entry : signalTimelines) {
|
||||
signalSemaphores.push_back(entry.first.handle());
|
||||
signalSemaphoreValues.push_back(entry.second);
|
||||
|
|
|
|||
|
|
@ -74,12 +74,12 @@ DescriptorSet::DescriptorSet(const Device& device,
|
|||
}))
|
||||
});
|
||||
|
||||
size_t inputIdx{32};
|
||||
size_t sampledIdx{32};
|
||||
for (const auto& img : sampledImages) {
|
||||
entries.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSetHandle,
|
||||
.dstBinding = static_cast<uint32_t>(inputIdx++),
|
||||
.dstBinding = static_cast<uint32_t>(sampledIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.pImageInfo = &(imageInfos.emplace_back(VkDescriptorImageInfo{
|
||||
|
|
@ -90,12 +90,12 @@ DescriptorSet::DescriptorSet(const Device& device,
|
|||
});
|
||||
}
|
||||
|
||||
size_t outputIdx{48};
|
||||
size_t storageIdx{48};
|
||||
for (const auto& img : storageImages)
|
||||
entries.push_back({
|
||||
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET,
|
||||
.dstSet = descriptorSetHandle,
|
||||
.dstBinding = static_cast<uint32_t>(outputIdx++),
|
||||
.dstBinding = static_cast<uint32_t>(storageIdx++),
|
||||
.descriptorCount = 1,
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.pImageInfo = &(imageInfos.emplace_back(VkDescriptorImageInfo{
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& cod
|
|||
layoutBindings.reserve(buffers + samplers + sampledImages + storageImages);
|
||||
|
||||
for (size_t i = 0; i < buffers; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
layoutBindings.push_back({
|
||||
.binding = static_cast<uint32_t>(i),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER,
|
||||
.descriptorCount = 1,
|
||||
|
|
@ -42,7 +42,7 @@ ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& cod
|
|||
});
|
||||
|
||||
for (size_t i = 0; i < samplers; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
layoutBindings.push_back({
|
||||
.binding = static_cast<uint32_t>(i + 16),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLER,
|
||||
.descriptorCount = 1,
|
||||
|
|
@ -50,7 +50,7 @@ ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& cod
|
|||
});
|
||||
|
||||
for (size_t i = 0; i < sampledImages; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
layoutBindings.push_back({
|
||||
.binding = static_cast<uint32_t>(i + 32),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
|
|
@ -58,7 +58,7 @@ ShaderModule::ShaderModule(const Device& device, const std::vector<uint8_t>& cod
|
|||
});
|
||||
|
||||
for (size_t i = 0; i < storageImages; i++)
|
||||
layoutBindings.emplace_back(VkDescriptorSetLayoutBinding {
|
||||
layoutBindings.push_back({
|
||||
.binding = static_cast<uint32_t>(i + 48),
|
||||
.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.descriptorCount = 1,
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ MultiSet MultiSetBuilder::build(
|
|||
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
|
||||
recipe.sampled, recipe.storage, this->samplers, this->buffer),
|
||||
.sampled = recipe.sampled,
|
||||
.storage = recipe.storage
|
||||
});
|
||||
|
||||
return multiset;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue