More abstraction...

Signed-off-by: Slendi <slendi@socopon.com>
This commit is contained in:
2025-12-11 11:09:07 +02:00
parent 42f5eb7426
commit be453697f0
7 changed files with 254 additions and 14 deletions

View File

@@ -110,7 +110,9 @@ exe = executable('vr-compositor',
'src/DescriptorLayoutBuilder.cpp', 'src/DescriptorLayoutBuilder.cpp',
'src/DescriptorAllocator.cpp', 'src/DescriptorAllocator.cpp',
'src/GraphicsPipelineBuilder.cpp', 'src/GraphicsPipelineBuilder.cpp',
'src/DescriptorAllocatorGrowable.cpp',
'src/Loader.cpp', 'src/Loader.cpp',
'src/DescriptorWriter.cpp',
'src/VulkanRenderer.cpp', 'src/VulkanRenderer.cpp',
'src/Application.cpp', 'src/Application.cpp',
], ],

View File

@@ -0,0 +1,113 @@
#include "DescriptorAllocatorGrowable.h"
#include "Logger.h"
#include "Util.h"
namespace Lunar {
auto DescriptorAllocatorGrowable::init(VkDevice dev, uint32_t max_sets,
std::span<PoolSizeRatio> pool_ratios) -> void
{
m_ratios.clear();
m_ratios.insert(m_ratios.begin(), pool_ratios.begin(), pool_ratios.end());
auto const new_pool = create_pool(dev, max_sets, pool_ratios);
m_sets_per_pool = static_cast<uint32_t>(max_sets * 1.5);
if (m_sets_per_pool > 4092)
m_sets_per_pool = 4092;
m_ready_pools.emplace_back(new_pool);
}
auto DescriptorAllocatorGrowable::clear_pools(VkDevice dev) -> void
{
for (auto const p : m_ready_pools)
vkResetDescriptorPool(dev, p, 0);
for (auto const p : m_full_pools) {
vkResetDescriptorPool(dev, p, 0);
m_ready_pools.emplace_back(p);
}
m_full_pools.clear();
}
auto DescriptorAllocatorGrowable::destroy_pools(VkDevice dev) -> void
{
for (auto const p : m_ready_pools) {
vkDestroyDescriptorPool(dev, p, nullptr);
}
m_ready_pools.clear();
for (auto const p : m_full_pools) {
vkDestroyDescriptorPool(dev, p, nullptr);
}
m_full_pools.clear();
}
auto DescriptorAllocatorGrowable::allocate(Logger &logger, VkDevice dev,
VkDescriptorSetLayout layout, void *p_next) -> VkDescriptorSet
{
auto pool_to_use = get_pool(dev);
VkDescriptorSetAllocateInfo alloci {};
alloci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
alloci.pNext = p_next;
alloci.descriptorPool = pool_to_use;
alloci.descriptorSetCount = 1;
alloci.pSetLayouts = &layout;
VkDescriptorSet ds;
auto const res = vkAllocateDescriptorSets(dev, &alloci, &ds);
if (res == VK_ERROR_OUT_OF_POOL_MEMORY || res == VK_ERROR_FRAGMENTED_POOL) {
m_full_pools.emplace_back(pool_to_use);
pool_to_use = get_pool(dev);
alloci.descriptorPool = pool_to_use;
VK_CHECK(logger, vkAllocateDescriptorSets(dev, &alloci, &ds));
}
m_ready_pools.emplace_back(pool_to_use);
return ds;
}
auto DescriptorAllocatorGrowable::get_pool(VkDevice dev) -> VkDescriptorPool
{
VkDescriptorPool new_pool;
if (m_ready_pools.empty()) {
new_pool = create_pool(dev, m_sets_per_pool, m_ratios);
m_sets_per_pool = static_cast<uint32_t>(m_sets_per_pool * 1.5);
if (m_sets_per_pool > 4092)
m_sets_per_pool = 4092;
} else {
new_pool = m_ready_pools.back();
m_ready_pools.pop_back();
}
return new_pool;
}
auto DescriptorAllocatorGrowable::create_pool(VkDevice dev, uint32_t set_count,
std::span<PoolSizeRatio> pool_ratios) -> VkDescriptorPool
{
std::vector<VkDescriptorPoolSize> pool_sizes;
for (auto const ratio : pool_ratios) {
pool_sizes.emplace_back(VkDescriptorPoolSize {
.type = ratio.type,
.descriptorCount = static_cast<uint32_t>(ratio.ratio * set_count),
});
}
VkDescriptorPoolCreateInfo pool_ci {};
pool_ci.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
pool_ci.flags = 0;
pool_ci.maxSets = set_count;
pool_ci.poolSizeCount = static_cast<uint32_t>(pool_sizes.size());
pool_ci.pPoolSizes = pool_sizes.data();
VkDescriptorPool new_pool;
vkCreateDescriptorPool(dev, &pool_ci, nullptr, &new_pool);
return new_pool;
}
} // namespace Lunar

View File

