proper descriptor pooling (prerequisite for properly segregating pipelines as shareable and descriptor sets as not)
This commit is contained in:
parent
a10ed8bc60
commit
5f5bc08068
@ -118,7 +118,7 @@
|
||||
"gui": true,
|
||||
"vsync": true, // vsync on vulkan side rather than engine-side
|
||||
"hdr": true,
|
||||
"vxgi": false,
|
||||
"vxgi": true,
|
||||
"culling": false,
|
||||
"bloom": false,
|
||||
"dof": false,
|
||||
|
||||
@ -29,6 +29,30 @@ namespace ext {
|
||||
operator VkCommandBuffer() { return handle; }
|
||||
};
|
||||
|
||||
struct DescriptorAllocator {
|
||||
VkDevice device = VK_NULL_HANDLE;
|
||||
VkDescriptorPool currentPool = VK_NULL_HANDLE;
|
||||
uf::stl::vector<VkDescriptorPool> usedPools;
|
||||
|
||||
uf::stl::vector<VkDescriptorPoolSize> poolSizes = {
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLER, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 4000 },
|
||||
{ VK_DESCRIPTOR_TYPE_SAMPLED_IMAGE, 4000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_IMAGE, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 2000 },
|
||||
{ VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 2000 },
|
||||
{ VK_DESCRIPTOR_TYPE_STORAGE_BUFFER_DYNAMIC, 1000 },
|
||||
{ VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT, 500 },
|
||||
{ VK_DESCRIPTOR_TYPE_ACCELERATION_STRUCTURE_KHR, 100 }
|
||||
};
|
||||
|
||||
void initialize( VkDevice );
|
||||
void destroy();
|
||||
VkDescriptorPool createPool();
|
||||
bool allocate( VkDescriptorSet* set, VkDescriptorSetLayout layout );
|
||||
};
|
||||
|
||||
struct Texture;
|
||||
|
||||
struct UF_API Device {
|
||||
@ -69,6 +93,7 @@ namespace ext {
|
||||
} extensions;
|
||||
|
||||
VkPipelineCache pipelineCache;
|
||||
DescriptorAllocator descriptorAllocator;
|
||||
|
||||
uf::stl::vector<VkQueueFamilyProperties> queueFamilyProperties;
|
||||
|
||||
|
||||
@ -12,6 +12,8 @@ namespace ext {
|
||||
struct Graphic;
|
||||
|
||||
struct UF_API Pipeline : public Buffers {
|
||||
static uf::stl::unordered_map<GraphicDescriptor, Pipeline> pipelines;
|
||||
|
||||
bool aliased = false;
|
||||
|
||||
Device* device = NULL;
|
||||
@ -42,9 +44,6 @@ namespace ext {
|
||||
void record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer, size_t = 0, size_t = 0, size_t = 0 ) const;
|
||||
void destroy();
|
||||
|
||||
uf::stl::vector<Shader*> getShaders( uf::stl::vector<Shader>&, const uf::stl::string& = "" );
|
||||
uf::stl::vector<const Shader*> getShaders( const uf::stl::vector<Shader>&, const uf::stl::string& = "" ) const;
|
||||
|
||||
void collectBuffers( const Shader& shader, const RenderMode& renderMode, const Graphic& graphic, const std::function<void(const Buffer&)>& lambda ) const;
|
||||
};
|
||||
|
||||
@ -73,6 +72,8 @@ namespace ext {
|
||||
Shader& getShader( const uf::stl::string& type, const uf::stl::string& pipeline = "" );
|
||||
const Shader& getShader( const uf::stl::string& type, const uf::stl::string& pipeline = "" ) const;
|
||||
|
||||
uf::stl::vector<const Shader*> getShaders( const uf::stl::string& = "" ) const;
|
||||
|
||||
bool validate();
|
||||
};
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include <uf/ext/vulkan/vulkan.h>
|
||||
#include <uf/ext/vulkan/device.h>
|
||||
#include <uf/ext/vulkan/graphic.h>
|
||||
#include <uf/ext/vulkan/initializers.h>
|
||||
#include <uf/utils/window/window.h>
|
||||
#include <uf/utils/string/ext.h>
|
||||
@ -1178,8 +1179,8 @@ void ext::vulkan::Device::initialize() {
|
||||
}
|
||||
|
||||
struct BaseStructure {
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
VkStructureType sType;
|
||||
void* pNext;
|
||||
};
|
||||
std::queue<void*> chain = {};
|
||||
|
||||
@ -1457,7 +1458,7 @@ void ext::vulkan::Device::initialize() {
|
||||
if ( uf::io::exists( uf::io::root + "/cache/vulkan/cache.bin" ) ) {
|
||||
uf::io::readAsBuffer( buffer, uf::io::root + "/cache/vulkan/cache.bin" );
|
||||
pipelineCacheCreateInfo.initialDataSize = buffer.size();
|
||||
pipelineCacheCreateInfo.pInitialData = buffer.data();
|
||||
pipelineCacheCreateInfo.pInitialData = buffer.data();
|
||||
}
|
||||
|
||||
VK_CHECK_RESULT(vkCreatePipelineCache( device, &pipelineCacheCreateInfo, nullptr, &this->pipelineCache));
|
||||
@ -1507,6 +1508,10 @@ void ext::vulkan::Device::initialize() {
|
||||
VK_REGISTER_HANDLE( allocator );
|
||||
}
|
||||
|
||||
{
|
||||
descriptorAllocator.initialize( logicalDevice );
|
||||
}
|
||||
|
||||
{
|
||||
vkGetBufferDeviceAddressKHR = reinterpret_cast<PFN_vkGetBufferDeviceAddressKHR>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR"));
|
||||
vkCmdBuildAccelerationStructuresKHR = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR"));
|
||||
@ -1569,6 +1574,12 @@ void ext::vulkan::Device::destroy() {
|
||||
VK_UNREGISTER_HANDLE( this->pipelineCache );
|
||||
this->pipelineCache = nullptr;
|
||||
}
|
||||
|
||||
for ( auto& pair : Pipeline::pipelines ) pair.second.destroy();
|
||||
Pipeline::pipelines.clear();
|
||||
|
||||
descriptorAllocator.destroy();
|
||||
|
||||
for ( auto& pair : this->commandPool.graphics.container() ) {
|
||||
vkDestroyCommandPool( this->logicalDevice, pair.second, nullptr );
|
||||
VK_UNREGISTER_HANDLE( pair.second );
|
||||
@ -1608,4 +1619,50 @@ void ext::vulkan::Device::destroy() {
|
||||
VK_UNREGISTER_HANDLE( allocator );
|
||||
}
|
||||
|
||||
void ext::vulkan::DescriptorAllocator::initialize(VkDevice inDevice) {
|
||||
device = inDevice;
|
||||
currentPool = createPool();
|
||||
}
|
||||
|
||||
void ext::vulkan::DescriptorAllocator::destroy() {
|
||||
if ( currentPool ) vkDestroyDescriptorPool(device, currentPool, nullptr);
|
||||
for ( auto p : usedPools ) vkDestroyDescriptorPool(device, p, nullptr);
|
||||
usedPools.clear();
|
||||
}
|
||||
|
||||
VkDescriptorPool ext::vulkan::DescriptorAllocator::createPool() {
|
||||
VkDescriptorPoolCreateInfo poolInfo = {};
|
||||
poolInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
poolInfo.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT;
|
||||
poolInfo.maxSets = 1000;
|
||||
poolInfo.poolSizeCount = (uint32_t) poolSizes.size();
|
||||
poolInfo.pPoolSizes = poolSizes.data();
|
||||
|
||||
VkDescriptorPool pool;
|
||||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &poolInfo, nullptr, &pool));
|
||||
return pool;
|
||||
}
|
||||
|
||||
bool ext::vulkan::DescriptorAllocator::allocate( VkDescriptorSet* set, VkDescriptorSetLayout layout ) {
|
||||
if ( currentPool == VK_NULL_HANDLE ) currentPool = createPool();
|
||||
|
||||
VkDescriptorSetAllocateInfo allocInfo = {};
|
||||
allocInfo.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
allocInfo.descriptorPool = currentPool;
|
||||
allocInfo.descriptorSetCount = 1;
|
||||
allocInfo.pSetLayouts = &layout;
|
||||
|
||||
VkResult result = vkAllocateDescriptorSets(device, &allocInfo, set);
|
||||
|
||||
if ( result == VK_ERROR_OUT_OF_POOL_MEMORY || result == VK_ERROR_FRAGMENTED_POOL ) {
|
||||
usedPools.push_back(currentPool);
|
||||
currentPool = createPool();
|
||||
allocInfo.descriptorPool = currentPool;
|
||||
|
||||
result = vkAllocateDescriptorSets(device, &allocInfo, set);
|
||||
}
|
||||
|
||||
return result == VK_SUCCESS;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -19,6 +19,8 @@ namespace {
|
||||
uint32_t VERTEX_BUFFER_BIND_ID = 0;
|
||||
}
|
||||
|
||||
uf::stl::unordered_map<ext::vulkan::GraphicDescriptor, ext::vulkan::Pipeline> ext::vulkan::Pipeline::pipelines;
|
||||
|
||||
PFN_vkGetBufferDeviceAddressKHR ext::vulkan::vkGetBufferDeviceAddressKHR = NULL; // = reinterpret_cast<PFN_vkGetBufferDeviceAddressKHR>(vkGetDeviceProcAddr(device, "vkGetBufferDeviceAddressKHR"));
|
||||
PFN_vkCmdBuildAccelerationStructuresKHR ext::vulkan::vkCmdBuildAccelerationStructuresKHR = NULL; // = reinterpret_cast<PFN_vkCmdBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkCmdBuildAccelerationStructuresKHR"));
|
||||
PFN_vkBuildAccelerationStructuresKHR ext::vulkan::vkBuildAccelerationStructuresKHR = NULL; // = reinterpret_cast<PFN_vkBuildAccelerationStructuresKHR>(vkGetDeviceProcAddr(device, "vkBuildAccelerationStructuresKHR"));
|
||||
@ -41,7 +43,7 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
this->metadata.type = descriptor.pipeline;
|
||||
Device& device = *graphic.device;
|
||||
|
||||
auto shaders = getShaders( graphic.material.shaders, descriptor.pipeline );
|
||||
auto shaders = graphic.material.getShaders( descriptor.pipeline );
|
||||
assert( shaders.size() > 0 );
|
||||
|
||||
uint32_t subpass = descriptor.subpass;
|
||||
@ -78,6 +80,7 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
offset += len;
|
||||
}
|
||||
}
|
||||
/*
|
||||
for ( auto& descriptor : descriptorSetLayoutBindings ) {
|
||||
if ( descriptorTypes.count( descriptor.descriptorType ) < 0 ) descriptorTypes[descriptor.descriptorType] = 0;
|
||||
descriptorTypes[descriptor.descriptorType] += descriptor.descriptorCount;
|
||||
@ -92,6 +95,7 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
);
|
||||
VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool));
|
||||
VK_REGISTER_HANDLE( descriptorPool );
|
||||
*/
|
||||
|
||||
VkDescriptorSetLayoutCreateInfo descriptorLayout = ext::vulkan::initializers::descriptorSetLayoutCreateInfo(
|
||||
descriptorSetLayoutBindings.data(),
|
||||
@ -100,12 +104,16 @@ void ext::vulkan::Pipeline::initialize( const Graphic& graphic, const GraphicDes
|
||||
VK_CHECK_RESULT(vkCreateDescriptorSetLayout( device, &descriptorLayout, nullptr, &descriptorSetLayout ));
|
||||
VK_REGISTER_HANDLE( descriptorSetLayout );
|
||||
|
||||
UF_ASSERT(device.descriptorAllocator.allocate( &descriptorSet, descriptorSetLayout ));
|
||||
|
||||
/*
|
||||
VkDescriptorSetAllocateInfo allocInfo = ext::vulkan::initializers::descriptorSetAllocateInfo(
|
||||
descriptorPool,
|
||||
&descriptorSetLayout,
|
||||
1
|
||||
);
|
||||
VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet));
|
||||
*/
|
||||
|
||||
VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = ext::vulkan::initializers::pipelineLayoutCreateInfo(
|
||||
&descriptorSetLayout,
|
||||
@ -396,7 +404,7 @@ void ext::vulkan::Pipeline::record( const Graphic& graphic, VkCommandBuffer comm
|
||||
return record( graphic, descriptor, commandBuffer, pass, draw, offset );
|
||||
}
|
||||
void ext::vulkan::Pipeline::record( const Graphic& graphic, const GraphicDescriptor& descriptor, VkCommandBuffer commandBuffer, size_t pass, size_t draw, size_t offset ) const {
|
||||
auto shaders = getShaders( graphic.material.shaders, descriptor.pipeline );
|
||||
auto shaders = graphic.material.getShaders( descriptor.pipeline );
|
||||
|
||||
// create dynamic offset ranges
|
||||
STATIC_THREAD_LOCAL(uf::stl::vector<uint32_t>, dynamicOffsets);
|
||||
@ -507,7 +515,7 @@ void ext::vulkan::Pipeline::update( const Graphic& graphic, const GraphicDescrip
|
||||
RenderMode& renderMode = ext::vulkan::getRenderMode(descriptor.renderMode, true);
|
||||
auto& renderTarget = renderMode.getRenderTarget(/*descriptor.renderTarget*/);
|
||||
|
||||
auto shaders = getShaders( graphic.material.shaders, descriptor.pipeline );
|
||||
auto shaders = graphic.material.getShaders( descriptor.pipeline );
|
||||
uf::stl::vector<VkWriteDescriptorSet> writeDescriptorSets;
|
||||
uf::stl::vector<uf::renderer::AccelerationStructure> tlases;
|
||||
|
||||
@ -948,32 +956,17 @@ void ext::vulkan::Pipeline::destroy() {
|
||||
}
|
||||
*/
|
||||
}
|
||||
uf::stl::vector<ext::vulkan::Shader*> ext::vulkan::Pipeline::getShaders( uf::stl::vector<ext::vulkan::Shader>& shaders, const uf::stl::string& type ) {
|
||||
uf::stl::unordered_map<uf::stl::string, ext::vulkan::Shader*> map;
|
||||
uf::stl::vector<ext::vulkan::Shader*> res;
|
||||
bool isCompute = false;
|
||||
for ( auto& shader : shaders ) {
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
|
||||
if ( shader.descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) isCompute = true;
|
||||
}
|
||||
for ( auto& shader : shaders ) {
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
|
||||
if ( isCompute && shader.descriptor.stage != VK_SHADER_STAGE_COMPUTE_BIT ) continue;
|
||||
map[shader.metadata.type] = &shader;
|
||||
}
|
||||
for ( auto pair : map ) res.insert( res.begin(), pair.second);
|
||||
return res;
|
||||
}
|
||||
uf::stl::vector<const ext::vulkan::Shader*> ext::vulkan::Pipeline::getShaders( const uf::stl::vector<ext::vulkan::Shader>& shaders, const uf::stl::string& type ) const {
|
||||
|
||||
uf::stl::vector<const ext::vulkan::Shader*> ext::vulkan::Material::getShaders( const uf::stl::string& type ) const {
|
||||
uf::stl::unordered_map<uf::stl::string, const ext::vulkan::Shader*> map;
|
||||
uf::stl::vector<const ext::vulkan::Shader*> res;
|
||||
bool isCompute = false;
|
||||
for ( auto& shader : shaders ) {
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != type ) continue;
|
||||
if ( shader.descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) isCompute = true;
|
||||
}
|
||||
for ( auto& shader : shaders ) {
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != (type == "" ? metadata.type : type) ) continue;
|
||||
if ( shader.metadata.pipeline != "" && shader.metadata.pipeline != type ) continue;
|
||||
if ( isCompute && shader.descriptor.stage != VK_SHADER_STAGE_COMPUTE_BIT ) continue;
|
||||
map[shader.metadata.type] = &shader;
|
||||
}
|
||||
@ -1852,7 +1845,7 @@ void ext::vulkan::Graphic::record( VkCommandBuffer commandBuffer, const GraphicD
|
||||
if ( !pipeline.metadata.process ) return;
|
||||
pipeline.record(*this, descriptor, commandBuffer, pass, draw, offset);
|
||||
|
||||
auto shaders = pipeline.getShaders( material.shaders, descriptor.pipeline );
|
||||
auto shaders = material.getShaders( descriptor.pipeline );
|
||||
for ( auto* shader : shaders ) {
|
||||
if ( shader->descriptor.stage == VK_SHADER_STAGE_COMPUTE_BIT ) return;
|
||||
if (
|
||||
|
||||
Loading…
Reference in New Issue
Block a user