diff --git a/crates/bevy_core_pipeline/src/core_2d/mod.rs b/crates/bevy_core_pipeline/src/core_2d/mod.rs index 49636f267c8a5..f391a49496a04 100644 --- a/crates/bevy_core_pipeline/src/core_2d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_2d/mod.rs @@ -27,7 +27,7 @@ use bevy_render::{ render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType}, render_phase::{ batch_phase_system, sort_phase_system, BatchedPhaseItem, CachedRenderPipelinePhaseItem, - DrawFunctionId, DrawFunctions, EntityPhaseItem, PhaseItem, RenderPhase, + DrawFunctionId, DrawFunctions, PhaseItem, RenderPhase, }, render_resource::CachedRenderPipelineId, Extract, RenderApp, RenderStage, @@ -115,6 +115,11 @@ pub struct Transparent2d { impl PhaseItem for Transparent2d { type SortKey = FloatOrd; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { self.sort_key @@ -131,13 +136,6 @@ impl PhaseItem for Transparent2d { } } -impl EntityPhaseItem for Transparent2d { - #[inline] - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for Transparent2d { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 8dc51d760ac1c..34a430a345398 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -29,8 +29,8 @@ use bevy_render::{ prelude::Msaa, render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType}, render_phase::{ - sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, - EntityPhaseItem, PhaseItem, RenderPhase, + sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, + RenderPhase, }, render_resource::{ CachedRenderPipelineId, Extent3d, TextureDescriptor, TextureDimension, TextureFormat, @@ -124,6 +124,11 @@ impl PhaseItem for Opaque3d { // NOTE: Values increase towards the camera. Front-to-back ordering for opaque means we need a descending sort. type SortKey = Reverse; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { Reverse(FloatOrd(self.distance)) @@ -141,13 +146,6 @@ impl PhaseItem for Opaque3d { } } -impl EntityPhaseItem for Opaque3d { - #[inline] - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for Opaque3d { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { @@ -166,6 +164,11 @@ impl PhaseItem for AlphaMask3d { // NOTE: Values increase towards the camera. Front-to-back ordering for alpha mask means we need a descending sort. type SortKey = Reverse; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { Reverse(FloatOrd(self.distance)) @@ -183,13 +186,6 @@ impl PhaseItem for AlphaMask3d { } } -impl EntityPhaseItem for AlphaMask3d { - #[inline] - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for AlphaMask3d { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { @@ -208,6 +204,11 @@ impl PhaseItem for Transparent3d { // NOTE: Values increase towards the camera. Back-to-front ordering for transparent means we need an ascending sort. type SortKey = FloatOrd; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { FloatOrd(self.distance) @@ -224,13 +225,6 @@ impl PhaseItem for Transparent3d { } } -impl EntityPhaseItem for Transparent3d { - #[inline] - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for Transparent3d { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index c1d0fc8297325..d10fac03a684e 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -10,12 +10,11 @@ use bevy_core_pipeline::{ }; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - entity::Entity, event::EventReader, prelude::World, schedule::IntoSystemDescriptor, system::{ - lifetimeless::{Read, SQuery, SRes}, + lifetimeless::{Read, SRes}, Commands, Local, Query, Res, ResMut, Resource, SystemParamItem, }, world::FromWorld, @@ -27,8 +26,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, + AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, @@ -296,15 +295,19 @@ type DrawMaterial = ( /// Sets the bind group for a given [`Material`] at the configured `I` index. pub struct SetMaterialBindGroup(PhantomData); -impl EntityRenderCommand for SetMaterialBindGroup { - type Param = (SRes>, SQuery>>); +impl RenderCommand

for SetMaterialBindGroup { + type Param = SRes>; + type ViewWorldQuery = (); + type ItemWorldQuery = Read>; + + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (materials, query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + material_handle: &'_ Handle, + materials: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let material_handle = query.get(item).unwrap(); let material = materials.into_inner().get(material_handle).unwrap(); pass.set_bind_group(I, &material.bind_group, &[]); RenderCommandResult::Success diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 9a821073b0d0d..9cd2bf0bbd83c 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -18,9 +18,8 @@ use bevy_render::{ render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, render_phase::{ - CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityPhaseItem, - EntityRenderCommand, PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, - TrackedRenderPass, + CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, RenderCommand, + RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, renderer::{RenderContext, RenderDevice, RenderQueue}, @@ -1699,6 +1698,11 @@ pub struct Shadow { impl PhaseItem for Shadow { type SortKey = FloatOrd; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { FloatOrd(self.distance) @@ -1715,12 +1719,6 @@ impl PhaseItem for Shadow { } } -impl EntityPhaseItem for Shadow { - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for Shadow { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { @@ -1806,16 +1804,19 @@ pub type DrawShadowMesh = ( ); pub struct SetShadowViewBindGroup; -impl EntityRenderCommand for SetShadowViewBindGroup { - type Param = (SRes, SQuery>); +impl RenderCommand for SetShadowViewBindGroup { + type Param = SRes; + type ViewWorldQuery = Read; + type ItemWorldQuery = (); + #[inline] fn render<'w>( - view: Entity, - _item: Entity, - (light_meta, view_query): SystemParamItem<'w, '_, Self::Param>, + _item: &Shadow, + view_uniform_offset: &'_ ViewUniformOffset, + _entity: (), + light_meta: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let view_uniform_offset = view_query.get(view).unwrap(); pass.set_bind_group( I, light_meta diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index bf3b181913a70..92b65621922ac 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -7,6 +7,7 @@ use bevy_app::Plugin; use bevy_asset::{load_internal_asset, Assets, Handle, HandleUntyped}; use bevy_ecs::{ prelude::*, + query::ROQueryItem, system::{lifetimeless::*, SystemParamItem, SystemState}, }; use bevy_math::{Mat3A, Mat4, Vec2}; @@ -19,7 +20,7 @@ use bevy_render::{ GpuBufferInfo, Mesh, MeshVertexBufferLayout, }, render_asset::RenderAssets, - render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass}, + render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::{ @@ -873,20 +874,23 @@ pub fn queue_mesh_view_bind_groups( } pub struct SetMeshViewBindGroup; -impl EntityRenderCommand for SetMeshViewBindGroup { - type Param = SQuery<( +impl RenderCommand

for SetMeshViewBindGroup { + type Param = (); + type ViewWorldQuery = ( Read, Read, Read, - )>; + ); + type ItemWorldQuery = (); + #[inline] fn render<'w>( - view: Entity, - _item: Entity, - view_query: SystemParamItem<'w, '_, Self::Param>, + _item: &P, + (view_uniform, view_lights, mesh_view_bind_group): ROQueryItem<'w, Self::ViewWorldQuery>, + _entity: (), + _: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let (view_uniform, view_lights, mesh_view_bind_group) = view_query.get_inner(view).unwrap(); pass.set_bind_group( I, &mesh_view_bind_group.value, @@ -898,22 +902,21 @@ impl EntityRenderCommand for SetMeshViewBindGroup { } pub struct SetMeshBindGroup; -impl EntityRenderCommand for SetMeshBindGroup { - type Param = ( - SRes, - SQuery<( - Read>, - Option>, - )>, +impl RenderCommand

for SetMeshBindGroup { + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = ( + Read>, + Option>, ); #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (mesh_bind_group, mesh_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + (mesh_index, skinned_mesh_joints): ROQueryItem<'_, Self::ItemWorldQuery>, + mesh_bind_group: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let (mesh_index, skinned_mesh_joints) = mesh_query.get(item).unwrap(); if let Some(joints) = skinned_mesh_joints { pass.set_bind_group( I, @@ -932,16 +935,18 @@ impl EntityRenderCommand for SetMeshBindGroup { } pub struct DrawMesh; -impl EntityRenderCommand for DrawMesh { - type Param = (SRes>, SQuery>>); +impl RenderCommand

for DrawMesh { + type Param = SRes>; + type ViewWorldQuery = (); + type ItemWorldQuery = Read>; #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (meshes, mesh_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + mesh_handle: ROQueryItem<'_, Self::ItemWorldQuery>, + meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let mesh_handle = mesh_query.get(item).unwrap(); if let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) { pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); match &gpu_mesh.buffer_info { diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 14930b1931ffa..d0a60d529d57c 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -6,6 +6,7 @@ use bevy_app::App; use bevy_ecs::{ all_tuples, entity::Entity, + query::{QueryState, ROQueryItem, ReadOnlyWorldQuery}, system::{ lifetimeless::SRes, ReadOnlySystemParam, Resource, SystemParam, SystemParamItem, SystemState, @@ -21,6 +22,12 @@ use std::{any::TypeId, fmt::Debug, hash::Hash, ops::Range}; /// They are the general form of drawing items, whereas [`RenderCommands`](RenderCommand) /// are more modular. pub trait Draw: Send + Sync + 'static { + /// Prepares the draw function to be used. This is called once and only once before the phase + /// begins. There may be zero or more `draw` calls following a call to this function.. + /// Implementing this is optional. + #[allow(unused_variables)] + fn prepare(&mut self, world: &'_ World) {} + /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn draw<'w>( &mut self, @@ -39,6 +46,8 @@ pub trait Draw: Send + Sync + 'static { pub trait PhaseItem: Sized + Send + Sync + 'static { /// The type used for ordering the items. The smallest values are drawn first. type SortKey: Ord; + fn entity(&self) -> Entity; + /// Determines the order in which the items are drawn during the corresponding [`RenderPhase`](super::RenderPhase). fn sort_key(&self) -> Self::SortKey; /// Specifies the [`Draw`] function used to render the item. @@ -75,6 +84,12 @@ pub struct DrawFunctionsInternal { } impl DrawFunctionsInternal

{ + pub fn prepare(&mut self, world: &World) { + for function in &mut self.draw_functions { + function.prepare(world); + } + } + /// Adds the [`Draw`] function and associates it to its own type. pub fn add>(&mut self, draw_function: T) -> DrawFunctionId { self.add_with::(draw_function) @@ -168,11 +183,14 @@ pub trait RenderCommand { /// Specifies all ECS data required by [`RenderCommand::render`]. /// All parameters have to be read only. type Param: SystemParam + 'static; + type ViewWorldQuery: ReadOnlyWorldQuery; + type ItemWorldQuery: ReadOnlyWorldQuery; /// Renders the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn render<'w>( - view: Entity, item: &P, + view: ROQueryItem<'w, Self::ViewWorldQuery>, + entity: ROQueryItem<'w, Self::ItemWorldQuery>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; @@ -183,20 +201,6 @@ pub enum RenderCommandResult { Failure, } -pub trait EntityRenderCommand { - type Param: SystemParam + 'static; - fn render<'w>( - view: Entity, - item: Entity, - param: SystemParamItem<'w, '_, Self::Param>, - pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult; -} - -pub trait EntityPhaseItem: PhaseItem { - fn entity(&self) -> Entity; -} - pub trait CachedRenderPipelinePhaseItem: PhaseItem { fn cached_pipeline(&self) -> CachedRenderPipelineId; } @@ -208,7 +212,7 @@ pub trait CachedRenderPipelinePhaseItem: PhaseItem { /// /// If this is implemented on a type, the implementation of [`PhaseItem::sort`] should /// be changed to implement a stable sort, or incorrect/suboptimal batching may result. -pub trait BatchedPhaseItem: EntityPhaseItem { +pub trait BatchedPhaseItem: PhaseItem { /// Range in the vertex buffer of this item fn batch_range(&self) -> &Option>; @@ -247,30 +251,16 @@ pub enum BatchResult { IncompatibleItems, } -impl RenderCommand

for E -where - E::Param: 'static, -{ - type Param = E::Param; - - #[inline] - fn render<'w>( - view: Entity, - item: &P, - param: SystemParamItem<'w, '_, Self::Param>, - pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult { - ::render(view, item.entity(), param, pass) - } -} - pub struct SetItemPipeline; impl RenderCommand

for SetItemPipeline { type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = (); #[inline] fn render<'w>( - _view: Entity, item: &P, + _view: (), + _entity: (), pipeline_cache: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { @@ -287,18 +277,21 @@ impl RenderCommand

for SetItemPipeline { } macro_rules! render_command_tuple_impl { - ($($name: ident),*) => { + ($(($name: ident, $view: ident, $entity: ident)),*) => { impl),*> RenderCommand

for ($($name,)*) { type Param = ($($name::Param,)*); + type ViewWorldQuery = ($($name::ViewWorldQuery,)*); + type ItemWorldQuery = ($($name::ItemWorldQuery,)*); #[allow(non_snake_case)] fn render<'w>( - _view: Entity, _item: &P, + ($($view,)*): ROQueryItem<'w, Self::ViewWorldQuery>, + ($($entity,)*): ROQueryItem<'w, Self::ItemWorldQuery>, ($($name,)*): SystemParamItem<'w, '_, Self::Param>, _pass: &mut TrackedRenderPass<'w>, - ) -> RenderCommandResult{ - $(if let RenderCommandResult::Failure = $name::render(_view, _item, $name, _pass) { + ) -> RenderCommandResult { + $(if let RenderCommandResult::Failure = $name::render(_item, $view, $entity, $name, _pass) { return RenderCommandResult::Failure; })* RenderCommandResult::Success @@ -307,18 +300,22 @@ macro_rules! render_command_tuple_impl { }; } -all_tuples!(render_command_tuple_impl, 0, 15, C); +all_tuples!(render_command_tuple_impl, 0, 15, C, V, E); /// Wraps a [`RenderCommand`] into a state so that it can be used as a [`Draw`] function. /// Therefore the [`RenderCommand::Param`] is queried from the ECS and passed to the command. pub struct RenderCommandState> { state: SystemState, + view: QueryState, + entity: QueryState, } impl> RenderCommandState { pub fn new(world: &mut World) -> Self { Self { state: SystemState::new(world), + view: world.query(), + entity: world.query(), } } } @@ -327,6 +324,11 @@ impl + Send + Sync + 'static> Draw

for Rend where C::Param: ReadOnlySystemParam, { + fn prepare(&mut self, world: &'_ World) { + self.view.update_archetypes(world); + self.entity.update_archetypes(world); + } + /// Prepares the ECS parameters for the wrapped [`RenderCommand`] and then renders it. fn draw<'w>( &mut self, @@ -336,7 +338,9 @@ where item: &P, ) { let param = self.state.get(world); - C::render(view, item, param, pass); + let view = self.view.get_manual(world, view).unwrap(); + let entity = self.entity.get_manual(world, item.entity()).unwrap(); + C::render(item, view, entity, param, pass); } } diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 2aa684ece7867..b0b502422b928 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -40,6 +40,7 @@ impl RenderPhase { ) { let draw_functions = world.resource::>(); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); for item in &self.items { let draw_function = draw_functions.get_mut(item.draw_function()).unwrap(); @@ -107,17 +108,16 @@ mod tests { impl PhaseItem for TestPhaseItem { type SortKey = (); + fn entity(&self) -> bevy_ecs::entity::Entity { + self.entity + } + fn sort_key(&self) -> Self::SortKey {} fn draw_function(&self) -> DrawFunctionId { unimplemented!(); } } - impl EntityPhaseItem for TestPhaseItem { - fn entity(&self) -> bevy_ecs::entity::Entity { - self.entity - } - } impl BatchedPhaseItem for TestPhaseItem { fn batch_range(&self) -> &Option> { &self.batch_range diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 0f3b86bf9e1d5..0a2a0b35ee116 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -3,12 +3,12 @@ use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle}; use bevy_core_pipeline::{core_2d::Transparent2d, tonemapping::Tonemapping}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ - entity::Entity, event::EventReader, prelude::{Bundle, World}, + query::ROQueryItem, schedule::IntoSystemDescriptor, system::{ - lifetimeless::{Read, SQuery, SRes}, + lifetimeless::{Read, SRes}, Commands, Local, Query, Res, ResMut, Resource, SystemParamItem, }, world::FromWorld, @@ -21,8 +21,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, + AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, @@ -281,15 +281,21 @@ type DrawMaterial2d = ( ); pub struct SetMaterial2dBindGroup(PhantomData); -impl EntityRenderCommand for SetMaterial2dBindGroup { - type Param = (SRes>, SQuery>>); +impl RenderCommand

+ for SetMaterial2dBindGroup +{ + type Param = SRes>; + type ViewWorldQuery = (); + type ItemWorldQuery = Read>; + + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (materials, query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + material2d_handle: ROQueryItem<'_, Self::ItemWorldQuery>, + materials: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let material2d_handle = query.get(item).unwrap(); let material2d = materials.into_inner().get(material2d_handle).unwrap(); pass.set_bind_group(I, &material2d.bind_group, &[]); RenderCommandResult::Success diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 0910463f26c9f..03e9f468aaa21 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -2,6 +2,7 @@ use bevy_app::Plugin; use bevy_asset::{load_internal_asset, Handle, HandleUntyped}; use bevy_ecs::{ prelude::*, + query::ROQueryItem, system::{lifetimeless::*, SystemParamItem, SystemState}, }; use bevy_math::{Mat4, Vec2}; @@ -11,7 +12,7 @@ use bevy_render::{ globals::{GlobalsBuffer, GlobalsUniform}, mesh::{GpuBufferInfo, Mesh, MeshVertexBufferLayout}, render_asset::RenderAssets, - render_phase::{EntityRenderCommand, RenderCommandResult, TrackedRenderPass}, + render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::{ @@ -495,16 +496,19 @@ pub fn queue_mesh2d_view_bind_groups( } pub struct SetMesh2dViewBindGroup; -impl EntityRenderCommand for SetMesh2dViewBindGroup { - type Param = SQuery<(Read, Read)>; +impl RenderCommand

for SetMesh2dViewBindGroup { + type Param = (); + type ViewWorldQuery = (Read, Read); + type ItemWorldQuery = (); + #[inline] fn render<'w>( - view: Entity, - _item: Entity, - view_query: SystemParamItem<'w, '_, Self::Param>, + _item: &P, + (view_uniform, mesh2d_view_bind_group): ROQueryItem<'w, Self::ViewWorldQuery>, + _view: (), + _param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let (view_uniform, mesh2d_view_bind_group) = view_query.get_inner(view).unwrap(); pass.set_bind_group(I, &mesh2d_view_bind_group.value, &[view_uniform.offset]); RenderCommandResult::Success @@ -512,19 +516,19 @@ impl EntityRenderCommand for SetMesh2dViewBindGroup { } pub struct SetMesh2dBindGroup; -impl EntityRenderCommand for SetMesh2dBindGroup { - type Param = ( - SRes, - SQuery>>, - ); +impl RenderCommand

for SetMesh2dBindGroup { + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = Read>; + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (mesh2d_bind_group, mesh2d_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + mesh2d_index: &'_ DynamicUniformIndex, + mesh2d_bind_group: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let mesh2d_index = mesh2d_query.get(item).unwrap(); pass.set_bind_group( I, &mesh2d_bind_group.into_inner().value, @@ -535,17 +539,20 @@ impl EntityRenderCommand for SetMesh2dBindGroup { } pub struct DrawMesh2d; -impl EntityRenderCommand for DrawMesh2d { - type Param = (SRes>, SQuery>); +impl RenderCommand

for DrawMesh2d { + type Param = SRes>; + type ViewWorldQuery = (); + type ItemWorldQuery = Read; + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (meshes, mesh2d_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + mesh_handle: ROQueryItem<'w, Self::ItemWorldQuery>, + meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let mesh_handle = &mesh2d_query.get(item).unwrap().0; - if let Some(gpu_mesh) = meshes.into_inner().get(mesh_handle) { + if let Some(gpu_mesh) = meshes.into_inner().get(&mesh_handle.0) { pass.set_vertex_buffer(0, gpu_mesh.vertex_buffer.slice(..)); match &gpu_mesh.buffer_info { GpuBufferInfo::Indexed { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 765679b09b425..e7df0c1c323ca 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -16,7 +16,7 @@ use bevy_render::{ color::Color, render_asset::RenderAssets, render_phase::{ - BatchedPhaseItem, DrawFunctions, EntityRenderCommand, RenderCommand, RenderCommandResult, + BatchedPhaseItem, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, @@ -696,16 +696,18 @@ pub type DrawSprite = ( ); pub struct SetSpriteViewBindGroup; -impl EntityRenderCommand for SetSpriteViewBindGroup { - type Param = (SRes, SQuery>); +impl RenderCommand

for SetSpriteViewBindGroup { + type Param = SRes; + type ViewWorldQuery = Read; + type ItemWorldQuery = (); fn render<'w>( - view: Entity, - _item: Entity, - (sprite_meta, view_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + view_uniform: &'_ ViewUniformOffset, + _entity: (), + sprite_meta: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let view_uniform = view_query.get(view).unwrap(); pass.set_bind_group( I, sprite_meta.into_inner().view_bind_group.as_ref().unwrap(), @@ -715,16 +717,18 @@ impl EntityRenderCommand for SetSpriteViewBindGroup { } } pub struct SetSpriteTextureBindGroup; -impl EntityRenderCommand for SetSpriteTextureBindGroup { - type Param = (SRes, SQuery>); +impl RenderCommand

for SetSpriteTextureBindGroup { + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = Read; fn render<'w>( - _view: Entity, - item: Entity, - (image_bind_groups, query_batch): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + sprite_batch: &'_ SpriteBatch, + image_bind_groups: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let sprite_batch = query_batch.get(item).unwrap(); let image_bind_groups = image_bind_groups.into_inner(); pass.set_bind_group( @@ -741,15 +745,17 @@ impl EntityRenderCommand for SetSpriteTextureBindGroup { pub struct DrawSpriteBatch; impl RenderCommand

for DrawSpriteBatch { - type Param = (SRes, SQuery>); + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = Read; fn render<'w>( - _view: Entity, item: &P, - (sprite_meta, query_batch): SystemParamItem<'w, '_, Self::Param>, + _view: (), + sprite_batch: &'_ SpriteBatch, + sprite_meta: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let sprite_batch = query_batch.get(item.entity()).unwrap(); let sprite_meta = sprite_meta.into_inner(); if sprite_batch.colored { pass.set_vertex_buffer(0, sprite_meta.colored_vertices.buffer().unwrap().slice(..)); diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 70406c7240bdc..ee05cf6f8a21b 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -106,6 +106,11 @@ pub struct TransparentUi { impl PhaseItem for TransparentUi { type SortKey = FloatOrd; + #[inline] + fn entity(&self) -> Entity { + self.entity + } + #[inline] fn sort_key(&self) -> Self::SortKey { self.sort_key @@ -117,13 +122,6 @@ impl PhaseItem for TransparentUi { } } -impl EntityPhaseItem for TransparentUi { - #[inline] - fn entity(&self) -> Entity { - self.entity - } -} - impl CachedRenderPipelinePhaseItem for TransparentUi { #[inline] fn cached_pipeline(&self) -> CachedRenderPipelineId { @@ -139,16 +137,18 @@ pub type DrawUi = ( ); pub struct SetUiViewBindGroup; -impl EntityRenderCommand for SetUiViewBindGroup { - type Param = (SRes, SQuery>); +impl RenderCommand

for SetUiViewBindGroup { + type Param = SRes; + type ViewWorldQuery = Read; + type ItemWorldQuery = (); fn render<'w>( - view: Entity, - _item: Entity, - (ui_meta, view_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + view_uniform: &'w ViewUniformOffset, + _entity: (), + ui_meta: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let view_uniform = view_query.get(view).unwrap(); pass.set_bind_group( I, ui_meta.into_inner().view_bind_group.as_ref().unwrap(), @@ -158,34 +158,38 @@ impl EntityRenderCommand for SetUiViewBindGroup { } } pub struct SetUiTextureBindGroup; -impl EntityRenderCommand for SetUiTextureBindGroup { - type Param = (SRes, SQuery>); +impl RenderCommand

for SetUiTextureBindGroup { + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = Read; + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (image_bind_groups, query_batch): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + batch: &'w UiBatch, + image_bind_groups: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let batch = query_batch.get(item).unwrap(); let image_bind_groups = image_bind_groups.into_inner(); - pass.set_bind_group(I, image_bind_groups.values.get(&batch.image).unwrap(), &[]); RenderCommandResult::Success } } pub struct DrawUiNode; -impl EntityRenderCommand for DrawUiNode { - type Param = (SRes, SQuery>); +impl RenderCommand

for DrawUiNode { + type Param = SRes; + type ViewWorldQuery = (); + type ItemWorldQuery = Read; + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (ui_meta, query_batch): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + batch: &'w UiBatch, + ui_meta: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let batch = query_batch.get(item).unwrap(); - pass.set_vertex_buffer(0, ui_meta.into_inner().vertices.buffer().unwrap().slice(..)); pass.draw(batch.range.clone(), 0..1); RenderCommandResult::Success diff --git a/examples/shader/shader_instancing.rs b/examples/shader/shader_instancing.rs index 10fc65ea61c23..7217722253b50 100644 --- a/examples/shader/shader_instancing.rs +++ b/examples/shader/shader_instancing.rs @@ -13,8 +13,8 @@ use bevy::{ mesh::{GpuBufferInfo, MeshVertexBufferLayout}, render_asset::RenderAssets, render_phase::{ - AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, + AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, renderer::RenderDevice, @@ -223,22 +223,19 @@ type DrawCustom = ( pub struct DrawMeshInstanced; -impl EntityRenderCommand for DrawMeshInstanced { - type Param = ( - SRes>, - SQuery>>, - SQuery>, - ); +impl RenderCommand

for DrawMeshInstanced { + type Param = SRes>; + type ViewWorldQuery = (); + type ItemWorldQuery = (Read>, Read); + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (meshes, mesh_query, instance_buffer_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + (mesh_handle, instance_buffer): (&'w Handle, &'w InstanceBuffer), + meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - let mesh_handle = mesh_query.get(item).unwrap(); - let instance_buffer = instance_buffer_query.get_inner(item).unwrap(); - let gpu_mesh = match meshes.into_inner().get(mesh_handle) { Some(gpu_mesh) => gpu_mesh, None => return RenderCommandResult::Failure,