@@ -704,36 +704,27 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
704704 VkCommandBuffer cmd =
705705 custom_cmd ? custom_cmd : vk->getCurrentCommandBuffer ();
706706
707- const VkPhysicalDeviceLimits& limit =
708- vk->getPhysicalDeviceProperties ().limits ;
709-
710- size_t sbo_alignment = limit.minStorageBufferOffsetAlignment ;
711- size_t sbo_padding = getPadding (m_skinning_data_padded_size, sbo_alignment);
712- if (sbo_padding != 0 )
713- {
714- m_skinning_data_padded_size += sbo_padding;
715- m_data_uploading.emplace_back ((void *)m_data_padding, sbo_padding);
716- }
717-
718707 // https://github.com/google/filament/pull/3814
719708 // Need both vertex and fragment bit
720709 VkPipelineStageFlags dst_stage = VK_PIPELINE_STAGE_VERTEX_SHADER_BIT |
721710 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
722711
723- size_t ubo_alignment = limit.minUniformBufferOffsetAlignment ;
724- size_t ubo_padding = 0 ;
712+ std::vector<std::pair<void *, size_t > > object_data_uploading;
713+ const VkPhysicalDeviceLimits& limit =
714+ vk->getPhysicalDeviceProperties ().limits ;
715+ size_t sbo_alignment = limit.minStorageBufferOffsetAlignment ;
716+ size_t sbo_padding = 0 ;
725717 const bool use_base_vertex = GEVulkanFeatures::supportsBaseVertexRendering ();
726718 if (use_base_vertex)
727719 {
728720 const size_t object_data_size =
729721 sizeof (ObjectData) * m_visible_objects.size ();
730- m_data_uploading .emplace_back ((void *)m_visible_objects.data (),
722+ object_data_uploading .emplace_back ((void *)m_visible_objects.data (),
731723 object_data_size);
732- ubo_padding = getPadding (
733- m_skinning_data_padded_size + object_data_size, ubo_alignment);
734- if (ubo_padding > 0 )
735- m_data_uploading.emplace_back ((void *)m_data_padding, ubo_padding);
736- m_object_data_padded_size = object_data_size + ubo_padding;
724+ sbo_padding = getPadding (object_data_size, sbo_alignment);
725+ if (sbo_padding > 0 )
726+ object_data_uploading.emplace_back ((void *)m_data_padding, sbo_padding);
727+ m_object_data_padded_size = object_data_size + sbo_padding;
737728 }
738729 else
739730 {
@@ -743,15 +734,14 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
743734 auto & cmd = m_cmds[i];
744735 size_t instance_size =
745736 cmd.m_cmd .instanceCount * sizeof (ObjectData);
746- m_data_uploading .emplace_back (
737+ object_data_uploading .emplace_back (
747738 &m_visible_objects[cmd.m_cmd .firstInstance ], instance_size);
748- size_t cur_padding = getPadding (
749- m_skinning_data_padded_size + m_object_data_padded_size +
739+ size_t cur_padding = getPadding (m_object_data_padded_size +
750740 instance_size, sbo_alignment);
751741 if (cur_padding > 0 )
752742 {
753743 instance_size += cur_padding;
754- m_data_uploading .emplace_back ((void *)m_data_padding,
744+ object_data_uploading .emplace_back ((void *)m_data_padding,
755745 cur_padding);
756746 }
757747 m_sbo_data_offset.push_back (m_object_data_padded_size);
@@ -760,19 +750,40 @@ void GEVulkanDrawCall::uploadDynamicData(GEVulkanDriver* vk,
760750 }
761751 if (!use_base_vertex)
762752 {
763- ubo_padding = getPadding (m_skinning_data_padded_size +
764- m_object_data_padded_size, ubo_alignment);
765- if (ubo_padding > 0 )
753+ sbo_padding = getPadding (m_object_data_padded_size, sbo_alignment);
754+ if (sbo_padding > 0 )
766755 {
767- m_data_uploading .emplace_back ((void *)m_data_padding,
768- ubo_padding );
769- m_object_data_padded_size += ubo_padding ;
756+ object_data_uploading .emplace_back ((void *)m_data_padding,
757+ sbo_padding );
758+ m_object_data_padded_size += sbo_padding ;
770759 }
760+ }
761+
762+ size_t ubo_alignment = limit.minUniformBufferOffsetAlignment ;
763+ size_t ubo_padding = getPadding (m_object_data_padded_size +
764+ m_skinning_data_padded_size, ubo_alignment);
765+ if (ubo_padding != 0 )
766+ {
767+ m_skinning_data_padded_size += ubo_padding;
768+ m_data_uploading.emplace_back ((void *)m_data_padding, ubo_padding);
769+ }
770+
771+ if (!use_base_vertex)
772+ {
771773 // Make sure dynamic offset won't become invaild
772- m_dynamic_data->resizeIfNeeded (m_skinning_data_padded_size +
773- m_object_data_padded_size * 2 + sizeof (GEVulkanCameraUBO));
774+ size_t remain = m_skinning_data_padded_size + sizeof (GEVulkanCameraUBO);
775+ if (m_object_data_padded_size > remain)
776+ {
777+ m_dynamic_data->resizeIfNeeded (m_skinning_data_padded_size +
778+ m_object_data_padded_size + sizeof (GEVulkanCameraUBO) +
779+ (m_object_data_padded_size - remain));
780+ }
774781 }
782+
775783 m_data_uploading.emplace_back (cam->getUBOData (), sizeof (GEVulkanCameraUBO));
784+ object_data_uploading.insert (object_data_uploading.end (),
785+ m_data_uploading.begin (), m_data_uploading.end ());
786+ std::swap (m_data_uploading, object_data_uploading);
776787
777788 const bool use_multidraw = GEVulkanFeatures::supportsMultiDrawIndirect () &&
778789 GEVulkanFeatures::supportsBindMeshTexturesAtOnce ();
@@ -832,7 +843,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
832843
833844 VkDescriptorBufferInfo sbo_info_objects;
834845 sbo_info_objects.buffer = m_dynamic_data->getCurrentBuffer ();
835- sbo_info_objects.offset = m_skinning_data_padded_size ;
846+ sbo_info_objects.offset = 0 ;
836847 sbo_info_objects.range = m_object_data_padded_size;
837848
838849 data_set[1 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
@@ -847,7 +858,7 @@ void GEVulkanDrawCall::render(GEVulkanDriver* vk, GEVulkanCameraSceneNode* cam,
847858
848859 VkDescriptorBufferInfo sbo_info_skinning;
849860 sbo_info_skinning.buffer = m_dynamic_data->getCurrentBuffer ();
850- sbo_info_skinning.offset = 0 ;
861+ sbo_info_skinning.offset = m_object_data_padded_size ;
851862 sbo_info_skinning.range = m_skinning_data_padded_size;
852863
853864 data_set[2 ].sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
0 commit comments