@@ -0,0 +1,38 @@
#pragma once
#include <span>
#include <vector>
#include <vulkan/vulkan_core.h>
#include "Logger.h"
namespace Lunar {
struct DescriptorAllocatorGrowable {
struct PoolSizeRatio {
VkDescriptorType type;
float ratio;
};
auto init(VkDevice dev, uint32_t max_sets,
std::span<PoolSizeRatio> pool_ratios) -> void;
auto clear_pools(VkDevice dev) -> void;
auto destroy_pools(VkDevice dev) -> void;
auto allocate(Logger &logger, VkDevice dev, VkDescriptorSetLayout layout,
void *p_next = nullptr) -> VkDescriptorSet;
private:
auto get_pool(VkDevice dev) -> VkDescriptorPool;
auto create_pool(VkDevice dev, uint32_t set_count,
std::span<PoolSizeRatio> pool_ratios) -> VkDescriptorPool;
std::vector<PoolSizeRatio> m_ratios;
std::vector<VkDescriptorPool> m_full_pools;
std::vector<VkDescriptorPool> m_ready_pools;
uint32_t m_sets_per_pool;
};
} // namespace Lunar

70
src/DescriptorWriter.cpp Normal file
View File

@@ -0,0 +1,70 @@
#include "DescriptorWriter.h"
namespace Lunar {
auto DescriptorWriter::write_image(int binding, VkImageView image_view,
VkSampler sampler, VkImageLayout layout, VkDescriptorType type)
-> DescriptorWriter &
{
auto const &info = image_infos.emplace_back(VkDescriptorImageInfo {
.sampler = sampler,
.imageView = image_view,
.imageLayout = layout,
});
VkWriteDescriptorSet write {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.pNext = nullptr;
write.dstBinding = binding;
write.dstSet = VK_NULL_HANDLE;
write.descriptorCount = 1;
write.descriptorType = type;
write.pImageInfo = &info;
writes.emplace_back(write);
return *this;
}
auto DescriptorWriter::write_buffer(int binding, VkBuffer buffer, size_t size,
size_t offset, VkDescriptorType type) -> DescriptorWriter &
{
auto const &info = buffer_infos.emplace_back(VkDescriptorBufferInfo {
.buffer = buffer,
.offset = offset,
.range = size,
});
VkWriteDescriptorSet write {};
write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
write.pNext = nullptr;
write.dstBinding = binding;
write.dstSet = VK_NULL_HANDLE;
write.descriptorCount = 1;
write.descriptorType = type;
write.pBufferInfo = &info;
writes.emplace_back(write);
return *this;
}
auto DescriptorWriter::clear() -> DescriptorWriter &
{
image_infos.clear();
writes.clear();
buffer_infos.clear();
return *this;
}
auto DescriptorWriter::update_set(VkDevice dev, VkDescriptorSet set) -> void
{
for (auto &write : writes) {
write.dstSet = set;
}
vkUpdateDescriptorSets(
dev, static_cast<uint32_t>(writes.size()), writes.data(), 0, nullptr);
}
} // namespace Lunar

24
src/DescriptorWriter.h Normal file
View File

@@ -0,0 +1,24 @@
#pragma once
#include <deque>
#include <vector>
#include <vulkan/vulkan_core.h>
namespace Lunar {
struct DescriptorWriter {
std::deque<VkDescriptorImageInfo> image_infos;
std::deque<VkDescriptorBufferInfo> buffer_infos;
std::vector<VkWriteDescriptorSet> writes;
auto write_image(int binding, VkImageView image_view, VkSampler sampler,
VkImageLayout layout, VkDescriptorType type) -> DescriptorWriter &;
auto write_buffer(int binding, VkBuffer buffer, size_t size, size_t offset,
VkDescriptorType type) -> DescriptorWriter &;
auto clear() -> DescriptorWriter &;
auto update_set(VkDevice dev, VkDescriptorSet set) -> void;
};
} // namespace Lunar

View File

@@ -5,6 +5,7 @@
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include "DeletionQueue.h" #include "DeletionQueue.h"
#include "DescriptorAllocatorGrowable.h"
namespace Lunar { namespace Lunar {
@@ -29,6 +30,7 @@ struct FrameData {
VkFence render_fence; VkFence render_fence;
DeletionQueue deletion_queue; DeletionQueue deletion_queue;
DescriptorAllocatorGrowable frame_descriptors;
}; };
struct Vertex { struct Vertex {

View File

@@ -14,6 +14,7 @@
#include <vulkan/vulkan_core.h> #include <vulkan/vulkan_core.h>
#include "DescriptorLayoutBuilder.h" #include "DescriptorLayoutBuilder.h"
#include "DescriptorWriter.h"
#include "GraphicsPipelineBuilder.h" #include "GraphicsPipelineBuilder.h"
#include "Util.h" #include "Util.h"
@@ -940,20 +941,10 @@ auto VulkanRenderer::destroy_depth_image() -> void
auto VulkanRenderer::update_draw_image_descriptor() -> void auto VulkanRenderer::update_draw_image_descriptor() -> void
{ {
VkDescriptorImageInfo img_info {}; DescriptorWriter()
img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL; .write_image(0, m_vk.draw_image.image_view, VK_NULL_HANDLE,
img_info.imageView = m_vk.draw_image.image_view; VK_IMAGE_LAYOUT_GENERAL, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
.update_set(m_vkb.dev, m_vk.draw_image_descriptors);
VkWriteDescriptorSet draw_img_write {};
draw_img_write.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
draw_img_write.pNext = nullptr;
draw_img_write.dstBinding = 0;
draw_img_write.dstSet = m_vk.draw_image_descriptors;
draw_img_write.descriptorCount = 1;
draw_img_write.descriptorType = VK_DESCRIPTOR_TYPE_STORAGE_IMAGE;
draw_img_write.pImageInfo = &img_info;
vkUpdateDescriptorSets(m_vkb.dev, 1, &draw_img_write, 0, nullptr);
} }
auto VulkanRenderer::destroy_draw_image() -> void auto VulkanRenderer::destroy_draw_image() -> void