diff --git a/bevy_render/src/lib.rs b/bevy_render/src/lib.rs index 73711241d2..a6be6bb1c0 100644 --- a/bevy_render/src/lib.rs +++ b/bevy_render/src/lib.rs @@ -42,7 +42,7 @@ use self::{ build_entity_render_resource_assignments_system, resource_providers::{ Camera2dResourceProvider, CameraResourceProvider, LightResourceProvider, - MeshResourceProvider, UniformResourceProvider, + UniformResourceProvider, }, AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignments, }, @@ -54,7 +54,9 @@ use bevy_app::{stage, AppBuilder, AppPlugin, GetEventReader}; use bevy_asset::AssetStorage; use bevy_transform::prelude::LocalToWorld; use bevy_window::WindowResized; +use render_resource::resource_providers::mesh_resource_provider_system; +pub static RENDER_RESOURCE_STAGE: &str = "render_resource"; pub static RENDER_STAGE: &str = "render"; #[derive(Default)] @@ -82,7 +84,6 @@ impl RenderPlugin { resources.get_event_reader::(), )) .add_resource_provider(LightResourceProvider::new(10)) - .add_resource_provider(MeshResourceProvider::default()) .add_resource_provider(UniformResourceProvider::::new(true)) .add_resource_provider(UniformResourceProvider::::new(true)) .add_forward_pass() @@ -94,18 +95,9 @@ impl AppPlugin for RenderPlugin { fn build(&self, app: &mut AppBuilder) { let mut asset_batchers = AssetBatchers::default(); asset_batchers.batch_types2::(); - app.add_system(build_entity_render_resource_assignments_system()) - .build_system_on_stage(stage::POST_UPDATE, camera::camera_update_system) - .add_system_to_stage(stage::POST_UPDATE, mesh::mesh_batcher_system()) - .add_system_to_stage( - stage::POST_UPDATE, - shader::asset_handle_shader_def_system::(), - ) - .add_system_to_stage( - stage::POST_UPDATE, - shader::asset_handle_batcher_system::(), - ) - .add_stage_after(stage::POST_UPDATE, RENDER_STAGE) + app.add_stage_after(stage::POST_UPDATE, RENDER_RESOURCE_STAGE) + .add_stage_after(RENDER_RESOURCE_STAGE, RENDER_STAGE) + // resources .add_resource(RenderGraph::default()) .add_resource(AssetStorage::::new()) .add_resource(AssetStorage::::new()) @@ -117,7 +109,21 @@ impl AppPlugin for RenderPlugin { .add_resource(PipelineCompiler::new()) .add_resource(RenderResourceAssignments::default()) .add_resource(EntityRenderResourceAssignments::default()) - .add_resource(asset_batchers); + .add_resource(asset_batchers) + // core systems + .add_system(build_entity_render_resource_assignments_system()) + .build_system_on_stage(stage::POST_UPDATE, camera::camera_update_system) + .add_system_to_stage(stage::POST_UPDATE, mesh::mesh_batcher_system()) + .add_system_to_stage( + stage::POST_UPDATE, + shader::asset_handle_shader_def_system::(), + ) + .add_system_to_stage( + stage::POST_UPDATE, + shader::asset_handle_batcher_system::(), + ) + // render resource provider systems + .build_system_on_stage(RENDER_RESOURCE_STAGE, mesh_resource_provider_system); RenderPlugin::setup_render_graph_defaults(app); } } diff --git a/bevy_render/src/render_resource/resource_providers/mesh_resource_provider.rs b/bevy_render/src/render_resource/resource_providers/mesh_resource_provider.rs index 238b2cf4ea..624dd04e9a 100644 --- a/bevy_render/src/render_resource/resource_providers/mesh_resource_provider.rs +++ b/bevy_render/src/render_resource/resource_providers/mesh_resource_provider.rs @@ -1,111 +1,75 @@ use crate::{ mesh::{self, Mesh}, pipeline::VertexBufferDescriptors, - render_resource::{ - AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider, - }, - renderer_2::RenderContext, + render_resource::{AssetBatchers, BufferInfo, BufferUsage}, + renderer_2::GlobalRenderResourceContext, shader::AsUniforms, Vertex, }; -use bevy_asset::{AssetStorage, Handle}; +use bevy_asset::AssetStorage; use legion::prelude::*; use zerocopy::AsBytes; -#[derive(Default)] -pub struct MeshResourceProvider; +pub fn mesh_resource_provider_system(resources: &mut Resources) -> Box { + let mut vertex_buffer_descriptors = resources.get_mut::().unwrap(); + vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap()); + SystemBuilder::new("mesh_resource_provider") + .read_resource::() + .read_resource::>() + .write_resource::() + .build( + |_, _, (render_resource_context, meshes, asset_batchers), _| { + let render_resources = &render_resource_context.context; + if let Some(batches) = asset_batchers.get_handle_batches_mut::() { + for batch in batches { + let handle = batch.get_handle::().unwrap(); + log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id); + let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = + render_resources + .get_asset_resource(handle, mesh::VERTEX_BUFFER_ASSET_INDEX) + { + ( + vertex_buffer, + render_resources + .get_asset_resource(handle, mesh::INDEX_BUFFER_ASSET_INDEX), + ) + } else { + let mesh_asset = meshes.get(&handle).unwrap(); + let vertex_buffer = render_resources.create_buffer_with_data( + BufferInfo { + buffer_usage: BufferUsage::VERTEX, + ..Default::default() + }, + mesh_asset.vertices.as_bytes(), + ); + let index_buffer = render_resources.create_buffer_with_data( + BufferInfo { + buffer_usage: BufferUsage::INDEX, + ..Default::default() + }, + mesh_asset.indices.as_bytes(), + ); -impl MeshResourceProvider { - fn setup_mesh_resources( - render_context: &mut dyn RenderContext, - mesh_storage: &AssetStorage, - handle: Handle, - render_resource_assignments: &mut RenderResourceAssignments, - ) { - let render_resources = render_context.resources_mut(); - let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = - render_resources.get_asset_resource(handle, mesh::VERTEX_BUFFER_ASSET_INDEX) - { - ( - vertex_buffer, - render_resources.get_asset_resource(handle, mesh::INDEX_BUFFER_ASSET_INDEX), - ) - } else { - let mesh_asset = mesh_storage.get(&handle).unwrap(); - let vertex_buffer = render_resources.create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::VERTEX, - ..Default::default() - }, - mesh_asset.vertices.as_bytes(), - ); - let index_buffer = render_resources.create_buffer_with_data( - BufferInfo { - buffer_usage: BufferUsage::INDEX, - ..Default::default() - }, - mesh_asset.indices.as_bytes(), - ); + render_resources.set_asset_resource( + handle, + vertex_buffer, + mesh::VERTEX_BUFFER_ASSET_INDEX, + ); + render_resources.set_asset_resource( + handle, + index_buffer, + mesh::INDEX_BUFFER_ASSET_INDEX, + ); + (vertex_buffer, Some(index_buffer)) + }; - render_resources.set_asset_resource( - handle, - vertex_buffer, - mesh::VERTEX_BUFFER_ASSET_INDEX, - ); - render_resources.set_asset_resource( - handle, - index_buffer, - mesh::INDEX_BUFFER_ASSET_INDEX, - ); - (vertex_buffer, Some(index_buffer)) - }; - - render_resource_assignments.set_vertex_buffer("Vertex", vertex_buffer, index_buffer); - } -} - -impl ResourceProvider for MeshResourceProvider { - fn initialize( - &mut self, - _render_context: &mut dyn RenderContext, - _world: &mut World, - resources: &Resources, - ) { - let mut vertex_buffer_descriptors = resources.get_mut::().unwrap(); - vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap()); - } - - fn update( - &mut self, - _render_context: &mut dyn RenderContext, - _world: &World, - _resources: &Resources, - ) { - } - - fn finish_update( - &mut self, - render_context: &mut dyn RenderContext, - _world: &mut World, - resources: &Resources, - ) { - let mesh_storage = resources.get::>().unwrap(); - let mut asset_batchers = resources.get_mut::().unwrap(); - - // this scope is necessary because the Fetch pointer behaves weirdly - { - if let Some(batches) = asset_batchers.get_handle_batches_mut::() { - for batch in batches { - let handle = batch.get_handle::().unwrap(); - log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id); - Self::setup_mesh_resources( - render_context, - &mesh_storage, - handle, - &mut batch.render_resource_assignments, - ); + batch.render_resource_assignments.set_vertex_buffer( + "Vertex", + vertex_buffer, + index_buffer, + ); + } } - } - }; - } + }, + ) } diff --git a/bevy_render/src/render_resource/resource_providers/uniform_resource_provider.rs b/bevy_render/src/render_resource/resource_providers/uniform_resource_provider.rs index bc394e8f11..f8bf4a90b9 100644 --- a/bevy_render/src/render_resource/resource_providers/uniform_resource_provider.rs +++ b/bevy_render/src/render_resource/resource_providers/uniform_resource_provider.rs @@ -269,7 +269,7 @@ where fn setup_uniform_buffer_resources( &mut self, uniforms: &T, - render_resources: &mut dyn RenderResourceContext, + render_resources: &dyn RenderResourceContext, render_resource_assignments: &mut RenderResourceAssignments, staging_buffer: &mut [u8], ) { @@ -428,7 +428,7 @@ where fn setup_uniforms_buffer_resources( &mut self, world: &mut World, - render_resources: &mut dyn RenderResourceContext, + render_resources: &dyn RenderResourceContext, staging_buffer: &mut [u8], ) { let query_finish = self.query_finish.take().unwrap(); @@ -489,7 +489,7 @@ where &mut self, world: &mut World, resources: &Resources, - render_resources: &mut dyn RenderResourceContext, + render_resources: &dyn RenderResourceContext, staging_buffer: &mut [u8], ) { let assets = resources.get::>(); diff --git a/bevy_render/src/renderer_2/render_resource_context.rs b/bevy_render/src/renderer_2/render_resource_context.rs index e59ae93b4e..cd527fc433 100644 --- a/bevy_render/src/renderer_2/render_resource_context.rs +++ b/bevy_render/src/renderer_2/render_resource_context.rs @@ -23,33 +23,33 @@ impl GlobalRenderResourceContext { } pub trait RenderResourceContext: Downcast + Send + Sync + 'static { - fn create_swap_chain(&mut self, window: &Window); - fn next_swap_chain_texture(&mut self, window_id: WindowId); - fn drop_swap_chain_texture(&mut self, window_id: WindowId); - fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource; - fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource; - fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource; + fn create_swap_chain(&self, window: &Window); + fn next_swap_chain_texture(&self, window_id: WindowId); + fn drop_swap_chain_texture(&self, window_id: WindowId); + fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResource; + fn create_texture(&self, texture_descriptor: &TextureDescriptor) -> RenderResource; + fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResource; fn create_buffer_mapped( - &mut self, + &self, buffer_info: BufferInfo, - setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext), + setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), ) -> RenderResource; - fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource; + fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource; fn create_shader_module( &mut self, shader_handle: Handle, shader_storage: &AssetStorage, ); - fn remove_buffer(&mut self, resource: RenderResource); - fn remove_texture(&mut self, resource: RenderResource); - fn remove_sampler(&mut self, resource: RenderResource); + fn remove_buffer(&self, resource: RenderResource); + fn remove_texture(&self, resource: RenderResource); + fn remove_sampler(&self, resource: RenderResource); fn get_resource_info( &self, resource: RenderResource, handle_info: &mut dyn FnMut(Option<&ResourceInfo>), ); fn set_asset_resource_untyped( - &mut self, + &self, handle: HandleUntyped, render_resource: RenderResource, index: usize, @@ -63,7 +63,7 @@ pub trait RenderResourceContext: Downcast + Send + Sync + 'static { impl dyn RenderResourceContext { pub fn set_asset_resource( - &mut self, + &self, handle: Handle, render_resource: RenderResource, index: usize, diff --git a/bevy_wgpu/src/lib.rs b/bevy_wgpu/src/lib.rs index e799acdc9b..0a86edf635 100644 --- a/bevy_wgpu/src/lib.rs +++ b/bevy_wgpu/src/lib.rs @@ -9,26 +9,32 @@ pub use wgpu_renderer::*; pub use wgpu_resources::*; use bevy_app::{AppBuilder, AppPlugin, Events}; -use bevy_render::RENDER_STAGE; +use bevy_render::{renderer_2::GlobalRenderResourceContext, RENDER_STAGE}; use bevy_window::{WindowCreated, WindowResized}; use legion::prelude::*; +use renderer_2::WgpuRenderResourceContext; #[derive(Default)] pub struct WgpuPlugin; impl AppPlugin for WgpuPlugin { fn build(&self, app: &mut AppBuilder) { - let render_system = wgpu_render_system(app.resources()); + let render_system = wgpu_render_system(app.resources_mut()); app.add_thread_local_fn_to_stage(RENDER_STAGE, render_system); } } -pub fn wgpu_render_system(resources: &Resources) -> impl FnMut(&mut World, &mut Resources) { - let window_resized_event = resources.get::>().unwrap(); - let window_created_event = resources.get::>().unwrap(); - let mut wgpu_renderer = futures::executor::block_on(WgpuRenderer::new( - window_resized_event.get_reader(), - window_created_event.get_reader(), +pub fn wgpu_render_system(resources: &mut Resources) -> impl FnMut(&mut World, &mut Resources) { + let mut wgpu_renderer = { + let window_resized_event = resources.get::>().unwrap(); + let window_created_event = resources.get::>().unwrap(); + futures::executor::block_on(WgpuRenderer::new( + window_resized_event.get_reader(), + window_created_event.get_reader(), + )) + }; + resources.insert(GlobalRenderResourceContext::new( + WgpuRenderResourceContext::new(wgpu_renderer.device.clone()), )); move |world, resources| { wgpu_renderer.update(world, resources); diff --git a/bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs b/bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs index c8b9ac1218..2b3a5dde39 100644 --- a/bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs +++ b/bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs @@ -26,23 +26,23 @@ impl WgpuRenderResourceContext { } impl RenderResourceContext for WgpuRenderResourceContext { - fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource { + fn create_sampler(&self, sampler_descriptor: &SamplerDescriptor) -> RenderResource { self.wgpu_resources .create_sampler(&self.device, sampler_descriptor) } - fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource { + fn create_texture(&self, texture_descriptor: &TextureDescriptor) -> RenderResource { self.wgpu_resources .create_texture(&self.device, texture_descriptor) } - fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource { + fn create_buffer(&self, buffer_info: BufferInfo) -> RenderResource { self.wgpu_resources.create_buffer(&self.device, buffer_info) } // TODO: clean this up fn create_buffer_mapped( - &mut self, + &self, buffer_info: BufferInfo, - setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext), + setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), ) -> RenderResource { let buffer = WgpuResources::begin_create_buffer_mapped_render_context( &buffer_info, @@ -52,18 +52,18 @@ impl RenderResourceContext for WgpuRenderResourceContext { self.wgpu_resources.assign_buffer(buffer, buffer_info) } - fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource { + fn create_buffer_with_data(&self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource { self.wgpu_resources .create_buffer_with_data(&self.device, buffer_info, data) } - fn remove_buffer(&mut self, resource: RenderResource) { + fn remove_buffer(&self, resource: RenderResource) { self.wgpu_resources.remove_buffer(resource); } - fn remove_texture(&mut self, resource: RenderResource) { + fn remove_texture(&self, resource: RenderResource) { self.wgpu_resources.remove_texture(resource); } - fn remove_sampler(&mut self, resource: RenderResource) { + fn remove_sampler(&self, resource: RenderResource) { self.wgpu_resources.remove_sampler(resource); } @@ -95,18 +95,18 @@ impl RenderResourceContext for WgpuRenderResourceContext { self.wgpu_resources .create_shader_module(&self.device, shader_handle, shader); } - fn create_swap_chain(&mut self, window: &Window) { + fn create_swap_chain(&self, window: &Window) { self.wgpu_resources .create_window_swap_chain(&self.device, window) } - fn next_swap_chain_texture(&mut self, window_id: bevy_window::WindowId) { + fn next_swap_chain_texture(&self, window_id: bevy_window::WindowId) { self.wgpu_resources.next_swap_chain_texture(window_id); } - fn drop_swap_chain_texture(&mut self, window_id: WindowId) { + fn drop_swap_chain_texture(&self, window_id: WindowId) { self.wgpu_resources.remove_swap_chain_texture(window_id); } fn set_asset_resource_untyped( - &mut self, + &self, handle: HandleUntyped, render_resource: RenderResource, index: usize, diff --git a/bevy_wgpu/src/wgpu_renderer.rs b/bevy_wgpu/src/wgpu_renderer.rs index 0ebba8acad..c9bb69ed92 100644 --- a/bevy_wgpu/src/wgpu_renderer.rs +++ b/bevy_wgpu/src/wgpu_renderer.rs @@ -225,17 +225,7 @@ impl WgpuRenderer { } } - pub fn create_global_render_resource_context(&self, resources: &mut Resources) { - resources.insert(GlobalRenderResourceContext::new( - WgpuRenderResourceContext::new(self.device.clone()), - )) - } - pub fn update(&mut self, world: &mut World, resources: &mut Resources) { - if !self.intialized { - self.create_global_render_resource_context(resources); - } - let mut encoder = { let mut global_context = resources.get_mut::().unwrap(); let render_resource_context = global_context diff --git a/bevy_wgpu/src/wgpu_resources.rs b/bevy_wgpu/src/wgpu_resources.rs index 4f3bc2e0c6..db9363eb3b 100644 --- a/bevy_wgpu/src/wgpu_resources.rs +++ b/bevy_wgpu/src/wgpu_resources.rs @@ -243,8 +243,8 @@ impl WgpuResources { // TODO: clean this up pub fn begin_create_buffer_mapped_render_context( buffer_info: &BufferInfo, - render_resources: &mut WgpuRenderResourceContext, - setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext), + render_resources: &WgpuRenderResourceContext, + setup_data: &mut dyn FnMut(&mut [u8], &dyn RenderResourceContext), ) -> wgpu::Buffer { let device = render_resources.device.clone(); let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor { @@ -390,7 +390,7 @@ impl WgpuResources { } pub fn set_asset_resource_untyped( - &mut self, + &self, handle: HandleUntyped, render_resource: RenderResource, index: usize,