105 split_large_batches(context);
112 sort_batches(context);
117 const auto end_time = std::chrono::high_resolution_clock::now();
118 const auto duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
119 stats_.preparation_time_ms =
static_cast<float>(duration.count()) / 1000.0f;
123template<
typename Key>
126 return prepared_batches_;
129template<
typename Key>
132 batch_groups_.clear();
133 prepared_batches_.clear();
137template<
typename Key>
143template<
typename Key>
146 return batch_groups_.size();
149template<
typename Key>
153 for(
const auto& [key, group] : batch_groups_)
155 total += group.instances.size();
160template<
typename Key>
163 return !batch_groups_.empty();
166template<
typename Key>
169 max_instances_per_batch_ = max_instances;
172template<
typename Key>
178template<
typename Key>
181 if constexpr(std::is_same_v<Key, batch_key>)
183 std::sort(prepared_batches_.begin(),
184 prepared_batches_.end(),
187 if(a->key.material_ptr.get() != b->key.material_ptr.get())
189 return a->key.material_ptr.get() < b->key.material_ptr.get();
191 if(
a->key.mesh_ptr.get() !=
b->key.mesh_ptr.get())
193 return a->key.mesh_ptr.get() < b->key.mesh_ptr.get();
195 if(
a->key.lod_index !=
b->key.lod_index)
197 return a->key.lod_index < b->key.lod_index;
199 if(
a->key.submesh_index !=
b->key.submesh_index)
201 return a->key.submesh_index < b->key.submesh_index;
205 return a->camera_distance > b->camera_distance;
212 std::sort(prepared_batches_.begin(),
213 prepared_batches_.end(),
214 [&context](
const batch_group_t<Key>*
a,
const batch_group_t<Key>*
b) ->
bool
218 return a->key < b->key;
222 return a->camera_distance > b->camera_distance;
229template<
typename Key>
230void batch_collector_t<Key>::split_large_batches(
const submit_context& context)
232 if(context.max_instances_per_batch == 0)
237 batch_list_t new_batches;
238 for(
auto* batch : prepared_batches_)
240 if(batch->instances.size() <= context.max_instances_per_batch)
242 new_batches.push_back(batch);
246 stats_.split_batches++;
247 new_batches.push_back(batch);
249 prepared_batches_ = std::move(new_batches);
252template<
typename Key>
253void batch_collector_t<Key>::calculate_camera_distances(
const math::vec3& camera_pos)
255 for(
auto* batch : prepared_batches_)
257 batch->calculate_camera_distance(camera_pos);
261template<
typename Key>
262void batch_collector_t<Key>::update_statistics()
264 stats_.total_batches =
static_cast<uint32_t
>(prepared_batches_.size());
265 stats_.total_instances =
static_cast<uint32_t
>(get_instance_count());
267 stats_.instance_buffer_memory_used = 0;
268 for(
const auto* batch : prepared_batches_)
270 stats_.instance_buffer_memory_used += batch->get_gpu_memory_size();
272 stats_.calculate_derived_stats();
275template<
typename Key>
276auto batch_collector_t<Key>::get_or_create_batch_group(
const Key& key) -> batch_group_t<Key>&
278 auto it = batch_groups_.find(key);
279 if(it != batch_groups_.end())
283 auto [inserted_it, success] = batch_groups_.emplace(key, batch_group_t<Key>(key));
284 return inserted_it->second;