Fix NonMesh draw command item queries (#17893)
# Objective This fixes `NonMesh` draw commands not receiving render-world entities since - https://github.com/bevyengine/bevy/pull/17698 This unbreaks item queries for queued non-mesh entities: ```rust struct MyDrawCommand { type ItemQuery = Read<DynamicUniformIndex<SomeUniform>>; // ... } ``` ### Solution Pass render entity to `NonMesh` draw commands instead of `Entity::PLACEHOLDER`. This PR also introduces sorting of the `NonMesh` bin keys like other types, which I assume is the intended behavior. @pcwalton ## Testing - Tested on a local project that extensively uses `NonMesh` items.
This commit is contained in:
parent
9214fd649d
commit
8ece2ee07b
@ -187,6 +187,7 @@ where
|
|||||||
phase.multidrawable_meshes.sort_unstable_keys();
|
phase.multidrawable_meshes.sort_unstable_keys();
|
||||||
phase.batchable_meshes.sort_unstable_keys();
|
phase.batchable_meshes.sort_unstable_keys();
|
||||||
phase.unbatchable_meshes.sort_unstable_keys();
|
phase.unbatchable_meshes.sort_unstable_keys();
|
||||||
|
phase.non_mesh_items.sort_unstable_keys();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +129,7 @@ where
|
|||||||
/// entity are simply called in order at rendering time.
|
/// entity are simply called in order at rendering time.
|
||||||
///
|
///
|
||||||
/// See the `custom_phase_item` example for an example of how to use this.
|
/// See the `custom_phase_item` example for an example of how to use this.
|
||||||
pub non_mesh_items: IndexMap<(BPI::BatchSetKey, BPI::BinKey), RenderBin>,
|
pub non_mesh_items: IndexMap<(BPI::BatchSetKey, BPI::BinKey), NonMeshEntities>,
|
||||||
|
|
||||||
/// Information on each batch set.
|
/// Information on each batch set.
|
||||||
///
|
///
|
||||||
@ -322,6 +322,12 @@ pub struct UnbatchableBinnedEntities {
|
|||||||
pub(crate) buffer_indices: UnbatchableBinnedEntityIndexSet,
|
pub(crate) buffer_indices: UnbatchableBinnedEntityIndexSet,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Information about [`BinnedRenderPhaseType::NonMesh`] entities.
|
||||||
|
pub struct NonMeshEntities {
|
||||||
|
/// The entities.
|
||||||
|
pub entities: MainEntityHashMap<Entity>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Stores instance indices and dynamic offsets for unbatchable entities in a
|
/// Stores instance indices and dynamic offsets for unbatchable entities in a
|
||||||
/// binned render phase.
|
/// binned render phase.
|
||||||
///
|
///
|
||||||
@ -381,8 +387,6 @@ pub enum BinnedRenderPhaseType {
|
|||||||
|
|
||||||
/// The item is a mesh that's eligible for indirect rendering, but can't be
|
/// The item is a mesh that's eligible for indirect rendering, but can't be
|
||||||
/// batched with other meshes of the same type.
|
/// batched with other meshes of the same type.
|
||||||
///
|
|
||||||
/// At the moment, this is used for skinned meshes.
|
|
||||||
UnbatchableMesh,
|
UnbatchableMesh,
|
||||||
|
|
||||||
/// The item isn't a mesh at all.
|
/// The item isn't a mesh at all.
|
||||||
@ -526,10 +530,12 @@ where
|
|||||||
.entry((batch_set_key.clone(), bin_key.clone()).clone())
|
.entry((batch_set_key.clone(), bin_key.clone()).clone())
|
||||||
{
|
{
|
||||||
indexmap::map::Entry::Occupied(mut entry) => {
|
indexmap::map::Entry::Occupied(mut entry) => {
|
||||||
entry.get_mut().insert(main_entity, input_uniform_index);
|
entry.get_mut().entities.insert(main_entity, entity);
|
||||||
}
|
}
|
||||||
indexmap::map::Entry::Vacant(entry) => {
|
indexmap::map::Entry::Vacant(entry) => {
|
||||||
entry.insert(RenderBin::from_entity(main_entity, input_uniform_index));
|
let mut entities = MainEntityHashMap::default();
|
||||||
|
entities.insert(main_entity, entity);
|
||||||
|
entry.insert(NonMeshEntities { entities });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -795,14 +801,14 @@ where
|
|||||||
let draw_functions = world.resource::<DrawFunctions<BPI>>();
|
let draw_functions = world.resource::<DrawFunctions<BPI>>();
|
||||||
let mut draw_functions = draw_functions.write();
|
let mut draw_functions = draw_functions.write();
|
||||||
|
|
||||||
for ((batch_set_key, bin_key), bin) in &self.non_mesh_items {
|
for ((batch_set_key, bin_key), non_mesh_entities) in &self.non_mesh_items {
|
||||||
for &entity in bin.entities.keys() {
|
for (main_entity, entity) in non_mesh_entities.entities.iter() {
|
||||||
// Come up with a fake batch range and extra index. The draw
|
// Come up with a fake batch range and extra index. The draw
|
||||||
// function is expected to manage any sort of batching logic itself.
|
// function is expected to manage any sort of batching logic itself.
|
||||||
let binned_phase_item = BPI::new(
|
let binned_phase_item = BPI::new(
|
||||||
batch_set_key.clone(),
|
batch_set_key.clone(),
|
||||||
bin_key.clone(),
|
bin_key.clone(),
|
||||||
(Entity::PLACEHOLDER, entity),
|
(*entity, *main_entity),
|
||||||
0..1,
|
0..1,
|
||||||
PhaseItemExtraIndex::None,
|
PhaseItemExtraIndex::None,
|
||||||
);
|
);
|
||||||
@ -921,7 +927,7 @@ fn remove_entity_from_bin<BPI>(
|
|||||||
multidrawable_meshes: &mut IndexMap<BPI::BatchSetKey, IndexMap<BPI::BinKey, RenderBin>>,
|
multidrawable_meshes: &mut IndexMap<BPI::BatchSetKey, IndexMap<BPI::BinKey, RenderBin>>,
|
||||||
batchable_meshes: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), RenderBin>,
|
batchable_meshes: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), RenderBin>,
|
||||||
unbatchable_meshes: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), UnbatchableBinnedEntities>,
|
unbatchable_meshes: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), UnbatchableBinnedEntities>,
|
||||||
non_mesh_items: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), RenderBin>,
|
non_mesh_items: &mut IndexMap<(BPI::BatchSetKey, BPI::BinKey), NonMeshEntities>,
|
||||||
) where
|
) where
|
||||||
BPI: BinnedPhaseItem,
|
BPI: BinnedPhaseItem,
|
||||||
{
|
{
|
||||||
@ -984,10 +990,10 @@ fn remove_entity_from_bin<BPI>(
|
|||||||
entity_bin_key.batch_set_key.clone(),
|
entity_bin_key.batch_set_key.clone(),
|
||||||
entity_bin_key.bin_key.clone(),
|
entity_bin_key.bin_key.clone(),
|
||||||
)) {
|
)) {
|
||||||
bin_entry.get_mut().remove(entity);
|
bin_entry.get_mut().entities.remove(&entity);
|
||||||
|
|
||||||
// If the bin is now empty, remove the bin.
|
// If the bin is now empty, remove the bin.
|
||||||
if bin_entry.get_mut().is_empty() {
|
if bin_entry.get_mut().entities.is_empty() {
|
||||||
bin_entry.swap_remove();
|
bin_entry.swap_remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user