From b411da63fd4f165b53d0f25b7d9ccde854b46307 Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 6 Dec 2022 23:37:55 -0800 Subject: [PATCH 01/20] Flatten EntityPhaseItem into PhaseItem --- crates/bevy_core_pipeline/src/core_2d/mod.rs | 14 ++++---- crates/bevy_core_pipeline/src/core_3d/mod.rs | 38 +++++++++----------- crates/bevy_pbr/src/render/light.rs | 15 ++++---- crates/bevy_render/src/render_phase/draw.rs | 10 +++--- crates/bevy_render/src/render_phase/mod.rs | 9 +++-- crates/bevy_ui/src/render/render_pass.rs | 12 +++---- 6 files changed, 42 insertions(+), 56 deletions(-) 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..023a3d1171dc8 100644 --- a/crates/bevy_core_pipeline/src/core_3d/mod.rs +++ b/crates/bevy_core_pipeline/src/core_3d/mod.rs @@ -30,7 +30,7 @@ use bevy_render::{ render_graph::{EmptyNode, RenderGraph, SlotInfo, SlotType}, render_phase::{ sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, - EntityPhaseItem, PhaseItem, RenderPhase, + 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/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 8b9faeb99854f..92647db02b21a 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -18,8 +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, + CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, + EntityRenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, @@ -1699,6 +1699,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 +1720,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 { diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 1b044197fddca..7922c1abec2a5 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -39,6 +39,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. @@ -193,10 +195,6 @@ pub trait EntityRenderCommand { ) -> RenderCommandResult; } -pub trait EntityPhaseItem: PhaseItem { - fn entity(&self) -> Entity; -} - pub trait CachedRenderPipelinePhaseItem: PhaseItem { fn cached_pipeline(&self) -> CachedRenderPipelineId; } @@ -208,7 +206,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,7 +245,7 @@ pub enum BatchResult { IncompatibleItems, } -impl RenderCommand

for E +impl RenderCommand

for E where E::Param: 'static, { diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 29564481ca454..792772c8a0887 100644 --- a/crates/bevy_render/src/render_phase/mod.rs +++ b/crates/bevy_render/src/render_phase/mod.rs @@ -90,17 +90,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_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 527e96538f1f3..0b7b0b07858f4 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -111,6 +111,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 @@ -122,13 +127,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 { From 702b2c4d498cf6c2dce24e11cdfddb02b0f384c8 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 00:17:25 -0800 Subject: [PATCH 02/20] Add WorldQuery associated types to RenderCommand --- crates/bevy_render/src/render_phase/draw.rs | 9 +++++++++ crates/bevy_sprite/src/render/mod.rs | 2 ++ 2 files changed, 11 insertions(+) diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 7922c1abec2a5..3b4064ed0bb17 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -5,6 +5,7 @@ use crate::{ use bevy_app::App; use bevy_ecs::{ all_tuples, + query::ReadOnlyWorldQuery, entity::Entity, system::{ lifetimeless::SRes, ReadOnlySystemParamFetch, Resource, SystemParam, SystemParamItem, @@ -170,6 +171,8 @@ 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 WorldQuery: ReadOnlyWorldQuery; /// Renders the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn render<'w>( @@ -250,6 +253,8 @@ where E::Param: 'static, { type Param = E::Param; + type ViewWorldQuery = (); + type WorldQuery = (); #[inline] fn render<'w>( @@ -265,6 +270,8 @@ where pub struct SetItemPipeline; impl RenderCommand

for SetItemPipeline { type Param = SRes; + type ViewWorldQuery = (); + type WorldQuery = (); #[inline] fn render<'w>( _view: Entity, @@ -288,6 +295,8 @@ macro_rules! render_command_tuple_impl { ($($name: ident),*) => { impl),*> RenderCommand

for ($($name,)*) { type Param = ($($name::Param,)*); + type ViewWorldQuery = ($($name::ViewWorldQuery,)*); + type WorldQuery = ($($name::WorldQuery,)*); #[allow(non_snake_case)] fn render<'w>( diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 1cdc6d93782d8..78d2154304e2d 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -738,6 +738,8 @@ impl EntityRenderCommand for SetSpriteTextureBindGroup { pub struct DrawSpriteBatch; impl RenderCommand

for DrawSpriteBatch { type Param = (SRes, SQuery>); + type ViewWorldQuery = (); + type WorldQuery = Read; fn render<'w>( _view: Entity, From 2c099b131141c9c46d6f252170c33107fe814507 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 19:31:16 -0800 Subject: [PATCH 03/20] Pass WorldQuery into RenderCommand --- crates/bevy_core_pipeline/src/core_3d/mod.rs | 4 +-- crates/bevy_pbr/src/render/light.rs | 5 ++- crates/bevy_render/src/render_phase/draw.rs | 32 +++++++++++++------- crates/bevy_sprite/src/render/mod.rs | 8 ++--- 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/mod.rs b/crates/bevy_core_pipeline/src/core_3d/mod.rs index 023a3d1171dc8..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, - PhaseItem, RenderPhase, + sort_phase_system, CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, + RenderPhase, }, render_resource::{ CachedRenderPipelineId, Extent3d, TextureDescriptor, TextureDimension, TextureFormat, diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 92647db02b21a..3918bd58539b9 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, PhaseItem, - EntityRenderCommand, RenderCommandResult, RenderPhase, SetItemPipeline, - TrackedRenderPass, + CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityRenderCommand, + PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, renderer::{RenderContext, RenderDevice, RenderQueue}, diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 3b4064ed0bb17..cf5e022e7a1ce 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -5,8 +5,8 @@ use crate::{ use bevy_app::App; use bevy_ecs::{ all_tuples, - query::ReadOnlyWorldQuery, entity::Entity, + query::{QueryState, ROQueryItem, ReadOnlyWorldQuery}, system::{ lifetimeless::SRes, ReadOnlySystemParamFetch, Resource, SystemParam, SystemParamItem, SystemState, @@ -176,8 +176,9 @@ pub trait RenderCommand { /// Renders the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn render<'w>( - view: Entity, item: &P, + view: ROQueryItem<'_, Self::ViewWorldQuery>, + entity: ROQueryItem<'_, Self::WorldQuery>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; @@ -258,12 +259,13 @@ where #[inline] fn render<'w>( - view: Entity, item: &P, + _view: (), + _entity: (), param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - ::render(view, item.entity(), param, pass) + ::render(item.entity(), item.entity(), param, pass) } } @@ -274,8 +276,9 @@ impl RenderCommand

for SetItemPipeline { type WorldQuery = (); #[inline] fn render<'w>( - _view: Entity, item: &P, + _view: (), + _entity: (), pipeline_cache: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { @@ -292,7 +295,7 @@ 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,)*); @@ -300,12 +303,13 @@ macro_rules! render_command_tuple_impl { #[allow(non_snake_case)] fn render<'w>( - _view: Entity, _item: &P, + ($($view,)*): ROQueryItem<'_, Self::ViewWorldQuery>, + ($($entity,)*): ROQueryItem<'_, Self::WorldQuery>, ($($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 @@ -314,18 +318,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(), } } } @@ -343,7 +351,9 @@ where item: &P, ) { let param = self.state.get(world); - C::render(view, item, param, pass); + let Ok(view) = self.view.get(world, view) else { return }; + let Ok(entity) = self.entity.get(world, item.entity()) else { return }; + C::render(item, view, entity, param, pass); } } diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index 78d2154304e2d..526561252b096 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -737,17 +737,17 @@ impl EntityRenderCommand for SetSpriteTextureBindGroup { pub struct DrawSpriteBatch; impl RenderCommand

for DrawSpriteBatch { - type Param = (SRes, SQuery>); + type Param = SRes; type ViewWorldQuery = (); type WorldQuery = 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(..)); From 8e4f9ffd8cd561b7ddf4dadb81e25fe58566cdff Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 20:10:46 -0800 Subject: [PATCH 04/20] Flatten EntityRenderCommand out --- crates/bevy_pbr/src/material.rs | 20 +++++--- crates/bevy_pbr/src/render/light.rs | 17 ++++--- crates/bevy_pbr/src/render/mesh.rs | 55 +++++++++++---------- crates/bevy_render/src/render_phase/draw.rs | 30 ----------- crates/bevy_sprite/src/mesh2d/material.rs | 21 +++++--- crates/bevy_sprite/src/mesh2d/mesh.rs | 53 +++++++++++--------- crates/bevy_sprite/src/render/mod.rs | 32 ++++++------ 7 files changed, 113 insertions(+), 115 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index c1d0fc8297325..af42fd4c63552 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -27,8 +27,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, + AddRenderCommand, DrawFunctions, RenderCommandResult, RenderPhase, + SetItemPipeline, TrackedRenderPass, RenderCommand, PhaseItem, }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, @@ -296,15 +296,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 WorldQuery = 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 3918bd58539b9..8bcaac1dcb441 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -18,7 +18,7 @@ use bevy_render::{ render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, render_phase::{ - CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, EntityRenderCommand, + CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, RenderCommand, PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, @@ -1808,16 +1808,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 WorldQuery = (); + #[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 15fa70b81e8df..02966d86359ca 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::{RenderCommand, RenderCommandResult, TrackedRenderPass, PhaseItem}, render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::{ @@ -883,20 +884,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 WorldQuery = (); + #[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<'_, 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, @@ -908,22 +912,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 WorldQuery = ( + 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::WorldQuery>, + 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, @@ -942,16 +945,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 WorldQuery = Read>; #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (meshes, mesh_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + mesh_handle: ROQueryItem<'_, Self::WorldQuery>, + 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 cf5e022e7a1ce..5f82f0780bd9d 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -189,16 +189,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 CachedRenderPipelinePhaseItem: PhaseItem { fn cached_pipeline(&self) -> CachedRenderPipelineId; } @@ -249,26 +239,6 @@ pub enum BatchResult { IncompatibleItems, } -impl RenderCommand

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

for SetItemPipeline { type Param = SRes; diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 0f3b86bf9e1d5..abf9957d0ebe8 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -5,6 +5,7 @@ use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ entity::Entity, event::EventReader, + query::ROQueryItem, prelude::{Bundle, World}, schedule::IntoSystemDescriptor, system::{ @@ -21,8 +22,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, EntityRenderCommand, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, + AddRenderCommand, DrawFunctions, RenderCommandResult, RenderPhase, + SetItemPipeline, TrackedRenderPass, PhaseItem, RenderCommand }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, @@ -281,15 +282,19 @@ type DrawMaterial2d = ( ); pub struct SetMaterial2dBindGroup(PhantomData); -impl EntityRenderCommand for SetMaterial2dBindGroup { - type Param = (SRes>, SQuery>>); +impl RenderCommand

for SetMaterial2dBindGroup { + type Param = SRes>; + type ViewWorldQuery = (); + type WorldQuery = Read>; + + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (materials, query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + material2d_handle: ROQueryItem<'_, Self::WorldQuery>, + 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..d211bc1c0f765 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::{RenderCommandResult, TrackedRenderPass, RenderCommand, PhaseItem}, 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 WorldQuery = (); + #[inline] fn render<'w>( - view: Entity, - _item: Entity, - view_query: SystemParamItem<'w, '_, Self::Param>, + _item: &P, + (view_uniform, mesh2d_view_bind_group): ROQueryItem<'_, 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 WorldQuery = 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 WorldQuery = Read; + #[inline] fn render<'w>( - _view: Entity, - item: Entity, - (meshes, mesh2d_query): SystemParamItem<'w, '_, Self::Param>, + _item: &P, + _view: (), + mesh_handle: ROQueryItem<'_, Self::WorldQuery>, + 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 526561252b096..c2b3c3bcb59d7 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -16,8 +16,8 @@ use bevy_render::{ color::Color, render_asset::RenderAssets, render_phase::{ - BatchedPhaseItem, DrawFunctions, EntityRenderCommand, RenderCommand, RenderCommandResult, - RenderPhase, SetItemPipeline, TrackedRenderPass, + BatchedPhaseItem, DrawFunctions, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, PhaseItem, }, render_resource::*, renderer::{RenderDevice, RenderQueue}, @@ -692,16 +692,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 WorldQuery = (); 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(), @@ -711,16 +713,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 WorldQuery = 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( From 45f227a1a9e8cbe01d731ba0c7f1382435097dce Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 20:40:18 -0800 Subject: [PATCH 05/20] Cleanup --- crates/bevy_pbr/src/material.rs | 3 +- crates/bevy_pbr/src/render/mesh.rs | 2 +- crates/bevy_render/src/render_phase/draw.rs | 8 ++-- crates/bevy_sprite/src/mesh2d/material.rs | 3 +- crates/bevy_sprite/src/mesh2d/mesh.rs | 4 +- crates/bevy_ui/src/render/render_pass.rs | 46 ++++++++++++--------- 6 files changed, 35 insertions(+), 31 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index af42fd4c63552..3cc225f356aeb 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, diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 02966d86359ca..f72c0f27beb57 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -896,7 +896,7 @@ impl RenderCommand

for SetMeshViewBindGroup #[inline] fn render<'w>( _item: &P, - (view_uniform, view_lights, mesh_view_bind_group): ROQueryItem<'_, Self::ViewWorldQuery>, + (view_uniform, view_lights, mesh_view_bind_group): ROQueryItem<'w, Self::ViewWorldQuery>, _entity: (), _: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 5f82f0780bd9d..27a5e73c057d7 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -177,8 +177,8 @@ pub trait RenderCommand { /// Renders the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn render<'w>( item: &P, - view: ROQueryItem<'_, Self::ViewWorldQuery>, - entity: ROQueryItem<'_, Self::WorldQuery>, + view: ROQueryItem<'w, Self::ViewWorldQuery>, + entity: ROQueryItem<'w, Self::WorldQuery>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; @@ -274,8 +274,8 @@ macro_rules! render_command_tuple_impl { #[allow(non_snake_case)] fn render<'w>( _item: &P, - ($($view,)*): ROQueryItem<'_, Self::ViewWorldQuery>, - ($($entity,)*): ROQueryItem<'_, Self::WorldQuery>, + ($($view,)*): ROQueryItem<'w, Self::ViewWorldQuery>, + ($($entity,)*): ROQueryItem<'w, Self::WorldQuery>, ($($name,)*): SystemParamItem<'w, '_, Self::Param>, _pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index abf9957d0ebe8..b37a8cadc946d 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -3,13 +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, query::ROQueryItem, prelude::{Bundle, World}, schedule::IntoSystemDescriptor, system::{ - lifetimeless::{Read, SQuery, SRes}, + lifetimeless::{Read, SRes}, Commands, Local, Query, Res, ResMut, Resource, SystemParamItem, }, world::FromWorld, diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index d211bc1c0f765..34ef2936502b4 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -504,7 +504,7 @@ impl RenderCommand

for SetMesh2dViewBindGroup( _item: &P, - (view_uniform, mesh2d_view_bind_group): ROQueryItem<'_, Self::ViewWorldQuery>, + (view_uniform, mesh2d_view_bind_group): ROQueryItem<'w, Self::ViewWorldQuery>, _view: (), _param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, @@ -548,7 +548,7 @@ impl RenderCommand

for DrawMesh2d { fn render<'w>( _item: &P, _view: (), - mesh_handle: ROQueryItem<'_, Self::WorldQuery>, + mesh_handle: ROQueryItem<'w, Self::WorldQuery>, meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 0b7b0b07858f4..9da8dc6fcba67 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -142,16 +142,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 WorldQuery = (); 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(), @@ -161,34 +163,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 WorldQuery = 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 WorldQuery = 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 From 03d6ca3dc834b09eaeaabf747755b67758cfe7b8 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 20:48:17 -0800 Subject: [PATCH 06/20] Fix CI --- crates/bevy_pbr/src/material.rs | 4 ++-- crates/bevy_pbr/src/render/light.rs | 4 ++-- crates/bevy_pbr/src/render/mesh.rs | 2 +- crates/bevy_sprite/src/mesh2d/material.rs | 12 ++++++----- crates/bevy_sprite/src/mesh2d/mesh.rs | 2 +- crates/bevy_sprite/src/render/mod.rs | 4 ++-- examples/shader/shader_instancing.rs | 25 ++++++++++------------- 7 files changed, 26 insertions(+), 27 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 3cc225f356aeb..8ecd8ce5dd767 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -26,8 +26,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, RenderCommand, PhaseItem, + AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 8bcaac1dcb441..60515919bb82e 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -18,8 +18,8 @@ use bevy_render::{ render_asset::RenderAssets, render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, render_phase::{ - CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, RenderCommand, - PhaseItem, RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, + CachedRenderPipelinePhaseItem, DrawFunctionId, DrawFunctions, PhaseItem, RenderCommand, + RenderCommandResult, RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, renderer::{RenderContext, RenderDevice, RenderQueue}, diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index f72c0f27beb57..dc379dfe4619e 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -20,7 +20,7 @@ use bevy_render::{ GpuBufferInfo, Mesh, MeshVertexBufferLayout, }, render_asset::RenderAssets, - render_phase::{RenderCommand, RenderCommandResult, TrackedRenderPass, PhaseItem}, + render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::{ diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index b37a8cadc946d..2dcf85a71d18c 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -4,8 +4,8 @@ use bevy_core_pipeline::{core_2d::Transparent2d, tonemapping::Tonemapping}; use bevy_derive::{Deref, DerefMut}; use bevy_ecs::{ event::EventReader, - query::ROQueryItem, prelude::{Bundle, World}, + query::ROQueryItem, schedule::IntoSystemDescriptor, system::{ lifetimeless::{Read, SRes}, @@ -21,8 +21,8 @@ use bevy_render::{ prelude::Image, render_asset::{PrepareAssetLabel, RenderAssets}, render_phase::{ - AddRenderCommand, DrawFunctions, RenderCommandResult, RenderPhase, - SetItemPipeline, TrackedRenderPass, PhaseItem, RenderCommand + AddRenderCommand, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::{ AsBindGroup, AsBindGroupError, BindGroup, BindGroupLayout, OwnedBindingResource, @@ -281,11 +281,13 @@ type DrawMaterial2d = ( ); pub struct SetMaterial2dBindGroup(PhantomData); -impl RenderCommand

for SetMaterial2dBindGroup { +impl RenderCommand

+ for SetMaterial2dBindGroup +{ type Param = SRes>; type ViewWorldQuery = (); type WorldQuery = Read>; - + #[inline] fn render<'w>( _item: &P, diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 34ef2936502b4..5aea75fba65f6 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -12,7 +12,7 @@ use bevy_render::{ globals::{GlobalsBuffer, GlobalsUniform}, mesh::{GpuBufferInfo, Mesh, MeshVertexBufferLayout}, render_asset::RenderAssets, - render_phase::{RenderCommandResult, TrackedRenderPass, RenderCommand, PhaseItem}, + render_phase::{PhaseItem, RenderCommand, RenderCommandResult, TrackedRenderPass}, render_resource::*, renderer::{RenderDevice, RenderQueue}, texture::{ diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index c2b3c3bcb59d7..5e36a0b2c1dea 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -16,8 +16,8 @@ use bevy_render::{ color::Color, render_asset::RenderAssets, render_phase::{ - BatchedPhaseItem, DrawFunctions, RenderCommand, RenderCommandResult, - RenderPhase, SetItemPipeline, TrackedRenderPass, PhaseItem, + BatchedPhaseItem, DrawFunctions, PhaseItem, RenderCommand, RenderCommandResult, + RenderPhase, SetItemPipeline, TrackedRenderPass, }, render_resource::*, renderer::{RenderDevice, RenderQueue}, diff --git a/examples/shader/shader_instancing.rs b/examples/shader/shader_instancing.rs index 5d8c8b816f473..561fbed059bca 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 WorldQuery = (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, From 22fd3c7c5baf0782361c307bd9acbb4572f34db0 Mon Sep 17 00:00:00 2001 From: james7132 Date: Wed, 7 Dec 2022 22:54:57 -0800 Subject: [PATCH 07/20] Use QueryState::get_manual over get --- Cargo.toml | 3 +++ .../src/core_2d/main_pass_2d_node.rs | 1 + .../src/core_3d/main_pass_3d_node.rs | 3 +++ crates/bevy_pbr/src/render/light.rs | 1 + crates/bevy_render/src/render_phase/draw.rs | 22 +++++++++++++++++-- crates/bevy_ui/src/render/render_pass.rs | 1 + 6 files changed, 29 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index c6ec1f14d6bd0..624bc577600e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1613,3 +1613,6 @@ inherits = "release" opt-level = "z" lto = "fat" codegen-units = 1 + +[profile.release] +lto = "fat" \ No newline at end of file diff --git a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs index f4006822f3436..d8057b1d00d4f 100644 --- a/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs +++ b/crates/bevy_core_pipeline/src/core_2d/main_pass_2d_node.rs @@ -84,6 +84,7 @@ impl Node for MainPass2dNode { .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); if let Some(viewport) = camera.viewport.as_ref() { tracked_pass.set_camera_viewport(viewport); diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index cf3a3d38fa603..a1f17dedf0f06 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -101,6 +101,7 @@ impl Node for MainPass3dNode { .command_encoder .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); if let Some(viewport) = camera.viewport.as_ref() { tracked_pass.set_camera_viewport(viewport); @@ -140,6 +141,7 @@ impl Node for MainPass3dNode { .command_encoder .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); if let Some(viewport) = camera.viewport.as_ref() { tracked_pass.set_camera_viewport(viewport); @@ -184,6 +186,7 @@ impl Node for MainPass3dNode { .command_encoder .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); if let Some(viewport) = camera.viewport.as_ref() { tracked_pass.set_camera_viewport(viewport); diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index 60515919bb82e..3e5d5510f5e4e 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1788,6 +1788,7 @@ impl Node for ShadowPassNode { .command_encoder .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); for item in &shadow_phase.items { let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 27a5e73c057d7..af3ab8603a8a8 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -22,6 +22,10 @@ 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 { + /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. + #[allow(unused_variables)] + fn prepare<'w>(&mut self, world: &'w World) {} + /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn draw<'w>( &mut self, @@ -78,6 +82,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) @@ -312,6 +322,14 @@ impl + Send + Sync + 'static> Draw

for Rend where ::Fetch: ReadOnlySystemParamFetch, { + fn prepare<'w>( + &mut self, + world: &'w 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, @@ -321,8 +339,8 @@ where item: &P, ) { let param = self.state.get(world); - let Ok(view) = self.view.get(world, view) else { return }; - let Ok(entity) = self.entity.get(world, item.entity()) else { return }; + let Ok(view) = self.view.get_manual(world, view) else { return }; + let Ok(entity) = self.entity.get_manual(world, item.entity()) else { return }; C::render(item, view, entity, param, pass); } } diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 9da8dc6fcba67..8a4260dd8c2b5 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -92,6 +92,7 @@ impl Node for UiPassNode { .begin_render_pass(&pass_descriptor); let mut draw_functions = draw_functions.write(); + draw_functions.prepare(world); let mut tracked_pass = TrackedRenderPass::new(render_pass); for item in &transparent_phase.items { let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); From 4a5638f8f534344b261b798d62ae21bdcefd8476 Mon Sep 17 00:00:00 2001 From: james7132 Date: Thu, 8 Dec 2022 01:16:33 -0800 Subject: [PATCH 08/20] Unwrap instead of return --- crates/bevy_render/src/render_phase/draw.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index af3ab8603a8a8..4a9f274741b03 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -339,8 +339,8 @@ where item: &P, ) { let param = self.state.get(world); - let Ok(view) = self.view.get_manual(world, view) else { return }; - let Ok(entity) = self.entity.get_manual(world, item.entity()) else { return }; + 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); } } From 5efcff35b7bf70f2d3fe2dbdd50c1e75d6c572ba Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 12 Dec 2022 00:04:20 -0800 Subject: [PATCH 09/20] Formatting --- crates/bevy_render/src/render_phase/draw.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 11b875db91a79..edd614da4d062 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -322,10 +322,7 @@ impl + Send + Sync + 'static> Draw

for Rend where C::Param: ReadOnlySystemParam, { - fn prepare<'w>( - &mut self, - world: &'w World, - ) { + fn prepare<'w>(&mut self, world: &'w World) { self.view.update_archetypes(world); self.entity.update_archetypes(world); } From 175670906e93353867cff3215856aafc6f605112 Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 13 Dec 2022 19:11:35 -0800 Subject: [PATCH 10/20] Remove spurious files --- Cargo.toml | 3 --- crates/bevy_render/src/render_phase/draw.rs | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3382f75c110ea..aa2eb4571a7fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1608,6 +1608,3 @@ inherits = "release" opt-level = "z" lto = "fat" codegen-units = 1 - -[profile.release] -lto = "fat" \ No newline at end of file diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index edd614da4d062..2006914d666bb 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -289,7 +289,7 @@ macro_rules! render_command_tuple_impl { ($($name,)*): SystemParamItem<'w, '_, Self::Param>, _pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - $(if let RenderCommandResult::Failure = $name::render(_item, $view, $entity, $name, _pass) { + $(if $name::render(_item, $view, $entity, $name, _pass) == RenderCommandResult::Failure { return RenderCommandResult::Failure; })* RenderCommandResult::Success From aa146b3bb1c3c873e9ef1b096dd956df837f5688 Mon Sep 17 00:00:00 2001 From: james7132 Date: Tue, 13 Dec 2022 19:20:07 -0800 Subject: [PATCH 11/20] Fix CI --- crates/bevy_render/src/render_phase/draw.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 2006914d666bb..dda9e46883d62 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -24,7 +24,7 @@ use std::{any::TypeId, fmt::Debug, hash::Hash, ops::Range}; pub trait Draw: Send + Sync + 'static { /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. #[allow(unused_variables)] - fn prepare<'w>(&mut self, world: &'w World) {} + fn prepare(&mut self, world: &'_ World) {} /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn draw<'w>( @@ -289,7 +289,7 @@ macro_rules! render_command_tuple_impl { ($($name,)*): SystemParamItem<'w, '_, Self::Param>, _pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { - $(if $name::render(_item, $view, $entity, $name, _pass) == RenderCommandResult::Failure { + $(if let RenderCommandResult::Failure = $name::render(_item, $view, $entity, $name, _pass) { return RenderCommandResult::Failure; })* RenderCommandResult::Success @@ -322,7 +322,7 @@ impl + Send + Sync + 'static> Draw

for Rend where C::Param: ReadOnlySystemParam, { - fn prepare<'w>(&mut self, world: &'w World) { + fn prepare(&mut self, world: &'_ World) { self.view.update_archetypes(world); self.entity.update_archetypes(world); } From 4d4d9b4a7ce4da49a388edb1b5a9f4b95e724319 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Dec 2022 14:51:52 -0800 Subject: [PATCH 12/20] Update Draw::prepare documentation --- crates/bevy_render/src/render_phase/draw.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index 9b6cd4bbff699..e1d3a51c560bc 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -22,7 +22,9 @@ 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 { - /// Draws the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. + /// 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) {} From c09c35842d8fab2f4ae357cab671e5fbf3ddd98d Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Dec 2022 14:58:12 -0800 Subject: [PATCH 13/20] WorldQuery -> ItemWorldQUery --- crates/bevy_pbr/src/material.rs | 2 +- crates/bevy_pbr/src/render/light.rs | 2 +- crates/bevy_pbr/src/render/mesh.rs | 10 +++++----- crates/bevy_render/src/render_phase/draw.rs | 14 +++++++------- crates/bevy_sprite/src/mesh2d/material.rs | 4 ++-- crates/bevy_sprite/src/mesh2d/mesh.rs | 8 ++++---- crates/bevy_sprite/src/render/mod.rs | 6 +++--- crates/bevy_ui/src/render/render_pass.rs | 6 +++--- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/crates/bevy_pbr/src/material.rs b/crates/bevy_pbr/src/material.rs index 8ecd8ce5dd767..d10fac03a684e 100644 --- a/crates/bevy_pbr/src/material.rs +++ b/crates/bevy_pbr/src/material.rs @@ -298,7 +298,7 @@ pub struct SetMaterialBindGroup(PhantomData); impl RenderCommand

for SetMaterialBindGroup { type Param = SRes>; type ViewWorldQuery = (); - type WorldQuery = Read>; + type ItemWorldQuery = Read>; #[inline] fn render<'w>( diff --git a/crates/bevy_pbr/src/render/light.rs b/crates/bevy_pbr/src/render/light.rs index ec429a23b5389..26ee773402ff1 100644 --- a/crates/bevy_pbr/src/render/light.rs +++ b/crates/bevy_pbr/src/render/light.rs @@ -1812,7 +1812,7 @@ pub struct SetShadowViewBindGroup; impl RenderCommand for SetShadowViewBindGroup { type Param = SRes; type ViewWorldQuery = Read; - type WorldQuery = (); + type ItemWorldQuery = (); #[inline] fn render<'w>( diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 0d07027a07745..92b65621922ac 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -881,7 +881,7 @@ impl RenderCommand

for SetMeshViewBindGroup Read, Read, ); - type WorldQuery = (); + type ItemWorldQuery = (); #[inline] fn render<'w>( @@ -905,7 +905,7 @@ pub struct SetMeshBindGroup; impl RenderCommand

for SetMeshBindGroup { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = ( + type ItemWorldQuery = ( Read>, Option>, ); @@ -913,7 +913,7 @@ impl RenderCommand

for SetMeshBindGroup { fn render<'w>( _item: &P, _view: (), - (mesh_index, skinned_mesh_joints): ROQueryItem<'_, Self::WorldQuery>, + (mesh_index, skinned_mesh_joints): ROQueryItem<'_, Self::ItemWorldQuery>, mesh_bind_group: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { @@ -938,12 +938,12 @@ pub struct DrawMesh; impl RenderCommand

for DrawMesh { type Param = SRes>; type ViewWorldQuery = (); - type WorldQuery = Read>; + type ItemWorldQuery = Read>; #[inline] fn render<'w>( _item: &P, _view: (), - mesh_handle: ROQueryItem<'_, Self::WorldQuery>, + mesh_handle: ROQueryItem<'_, Self::ItemWorldQuery>, meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index e1d3a51c560bc..d0a60d529d57c 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -23,7 +23,7 @@ use std::{any::TypeId, fmt::Debug, hash::Hash, ops::Range}; /// 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.. + /// 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) {} @@ -184,13 +184,13 @@ pub trait RenderCommand { /// All parameters have to be read only. type Param: SystemParam + 'static; type ViewWorldQuery: ReadOnlyWorldQuery; - type WorldQuery: ReadOnlyWorldQuery; + type ItemWorldQuery: ReadOnlyWorldQuery; /// Renders the [`PhaseItem`] by issuing draw calls via the [`TrackedRenderPass`]. fn render<'w>( item: &P, view: ROQueryItem<'w, Self::ViewWorldQuery>, - entity: ROQueryItem<'w, Self::WorldQuery>, + entity: ROQueryItem<'w, Self::ItemWorldQuery>, param: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult; @@ -255,7 +255,7 @@ pub struct SetItemPipeline; impl RenderCommand

for SetItemPipeline { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = (); + type ItemWorldQuery = (); #[inline] fn render<'w>( item: &P, @@ -281,13 +281,13 @@ macro_rules! render_command_tuple_impl { impl),*> RenderCommand

for ($($name,)*) { type Param = ($($name::Param,)*); type ViewWorldQuery = ($($name::ViewWorldQuery,)*); - type WorldQuery = ($($name::WorldQuery,)*); + type ItemWorldQuery = ($($name::ItemWorldQuery,)*); #[allow(non_snake_case)] fn render<'w>( _item: &P, ($($view,)*): ROQueryItem<'w, Self::ViewWorldQuery>, - ($($entity,)*): ROQueryItem<'w, Self::WorldQuery>, + ($($entity,)*): ROQueryItem<'w, Self::ItemWorldQuery>, ($($name,)*): SystemParamItem<'w, '_, Self::Param>, _pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { @@ -307,7 +307,7 @@ all_tuples!(render_command_tuple_impl, 0, 15, C, V, E); pub struct RenderCommandState> { state: SystemState, view: QueryState, - entity: QueryState, + entity: QueryState, } impl> RenderCommandState { diff --git a/crates/bevy_sprite/src/mesh2d/material.rs b/crates/bevy_sprite/src/mesh2d/material.rs index 2dcf85a71d18c..0a2a0b35ee116 100644 --- a/crates/bevy_sprite/src/mesh2d/material.rs +++ b/crates/bevy_sprite/src/mesh2d/material.rs @@ -286,13 +286,13 @@ impl RenderCommand

{ type Param = SRes>; type ViewWorldQuery = (); - type WorldQuery = Read>; + type ItemWorldQuery = Read>; #[inline] fn render<'w>( _item: &P, _view: (), - material2d_handle: ROQueryItem<'_, Self::WorldQuery>, + material2d_handle: ROQueryItem<'_, Self::ItemWorldQuery>, materials: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { diff --git a/crates/bevy_sprite/src/mesh2d/mesh.rs b/crates/bevy_sprite/src/mesh2d/mesh.rs index 5aea75fba65f6..03e9f468aaa21 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh.rs +++ b/crates/bevy_sprite/src/mesh2d/mesh.rs @@ -499,7 +499,7 @@ pub struct SetMesh2dViewBindGroup; impl RenderCommand

for SetMesh2dViewBindGroup { type Param = (); type ViewWorldQuery = (Read, Read); - type WorldQuery = (); + type ItemWorldQuery = (); #[inline] fn render<'w>( @@ -519,7 +519,7 @@ pub struct SetMesh2dBindGroup; impl RenderCommand

for SetMesh2dBindGroup { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = Read>; + type ItemWorldQuery = Read>; #[inline] fn render<'w>( @@ -542,13 +542,13 @@ pub struct DrawMesh2d; impl RenderCommand

for DrawMesh2d { type Param = SRes>; type ViewWorldQuery = (); - type WorldQuery = Read; + type ItemWorldQuery = Read; #[inline] fn render<'w>( _item: &P, _view: (), - mesh_handle: ROQueryItem<'w, Self::WorldQuery>, + mesh_handle: ROQueryItem<'w, Self::ItemWorldQuery>, meshes: SystemParamItem<'w, '_, Self::Param>, pass: &mut TrackedRenderPass<'w>, ) -> RenderCommandResult { diff --git a/crates/bevy_sprite/src/render/mod.rs b/crates/bevy_sprite/src/render/mod.rs index eb0c91b8302e7..e7df0c1c323ca 100644 --- a/crates/bevy_sprite/src/render/mod.rs +++ b/crates/bevy_sprite/src/render/mod.rs @@ -699,7 +699,7 @@ pub struct SetSpriteViewBindGroup; impl RenderCommand

for SetSpriteViewBindGroup { type Param = SRes; type ViewWorldQuery = Read; - type WorldQuery = (); + type ItemWorldQuery = (); fn render<'w>( _item: &P, @@ -720,7 +720,7 @@ pub struct SetSpriteTextureBindGroup; impl RenderCommand

for SetSpriteTextureBindGroup { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = Read; + type ItemWorldQuery = Read; fn render<'w>( _item: &P, @@ -747,7 +747,7 @@ pub struct DrawSpriteBatch; impl RenderCommand

for DrawSpriteBatch { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = Read; + type ItemWorldQuery = Read; fn render<'w>( item: &P, diff --git a/crates/bevy_ui/src/render/render_pass.rs b/crates/bevy_ui/src/render/render_pass.rs index 8a4260dd8c2b5..026fc7804ced8 100644 --- a/crates/bevy_ui/src/render/render_pass.rs +++ b/crates/bevy_ui/src/render/render_pass.rs @@ -146,7 +146,7 @@ pub struct SetUiViewBindGroup; impl RenderCommand

for SetUiViewBindGroup { type Param = SRes; type ViewWorldQuery = Read; - type WorldQuery = (); + type ItemWorldQuery = (); fn render<'w>( _item: &P, @@ -167,7 +167,7 @@ pub struct SetUiTextureBindGroup; impl RenderCommand

for SetUiTextureBindGroup { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = Read; + type ItemWorldQuery = Read; #[inline] fn render<'w>( @@ -186,7 +186,7 @@ pub struct DrawUiNode; impl RenderCommand

for DrawUiNode { type Param = SRes; type ViewWorldQuery = (); - type WorldQuery = Read; + type ItemWorldQuery = Read; #[inline] fn render<'w>( From f63f670bf30b05638c3c8d88e14a883b4e64d855 Mon Sep 17 00:00:00 2001 From: james7132 Date: Sun, 25 Dec 2022 17:47:26 -0800 Subject: [PATCH 14/20] Fix CI --- examples/shader/shader_instancing.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/shader/shader_instancing.rs b/examples/shader/shader_instancing.rs index ce441f33900f7..7217722253b50 100644 --- a/examples/shader/shader_instancing.rs +++ b/examples/shader/shader_instancing.rs @@ -226,7 +226,7 @@ pub struct DrawMeshInstanced; impl RenderCommand

for DrawMeshInstanced { type Param = SRes>; type ViewWorldQuery = (); - type WorldQuery = (Read>, Read); + type ItemWorldQuery = (Read>, Read); #[inline] fn render<'w>( From 0a84aaa2efb5f6481e456d49474dd392801c8a8d Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 2 Jan 2023 19:27:46 -0800 Subject: [PATCH 15/20] Fix CI --- .../src/core_3d/main_pass_3d_node.rs | 12 ------------ crates/bevy_render/src/render_phase/mod.rs | 1 + 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs index 6eee586f48f50..1067643e03b12 100644 --- a/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs +++ b/crates/bevy_core_pipeline/src/core_3d/main_pass_3d_node.rs @@ -99,14 +99,8 @@ impl Node for MainPass3dNode { let render_pass = render_context .command_encoder .begin_render_pass(&pass_descriptor); -<<<<<<< HEAD - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); -======= let mut render_pass = TrackedRenderPass::new(render_pass); ->>>>>>> main if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); } @@ -180,14 +174,8 @@ impl Node for MainPass3dNode { let render_pass = render_context .command_encoder .begin_render_pass(&pass_descriptor); -<<<<<<< HEAD - let mut draw_functions = draw_functions.write(); - draw_functions.prepare(world); - let mut tracked_pass = TrackedRenderPass::new(render_pass); -======= let mut render_pass = TrackedRenderPass::new(render_pass); ->>>>>>> main if let Some(viewport) = camera.viewport.as_ref() { render_pass.set_camera_viewport(viewport); } diff --git a/crates/bevy_render/src/render_phase/mod.rs b/crates/bevy_render/src/render_phase/mod.rs index 02ed5852e418c..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(); From 592dd8e698fd719f7a6ef7f9e191b1999fda13bb Mon Sep 17 00:00:00 2001 From: James Liu Date: Tue, 3 Jan 2023 15:24:09 -0500 Subject: [PATCH 16/20] Add SystemState::get_manual(_mut) --- crates/bevy_ecs/src/system/function_system.rs | 62 ++++++++++++++++++- crates/bevy_render/src/render_phase/draw.rs | 3 +- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 2cc88f9e30b77..3f68642a7c6ca 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -170,7 +170,8 @@ impl SystemState { where Param: ReadOnlySystemParam, { - self.validate_world_and_update_archetypes(world); + self.validate_world(world); + self.update_archetypes(world); // SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with. unsafe { self.get_unchecked_manual(world) } } @@ -178,7 +179,8 @@ impl SystemState { /// Retrieve the mutable [`SystemParam`] values. #[inline] pub fn get_mut<'w, 's>(&'s mut self, world: &'w mut World) -> SystemParamItem<'w, 's, Param> { - self.validate_world_and_update_archetypes(world); + self.validate_world(world); + self.update_archetypes(world); // SAFETY: World is uniquely borrowed and matches the World this SystemState was created with. unsafe { self.get_unchecked_manual(world) } } @@ -196,8 +198,13 @@ impl SystemState { self.world_id == world.id() } - fn validate_world_and_update_archetypes(&mut self, world: &World) { + #[inline] + fn validate_world(&mut self, world: &World) { assert!(self.matches_world(world), "Encountered a mismatched World. A SystemState cannot be used with Worlds other than the one it was created with."); + } + + #[inline] + pub fn update_archetypes(&mut self, world: &World) { let archetypes = world.archetypes(); let new_generation = archetypes.generation(); let old_generation = std::mem::replace(&mut self.archetype_generation, new_generation); @@ -211,6 +218,42 @@ impl SystemState { } } + /// Retrieve the [`SystemParam`] values. This can only be called when all parameters are read-only. + /// This will not update archetypes automatically nor increment the world's change tick. + /// + /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this + /// function. + /// + /// Users should strongly prefer to use [`SystemState::get`] over this function. + #[inline] + pub fn get_manual<'w, 's>(&'s mut self, world: &'w World) -> SystemParamItem<'w, 's, Param> + where + Param: ReadOnlySystemParam, + { + self.validate_world(world); + let change_tick = world.read_change_tick(); + // SAFETY: Param is read-only and doesn't allow mutable access to World. It also matches the World this SystemState was created with. + unsafe { self.fetch(world, change_tick) } + } + + /// Retrieve the mutable [`SystemParam`] values. This will not update archetypes automatically nor increment + /// the world's change tick. + /// + /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this + /// function. + /// + /// Users should strongly prefer to use [`SystemState::get_mut`] over this function. + #[inline] + pub fn get_manual_mut<'w, 's>( + &'s mut self, + world: &'w mut World, + ) -> SystemParamItem<'w, 's, Param> { + self.validate_world(world); + let change_tick = world.change_tick(); + // SAFETY: World is uniquely borrowed and matches the World this SystemState was created with. + unsafe { self.fetch(world, change_tick) } + } + /// Retrieve the [`SystemParam`] values. This will not update archetypes automatically. /// /// # Safety @@ -223,6 +266,19 @@ impl SystemState { world: &'w World, ) -> SystemParamItem<'w, 's, Param> { let change_tick = world.increment_change_tick(); + self.fetch(world, change_tick) + } + + /// # Safety + /// This call might access any of the input parameters in a way that violates Rust's mutability rules. Make sure the data + /// access is safe in the context of global [`World`] access. The passed-in [`World`] _must_ be the [`World`] the [`SystemState`] was + /// created with. + #[inline] + unsafe fn fetch<'w, 's>( + &'s mut self, + world: &'w World, + change_tick: u32, + ) -> SystemParamItem<'w, 's, Param> { let param = ::get_param( &mut self.param_state, &self.meta, diff --git a/crates/bevy_render/src/render_phase/draw.rs b/crates/bevy_render/src/render_phase/draw.rs index d0a60d529d57c..c433a91299ee6 100644 --- a/crates/bevy_render/src/render_phase/draw.rs +++ b/crates/bevy_render/src/render_phase/draw.rs @@ -325,6 +325,7 @@ where C::Param: ReadOnlySystemParam, { fn prepare(&mut self, world: &'_ World) { + self.state.update_archetypes(world); self.view.update_archetypes(world); self.entity.update_archetypes(world); } @@ -337,7 +338,7 @@ where view: Entity, item: &P, ) { - let param = self.state.get(world); + let param = self.state.get_manual(world); 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); From 0a79eec44e45d52b24b132604f231f5f8905ebeb Mon Sep 17 00:00:00 2001 From: James Liu Date: Mon, 9 Jan 2023 13:15:25 -0800 Subject: [PATCH 17/20] Add doc comment for `validate_world` Co-authored-by: Alice Cecile --- crates/bevy_ecs/src/system/function_system.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 3f68642a7c6ca..d33814d7a440b 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -199,6 +199,7 @@ impl SystemState { } #[inline] + /// Asserts that the [`SystemState`] matches the provided [`World`]. fn validate_world(&mut self, world: &World) { assert!(self.matches_world(world), "Encountered a mismatched World. A SystemState cannot be used with Worlds other than the one it was created with."); } From b90341e5cafe00758e836fd2c725b9010a76d948 Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 16 Jan 2023 22:56:10 -0800 Subject: [PATCH 18/20] Improve wording on get_manual variant's docs --- crates/bevy_ecs/src/system/function_system.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index db48612e3c18d..37b97b104ba43 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -221,7 +221,8 @@ impl SystemState { } /// Retrieve the [`SystemParam`] values. This can only be called when all parameters are read-only. - /// This will not update archetypes automatically nor increment the world's change tick. + /// This will not update the state's view of the world's archetypes automatically nor increment the + /// world's change tick. /// /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this /// function. @@ -238,8 +239,8 @@ impl SystemState { unsafe { self.fetch(world, change_tick) } } - /// Retrieve the mutable [`SystemParam`] values. This will not update archetypes automatically nor increment - /// the world's change tick. + /// Retrieve the mutable [`SystemParam`] values. This will not update the state's view of the world's archetypes + /// automatically nor increment the world's change tick. /// /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this /// function. From ce70df98751cc19facadeda215c45f85048cc6a3 Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 16 Jan 2023 23:00:26 -0800 Subject: [PATCH 19/20] Document update_archetypes --- crates/bevy_ecs/src/system/function_system.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 37b97b104ba43..b002e5a04184c 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -204,6 +204,12 @@ impl SystemState { assert!(self.matches_world(world), "Encountered a mismatched World. A SystemState cannot be used with Worlds other than the one it was created with."); } + /// Updates the state's internal view of the `world`'s archetypes. If this is not called before fetching the parameters, + /// the results may not accurately reflect what is in the `world`. + /// + /// This is only required if [`SystemState::get_manual`] or [`SystemState::get_manual_mut`] is being called, and it only needs to + /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using + /// [`SystemState::get`] or [`SystemState::get_mut`] do not need to call this as it will be automatically called for them. #[inline] pub fn update_archetypes(&mut self, world: &World) { let archetypes = world.archetypes(); From 15b8527e7ce27f91d0848a7a4975b92d1b970877 Mon Sep 17 00:00:00 2001 From: james7132 Date: Mon, 16 Jan 2023 23:09:07 -0800 Subject: [PATCH 20/20] Formatting --- crates/bevy_ecs/src/system/function_system.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index b002e5a04184c..7493f6d3a1584 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -205,10 +205,10 @@ impl SystemState { } /// Updates the state's internal view of the `world`'s archetypes. If this is not called before fetching the parameters, - /// the results may not accurately reflect what is in the `world`. - /// - /// This is only required if [`SystemState::get_manual`] or [`SystemState::get_manual_mut`] is being called, and it only needs to - /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using + /// the results may not accurately reflect what is in the `world`. + /// + /// This is only required if [`SystemState::get_manual`] or [`SystemState::get_manual_mut`] is being called, and it only needs to + /// be called if the `world` has been structurally mutated (i.e. added/removed a component or resource). Users using /// [`SystemState::get`] or [`SystemState::get_mut`] do not need to call this as it will be automatically called for them. #[inline] pub fn update_archetypes(&mut self, world: &World) { @@ -227,7 +227,7 @@ impl SystemState { } /// Retrieve the [`SystemParam`] values. This can only be called when all parameters are read-only. - /// This will not update the state's view of the world's archetypes automatically nor increment the + /// This will not update the state's view of the world's archetypes automatically nor increment the /// world's change tick. /// /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this @@ -245,7 +245,7 @@ impl SystemState { unsafe { self.fetch(world, change_tick) } } - /// Retrieve the mutable [`SystemParam`] values. This will not update the state's view of the world's archetypes + /// Retrieve the mutable [`SystemParam`] values. This will not update the state's view of the world's archetypes /// automatically nor increment the world's change tick. /// /// For this to return accurate results, ensure [`SystemState::update_archetypes`] is called before this