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/DescriptorAllocator.cpp',
|
||||
'src/GraphicsPipelineBuilder.cpp',
|
||||
'src/DescriptorAllocatorGrowable.cpp',
|
||||
'src/Loader.cpp',
|
||||
'src/DescriptorWriter.cpp',
|
||||
'src/VulkanRenderer.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 "DeletionQueue.h"
|
||||
#include "DescriptorAllocatorGrowable.h"
|
||||
|
||||
namespace Lunar {
|
||||
|
||||
@@ -29,6 +30,7 @@ struct FrameData {
|
||||
VkFence render_fence;
|
||||
|
||||
DeletionQueue deletion_queue;
|
||||
DescriptorAllocatorGrowable frame_descriptors;
|
||||
};
|
||||
|
||||
struct Vertex {
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
#include "DescriptorLayoutBuilder.h"
|
||||
#include "DescriptorWriter.h"
|
||||
#include "GraphicsPipelineBuilder.h"
|
||||
#include "Util.h"
|
||||
|
||||
@@ -940,20 +941,10 @@ auto VulkanRenderer::destroy_depth_image() -> void
|
||||
|
||||
auto VulkanRenderer::update_draw_image_descriptor() -> void
|
||||
{
|
||||
VkDescriptorImageInfo img_info {};
|
||||
img_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
|
||||
img_info.imageView = m_vk.draw_image.image_view;
|
||||
|
||||
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);
|
||||
DescriptorWriter()
|
||||
.write_image(0, m_vk.draw_image.image_view, VK_NULL_HANDLE,
|
||||
VK_IMAGE_LAYOUT_GENERAL, VK_DESCRIPTOR_TYPE_STORAGE_IMAGE)
|
||||
.update_set(m_vkb.dev, m_vk.draw_image_descriptors);
|
||||
}
|
||||
|
||||
auto VulkanRenderer::destroy_draw_image() -> void
|
||||
|
||||
Reference in New Issue
Block a user