asset handle batcher system

This commit is contained in:
Carter Anderson 2020-04-12 00:54:51 -07:00
parent 32bce28b00
commit 1d44b4034f
7 changed files with 74 additions and 64 deletions

View File

@ -83,7 +83,7 @@ impl RenderPlugin {
resources.get_event_reader::<WindowResized>(),
))
.add_resource_provider(LightResourceProvider::new(10))
.add_resource_provider(MeshResourceProvider::new())
.add_resource_provider(MeshResourceProvider::default())
.add_resource_provider(UniformResourceProvider::<StandardMaterial>::new(true))
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
.add_forward_pass()
@ -99,6 +99,7 @@ impl AppPlugin for RenderPlugin {
.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)
.add_resource(RenderGraph::default())
.add_resource(AssetStorage::<Mesh>::new())

View File

@ -4,40 +4,18 @@ use crate::{
render_resource::{
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
},
renderer_2::RenderContext,
shader::AsUniforms,
Renderable, Vertex, renderer_2::RenderContext,
Vertex,
};
use bevy_asset::{AssetStorage, Handle};
use legion::{filter::*, prelude::*};
use legion::prelude::*;
use zerocopy::AsBytes;
pub struct MeshResourceProvider {
pub mesh_query: Query<
(Read<Handle<Mesh>>, Read<Renderable>),
EntityFilterTuple<
And<(
ComponentFilter<Handle<Mesh>>,
ComponentFilter<Renderable>,
ComponentFilter<Handle<Mesh>>,
)>,
And<(Passthrough, Passthrough)>,
And<(
Passthrough,
Passthrough,
ComponentChangedFilter<Handle<Mesh>>,
)>,
>,
>,
}
#[derive(Default)]
pub struct MeshResourceProvider;
impl MeshResourceProvider {
pub fn new() -> Self {
MeshResourceProvider {
mesh_query: <(Read<Handle<Mesh>>, Read<Renderable>)>::query()
.filter(changed::<Handle<Mesh>>()),
}
}
fn setup_mesh_resources(
render_context: &mut dyn RenderContext,
mesh_storage: &AssetStorage<Mesh>,
@ -45,36 +23,34 @@ impl MeshResourceProvider {
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_mesh_vertices_resource(handle)
{
(
vertex_buffer,
render_resources
.get_mesh_indices_resource(handle),
)
} 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(),
);
let (vertex_buffer, index_buffer) =
if let Some(vertex_buffer) = render_resources.get_mesh_vertices_resource(handle) {
(
vertex_buffer,
render_resources.get_mesh_indices_resource(handle),
)
} 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(),
);
let asset_resources = render_resources.asset_resources_mut();
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
asset_resources.set_mesh_indices_resource(handle, index_buffer);
(vertex_buffer, Some(index_buffer))
};
let asset_resources = render_resources.asset_resources_mut();
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
asset_resources.set_mesh_indices_resource(handle, index_buffer);
(vertex_buffer, Some(index_buffer))
};
render_resource_assignments.set_vertex_buffer("Vertex", vertex_buffer, index_buffer);
}
@ -91,7 +67,12 @@ impl ResourceProvider for MeshResourceProvider {
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 update(
&mut self,
_render_context: &mut dyn RenderContext,
_world: &World,
_resources: &Resources,
) {
}
fn finish_update(

View File

@ -167,9 +167,8 @@ where
fn update_uniform_handles_info(&mut self, world: &World, resources: &Resources) {
let handle_query = self.handle_query.take().unwrap();
let assets = resources.get::<AssetStorage<T>>();
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
if let Some(assets) = assets {
for (entity, (handle, renderable)) in handle_query.iter_entities(world) {
for (handle, renderable) in handle_query.iter(world) {
if !renderable.is_visible {
return;
}
@ -187,7 +186,6 @@ where
);
}
} else {
asset_batchers.set_entity_handle(entity, *handle);
let uniforms = assets
.get(&handle)
.expect("Handle points to a non-existent resource");

View File

@ -2,7 +2,7 @@ use crate::{
color::ColorSource,
pipeline::{BindType, VertexBufferDescriptor},
texture::Texture,
Renderable,
Renderable, render_resource::AssetBatchers,
};
use bevy_asset::{AssetStorage, Handle};
@ -49,6 +49,10 @@ where
.with_query(<(Read<Handle<T>>, Write<Renderable>)>::query())
.build(|_, world, asset_storage, query| {
for (uniform_handle, mut renderable) in query.iter_mut(world) {
if !renderable.is_visible || renderable.is_instanced {
continue;
}
let uniforms = asset_storage.get(&uniform_handle).unwrap();
if let Some(shader_defs) = uniforms.get_shader_defs() {
renderable.render_resource_assignments.shader_defs.extend(shader_defs)
@ -57,6 +61,27 @@ where
})
}
pub fn asset_handle_batcher_system<T>() -> Box<dyn Schedulable>
where
T: AsUniforms + Send + Sync + 'static,
{
SystemBuilder::new(format!(
"asset_handle_batcher::{}",
std::any::type_name::<T>()
))
.write_resource::<AssetBatchers>()
.with_query(<(Read<Handle<T>>, Read<Renderable>)>::query())
.build(|_, world, asset_batchers, query| {
for (entity, (uniform_handle, renderable)) in query.iter_entities(world) {
if !renderable.is_visible || renderable.is_instanced {
continue;
}
asset_batchers.set_entity_handle(entity, *uniform_handle);
}
})
}
pub trait ShaderDefSuffixProvider {
fn get_shader_def(&self) -> Option<&'static str>;
}

View File

@ -231,7 +231,7 @@ impl WgpuRenderer {
device: Arc<wgpu::Device>,
global_wgpu_resources: &WgpuResources,
) -> (Vec::<wgpu::CommandBuffer>, Vec::<WgpuResources>) {
let max_thread_count = 4;
let max_thread_count = 8;
let (sender, receiver) = crossbeam_channel::bounded(max_thread_count);
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
let chunk_size = (render_graph.resource_providers.len() + max_thread_count - 1) / max_thread_count; // divide ints rounding remainder up

View File

@ -1,8 +1,9 @@
use bevy::{prelude::*};
use bevy::{prelude::*, render::shader};
fn main() {
App::build()
.add_default_plugins()
.add_system_to_stage(stage::POST_UPDATE, shader::asset_handle_batcher_system::<MyMaterial>())
.setup(setup)
.run();
}

View File

@ -4,6 +4,10 @@ fn main() {
App::build()
.add_default_plugins()
.setup(setup)
.add_system_to_stage(
stage::POST_UPDATE,
shader::asset_handle_batcher_system::<MyMaterial>(),
)
.add_system_to_stage(
stage::POST_UPDATE,
shader::asset_handle_shader_def_system::<MyMaterial>(),