@@ -4082,21 +4082,7 @@ void RenderingDeviceDriverVulkan::shader_destroy_modules(ShaderID p_shader) {
40824082/* ********************/
40834083/* *** UNIFORM SET ****/
40844084/* ********************/
4085- VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_create (const DescriptorSetPoolKey &p_key, DescriptorSetPools::Iterator *r_pool_sets_it, int p_linear_pool_index) {
4086- bool linear_pool = p_linear_pool_index >= 0 ;
4087- DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find (p_key) : descriptor_set_pools.find (p_key);
4088-
4089- if (pool_sets_it) {
4090- for (KeyValue<VkDescriptorPool, uint32_t > &E : pool_sets_it->value ) {
4091- if (E.value < max_descriptor_sets_per_pool) {
4092- *r_pool_sets_it = pool_sets_it;
4093- return E.key ;
4094- }
4095- }
4096- }
4097-
4098- // Create a new one.
4099-
4085+ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_create (const DescriptorSetPoolKey &p_key, bool p_linear_pool) {
41004086 // Here comes more vulkan API strangeness.
41014087 VkDescriptorPoolSize *vk_sizes = ALLOCA_ARRAY (VkDescriptorPoolSize, UNIFORM_TYPE_MAX);
41024088 uint32_t vk_sizes_count = 0 ;
@@ -4184,7 +4170,7 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat
41844170
41854171 VkDescriptorPoolCreateInfo descriptor_set_pool_create_info = {};
41864172 descriptor_set_pool_create_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
4187- if (linear_descriptor_pools_enabled && linear_pool ) {
4173+ if (linear_descriptor_pools_enabled && p_linear_pool ) {
41884174 descriptor_set_pool_create_info.flags = 0 ;
41894175 } else {
41904176 descriptor_set_pool_create_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; // Can't think how somebody may NOT need this flag.
@@ -4199,18 +4185,6 @@ VkDescriptorPool RenderingDeviceDriverVulkan::_descriptor_set_pool_find_or_creat
41994185 ERR_FAIL_COND_V_MSG (res, VK_NULL_HANDLE, " vkCreateDescriptorPool failed with error " + itos (res) + " ." );
42004186 }
42014187
4202- // Bookkeep.
4203-
4204- if (!pool_sets_it) {
4205- if (linear_pool) {
4206- pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert (p_key, HashMap<VkDescriptorPool, uint32_t >());
4207- } else {
4208- pool_sets_it = descriptor_set_pools.insert (p_key, HashMap<VkDescriptorPool, uint32_t >());
4209- }
4210- }
4211- HashMap<VkDescriptorPool, uint32_t > &pool_rcs = pool_sets_it->value ;
4212- pool_rcs.insert (vk_pool, 0 );
4213- *r_pool_sets_it = pool_sets_it;
42144188 return vk_pool;
42154189}
42164190
@@ -4454,27 +4428,55 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou
44544428 writes_amount++;
44554429 }
44564430
4457- // Need a descriptor pool.
4458- DescriptorSetPools::Iterator pool_sets_it;
4459- VkDescriptorPool vk_pool = _descriptor_set_pool_find_or_create (pool_key, &pool_sets_it, p_linear_pool_index);
4460- DEV_ASSERT (vk_pool);
4461- pool_sets_it->value [vk_pool]++;
4431+ bool linear_pool = p_linear_pool_index >= 0 ;
4432+ DescriptorSetPools::Iterator pool_sets_it = linear_pool ? linear_descriptor_set_pools[p_linear_pool_index].find (pool_key) : descriptor_set_pools.find (pool_key);
4433+ if (!pool_sets_it) {
4434+ if (linear_pool) {
4435+ pool_sets_it = linear_descriptor_set_pools[p_linear_pool_index].insert (pool_key, HashMap<VkDescriptorPool, uint32_t >());
4436+ } else {
4437+ pool_sets_it = descriptor_set_pools.insert (pool_key, HashMap<VkDescriptorPool, uint32_t >());
4438+ }
4439+ }
44624440
44634441 VkDescriptorSetAllocateInfo descriptor_set_allocate_info = {};
44644442 descriptor_set_allocate_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
4465- descriptor_set_allocate_info.descriptorPool = vk_pool;
44664443 descriptor_set_allocate_info.descriptorSetCount = 1 ;
44674444 const ShaderInfo *shader_info = (const ShaderInfo *)p_shader.id ;
44684445 descriptor_set_allocate_info.pSetLayouts = &shader_info->vk_descriptor_set_layouts [p_set_index];
44694446
44704447 VkDescriptorSet vk_descriptor_set = VK_NULL_HANDLE;
4448+ for (KeyValue<VkDescriptorPool, uint32_t > &E : pool_sets_it->value ) {
4449+ if (E.value < max_descriptor_sets_per_pool) {
4450+ descriptor_set_allocate_info.descriptorPool = E.key ;
4451+ VkResult res = vkAllocateDescriptorSets (vk_device, &descriptor_set_allocate_info, &vk_descriptor_set);
44714452
4472- VkResult res = vkAllocateDescriptorSets (vk_device, &descriptor_set_allocate_info, &vk_descriptor_set);
4473- if (res) {
4474- _descriptor_set_pool_unreference (pool_sets_it, vk_pool, p_linear_pool_index);
4475- ERR_FAIL_V_MSG (UniformSetID (), " Cannot allocate descriptor sets, error " + itos (res) + " ." );
4453+ // Break early on success.
4454+ if (res == VK_SUCCESS) {
4455+ break ;
4456+ }
4457+
4458+ // "Fragmented pool" and "out of memory pool" errors are handled by creating more pools. Any other error is unexpected.
4459+ if (res != VK_ERROR_FRAGMENTED_POOL && res != VK_ERROR_OUT_OF_POOL_MEMORY) {
4460+ ERR_FAIL_V_MSG (UniformSetID (), " Cannot allocate descriptor sets, error " + itos (res) + " ." );
4461+ }
4462+ }
44764463 }
44774464
4465+ // Create a new pool when no allocations could be made from the existing pools.
4466+ if (vk_descriptor_set == VK_NULL_HANDLE) {
4467+ descriptor_set_allocate_info.descriptorPool = _descriptor_set_pool_create (pool_key, linear_pool);
4468+ VkResult res = vkAllocateDescriptorSets (vk_device, &descriptor_set_allocate_info, &vk_descriptor_set);
4469+
4470+ // All errors are unexpected at this stage.
4471+ if (res) {
4472+ vkDestroyDescriptorPool (vk_device, descriptor_set_allocate_info.descriptorPool , VKC::get_allocation_callbacks (VK_OBJECT_TYPE_DESCRIPTOR_POOL));
4473+ ERR_FAIL_V_MSG (UniformSetID (), " Cannot allocate descriptor sets, error " + itos (res) + " ." );
4474+ }
4475+ }
4476+
4477+ DEV_ASSERT (descriptor_set_allocate_info.descriptorPool != VK_NULL_HANDLE && vk_descriptor_set != VK_NULL_HANDLE);
4478+ pool_sets_it->value [descriptor_set_allocate_info.descriptorPool ]++;
4479+
44784480 for (uint32_t i = 0 ; i < writes_amount; i++) {
44794481 vk_writes[i].dstSet = vk_descriptor_set;
44804482 }
@@ -4485,9 +4487,9 @@ RDD::UniformSetID RenderingDeviceDriverVulkan::uniform_set_create(VectorView<Bou
44854487 UniformSetInfo *usi = VersatileResource::allocate<UniformSetInfo>(resources_allocator);
44864488 usi->vk_descriptor_set = vk_descriptor_set;
44874489 if (p_linear_pool_index >= 0 ) {
4488- usi->vk_linear_descriptor_pool = vk_pool ;
4490+ usi->vk_linear_descriptor_pool = descriptor_set_allocate_info. descriptorPool ;
44894491 } else {
4490- usi->vk_descriptor_pool = vk_pool ;
4492+ usi->vk_descriptor_pool = descriptor_set_allocate_info. descriptorPool ;
44914493 }
44924494 usi->pool_sets_it = pool_sets_it;
44934495 usi->dynamic_buffers .resize (num_dynamic_buffers);
0 commit comments