begin migrating to render resource providers to systems

This commit is contained in:
Carter Anderson 2020-04-15 17:46:22 -07:00
parent 71460baa3d
commit b5ec8e78d8
8 changed files with 130 additions and 164 deletions

View file

@ -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::<WindowResized>(),
))
.add_resource_provider(LightResourceProvider::new(10))
.add_resource_provider(MeshResourceProvider::default())
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::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::<Mesh, StandardMaterial>();
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::<StandardMaterial>(),
)
.add_system_to_stage(
stage::POST_UPDATE,
shader::asset_handle_batcher_system::<StandardMaterial>(),
)
.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::<Mesh>::new())
.add_resource(AssetStorage::<Texture>::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::<StandardMaterial>(),
)
.add_system_to_stage(
stage::POST_UPDATE,
shader::asset_handle_batcher_system::<StandardMaterial>(),
)
// render resource provider systems
.build_system_on_stage(RENDER_RESOURCE_STAGE, mesh_resource_provider_system);
RenderPlugin::setup_render_graph_defaults(app);
}
}

View file

@ -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<dyn Schedulable> {
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
SystemBuilder::new("mesh_resource_provider")
.read_resource::<GlobalRenderResourceContext>()
.read_resource::<AssetStorage<Mesh>>()
.write_resource::<AssetBatchers>()
.build(
|_, _, (render_resource_context, meshes, asset_batchers), _| {
let render_resources = &render_resource_context.context;
if let Some(batches) = asset_batchers.get_handle_batches_mut::<Mesh>() {
for batch in batches {
let handle = batch.get_handle::<Mesh>().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<Mesh>,
handle: Handle<Mesh>,
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::<VertexBufferDescriptors>().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::<AssetStorage<Mesh>>().unwrap();
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
// this scope is necessary because the Fetch<AssetBatchers> pointer behaves weirdly
{
if let Some(batches) = asset_batchers.get_handle_batches_mut::<Mesh>() {
for batch in batches {
let handle = batch.get_handle::<Mesh>().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,
);
}
}
}
};
}
},
)
}

View file

@ -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::<AssetStorage<T>>();

View file

@ -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>,
shader_storage: &AssetStorage<Shader>,
);
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<T>(
&mut self,
&self,
handle: Handle<T>,
render_resource: RenderResource,
index: usize,

View file

@ -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::<Events<WindowResized>>().unwrap();
let window_created_event = resources.get::<Events<WindowCreated>>().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::<Events<WindowResized>>().unwrap();
let window_created_event = resources.get::<Events<WindowCreated>>().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);

View file

@ -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,

View file

@ -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::<GlobalRenderResourceContext>().unwrap();
let render_resource_context = global_context

View file

@ -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,