mirror of
https://github.com/slendidev/lunar.git
synced 2025-12-13 03:49:51 +02:00
@@ -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',
|
||||||
],
|
],
|
||||||
|
|||||||
113
src/DescriptorAllocatorGrowable.cpp
Normal file
113
src/DescriptorAllocatorGrowable.cpp
Normal 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
|
||||||
38
src/DescriptorAllocatorGrowable.h
Normal file
38
src/DescriptorAllocatorGrowable.h
Normal 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
70
src/DescriptorWriter.cpp
Normal 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
24
src/DescriptorWriter.h
Normal 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
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user