2424
2525namespace impeller {
2626
27- namespace {
28- constexpr char kPaddingType = 0 ;
29- constexpr char kFloatType = 1 ;
30- } // namespace
31-
3227// static
33- BufferView RuntimeEffectContents::EmplaceVulkanUniform (
34- const std::shared_ptr< const std::vector< uint8_t >>& input_data ,
28+ BufferView RuntimeEffectContents::EmplaceUniform (
29+ const uint8_t * source_data ,
3530 HostBuffer& data_host_buffer,
36- const RuntimeUniformDescription& uniform,
37- size_t minimum_uniform_alignment) {
38- // TODO(jonahwilliams): rewrite this to emplace directly into
39- // HostBuffer.
40- std::vector<float > uniform_buffer;
41- uniform_buffer.reserve (uniform.struct_layout .size ());
42- size_t uniform_byte_index = 0u ;
43- for (char byte_type : uniform.struct_layout ) {
44- if (byte_type == kPaddingType ) {
45- uniform_buffer.push_back (0 .f );
46- } else {
47- FML_DCHECK (byte_type == kFloatType );
48- uniform_buffer.push_back (reinterpret_cast <const float *>(
49- input_data->data ())[uniform_byte_index++]);
50- }
31+ const RuntimeUniformDescription& uniform) {
32+ size_t minimum_uniform_alignment =
33+ data_host_buffer.GetMinimumUniformAlignment ();
34+ size_t alignment = std::max (uniform.bit_width / 8 , minimum_uniform_alignment);
35+
36+ if (uniform.padding_layout .empty ()) {
37+ return data_host_buffer.Emplace (source_data, uniform.GetGPUSize (),
38+ alignment);
5139 }
5240
41+ // If the uniform has a padding layout, we need to repack the data.
42+ // We can do this by using the EmplaceProc to write directly to the
43+ // HostBuffer.
5344 return data_host_buffer.Emplace (
54- reinterpret_cast <const void *>(uniform_buffer.data ()),
55- sizeof (float ) * uniform_buffer.size (), minimum_uniform_alignment);
45+ uniform.GetGPUSize (), alignment,
46+ [&uniform, source_data](uint8_t * destination) {
47+ size_t count = uniform.array_elements .value_or (1 );
48+ if (count == 0 ) {
49+ // Make sure to run at least once.
50+ count = 1 ;
51+ }
52+ size_t uniform_byte_index = 0u ;
53+ size_t struct_float_index = 0u ;
54+ auto * float_destination = reinterpret_cast <float *>(destination);
55+ auto * float_source = reinterpret_cast <const float *>(source_data);
56+
57+ for (size_t i = 0 ; i < count; i++) {
58+ for (RuntimePaddingType byte_type : uniform.padding_layout ) {
59+ if (byte_type == RuntimePaddingType::kPadding ) {
60+ float_destination[struct_float_index++] = 0 .f ;
61+ } else {
62+ FML_DCHECK (byte_type == RuntimePaddingType::kFloat );
63+ float_destination[struct_float_index++] =
64+ float_source[uniform_byte_index++];
65+ }
66+ }
67+ }
68+ });
5669}
5770
5871void RuntimeEffectContents::SetRuntimeStage (
@@ -284,12 +297,8 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
284297 << " Uniform " << uniform.name
285298 << " had unexpected type kFloat for Vulkan backend." ;
286299
287- size_t alignment =
288- std::max (uniform.bit_width / 8 ,
289- data_host_buffer.GetMinimumUniformAlignment ());
290- BufferView buffer_view =
291- data_host_buffer.Emplace (uniform_data_->data () + buffer_offset,
292- uniform.GetSize (), alignment);
300+ BufferView buffer_view = EmplaceUniform (
301+ uniform_data_->data () + buffer_offset, data_host_buffer, uniform);
293302
294303 ShaderUniformSlot uniform_slot;
295304 uniform_slot.name = uniform.name .c_str ();
@@ -298,7 +307,7 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
298307 DescriptorType::kUniformBuffer , uniform_slot,
299308 std::move (metadata), std::move (buffer_view));
300309 buffer_index++;
301- buffer_offset += uniform.GetSize ();
310+ buffer_offset += uniform.GetDartSize ();
302311 buffer_location++;
303312 break ;
304313 }
@@ -309,12 +318,10 @@ bool RuntimeEffectContents::Render(const ContentContext& renderer,
309318 uniform_slot.binding = uniform.location ;
310319 uniform_slot.name = uniform.name .c_str ();
311320
312- pass.BindResource (ShaderStage::kFragment ,
313- DescriptorType::kUniformBuffer , uniform_slot,
314- nullptr ,
315- EmplaceVulkanUniform (
316- uniform_data_, data_host_buffer, uniform,
317- data_host_buffer.GetMinimumUniformAlignment ()));
321+ pass.BindResource (
322+ ShaderStage::kFragment , DescriptorType::kUniformBuffer ,
323+ uniform_slot, nullptr ,
324+ EmplaceUniform (uniform_data_->data (), data_host_buffer, uniform));
318325 }
319326 }
320327 }
0 commit comments