diff --git a/source/ref_nri/r_descriptor_pool.c b/source/ref_nri/r_descriptor_pool.c index dee5a1f7eb..2687e6df9b 100644 --- a/source/ref_nri/r_descriptor_pool.c +++ b/source/ref_nri/r_descriptor_pool.c @@ -83,7 +83,7 @@ void DetachDescriptorSlot( struct DescriptorSetAllocator *alloc, struct descript } } -struct descriptor_set_result_s ResolveDescriptorSet( struct RIDevice_s *device, struct DescriptorSetAllocator *alloc, uint32_t frameCount, uint32_t hash ) +struct descriptor_set_result_s ResolveDescriptorSet( struct RIDevice_s *device, struct DescriptorSetAllocator *alloc, uint32_t frameCount, hash_t hash ) { struct descriptor_set_result_s result = { 0 }; const size_t hashIndex = hash % ALLOC_HASH_RESERVE; diff --git a/source/ref_nri/r_descriptor_pool.h b/source/ref_nri/r_descriptor_pool.h index e5017e64da..05326db328 100644 --- a/source/ref_nri/r_descriptor_pool.h +++ b/source/ref_nri/r_descriptor_pool.h @@ -15,7 +15,7 @@ #define DESCRIPTOR_RESERVED_SIZE 64 struct descriptor_set_slot_s { - uint32_t hash; + hash_t hash; uint32_t frameCount; // queue struct descriptor_set_slot_s *quNext; @@ -70,7 +70,7 @@ struct descriptor_set_result_s { struct descriptor_set_result_s ResolveDescriptorSet( struct RIDevice_s *device, struct DescriptorSetAllocator *alloc, uint32_t frameCount, - uint32_t hash ); + hash_t hash ); void FreeDescriptorSetAlloc( struct RIDevice_s *device, struct DescriptorSetAllocator *alloc ); // utility diff --git a/source/ref_nri/r_program.c b/source/ref_nri/r_program.c index 2188c7fb35..3f2728d953 100644 --- a/source/ref_nri/r_program.c +++ b/source/ref_nri/r_program.c @@ -1197,8 +1197,10 @@ void RP_BindDescriptorSets( struct RIDevice_s *device, struct FrameState_s *cmd, TracyCZoneN( ctx, "RP_BindDescriptorSets", 1 ); #if ( DEVICE_IMPL_VULKAN ) { - size_t numWrites = 0; - VkWriteDescriptorSet descriptorWrite[32]; // write 32 descriptors at once + VkDescriptorSet setsToBind[R_DESCRIPTOR_SET_MAX] = { VK_NULL_HANDLE }; + uint32_t firstSetToBind = 0; + uint32_t setsToBindCount = 0; + for( uint32_t setIndex = 0; setIndex < R_DESCRIPTOR_SET_MAX; setIndex++ ) { hash_t hash = HASH_INITIAL_VALUE; for( size_t i = 0; i < numDescriptorData; i++ ) { @@ -1206,20 +1208,26 @@ void RP_BindDescriptorSets( struct RIDevice_s *device, struct FrameState_s *cmd, if( !refl || setIndex != refl->set || RI_IsEmptyDescriptor( &bindings[i].descriptor ) ) continue; hash = hash_u64( hash, refl->hash ); - assert(bindings[i].descriptor.cookie != 0); // the cookie can't be 0 + hash = hash_u64(hash, bindings[i].registerOffset); + assert( bindings[i].descriptor.cookie != 0 ); hash = hash_u64( hash, bindings[i].descriptor.cookie ); } - if( hash == HASH_INITIAL_VALUE ) + if( hash == HASH_INITIAL_VALUE ) continue; struct glsl_program_descriptor_s *info = &program->programDescriptors[setIndex]; struct descriptor_set_result_s result = ResolveDescriptorSet( &rsh.device, &info->alloc, rsh.frameSetCount, hash ); if( !result.found ) { + size_t numWrites = 0; + VkWriteDescriptorSet descriptorWrite[32]; for( size_t i = 0; i < numDescriptorData; i++ ) { const struct descriptor_reflection_s *refl = __ReflectDescriptorSet( program, &bindings[i].handle ); if( !refl || setIndex != refl->set || RI_IsEmptyDescriptor( &bindings[i].descriptor ) ) continue; - assert( numWrites < Q_ARRAY_COUNT( descriptorWrite ) ); + if( numWrites == Q_ARRAY_COUNT( descriptorWrite ) ) { + vkUpdateDescriptorSets( device->vk.device, numWrites, descriptorWrite, 0, NULL ); + numWrites = 0; + } VkWriteDescriptorSet *vkDesc = descriptorWrite + ( numWrites++ ); memset( vkDesc, 0, sizeof( VkWriteDescriptorSet ) ); vkDesc->sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; @@ -1244,21 +1252,23 @@ void RP_BindDescriptorSets( struct RIDevice_s *device, struct FrameState_s *cmd, vkDesc->pImageInfo = &bindings[i].descriptor.vk.image; break; default: - assert( false ); // this is bad + assert( false ); break; } - - if( numWrites >= Q_ARRAY_COUNT( descriptorWrite ) ) { - vkUpdateDescriptorSets( device->vk.device, numWrites, descriptorWrite, 0, NULL ); - numWrites = 0; - } } + if( numWrites > 0 ) { + vkUpdateDescriptorSets( device->vk.device, numWrites, descriptorWrite, 0, NULL ); + } + } + + if( setsToBindCount == 0 ) { + firstSetToBind = setIndex; } - VkDescriptorSet vkDescriptorSet = result.set->vk.handle; - vkCmdBindDescriptorSets( cmd->handle.vk.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, program->vk.pipelineLayout, setIndex, 1, &vkDescriptorSet, 0, NULL ); + setsToBind[setsToBindCount++] = result.set->vk.handle; } - if( numWrites > 0 ) { - vkUpdateDescriptorSets( device->vk.device, numWrites, descriptorWrite, 0, NULL ); + if( setsToBindCount > 0 ) { + vkCmdBindDescriptorSets( cmd->handle.vk.cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, + program->vk.pipelineLayout, firstSetToBind, setsToBindCount, setsToBind, 0, NULL ); } } #endif