asset handle batcher system
This commit is contained in:
parent
32bce28b00
commit
1d44b4034f
@ -83,7 +83,7 @@ impl RenderPlugin {
|
|||||||
resources.get_event_reader::<WindowResized>(),
|
resources.get_event_reader::<WindowResized>(),
|
||||||
))
|
))
|
||||||
.add_resource_provider(LightResourceProvider::new(10))
|
.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::<StandardMaterial>::new(true))
|
||||||
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
|
.add_resource_provider(UniformResourceProvider::<LocalToWorld>::new(true))
|
||||||
.add_forward_pass()
|
.add_forward_pass()
|
||||||
@ -99,6 +99,7 @@ impl AppPlugin for RenderPlugin {
|
|||||||
.build_system_on_stage(stage::POST_UPDATE, camera::camera_update_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, 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_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_stage_after(stage::POST_UPDATE, RENDER_STAGE)
|
||||||
.add_resource(RenderGraph::default())
|
.add_resource(RenderGraph::default())
|
||||||
.add_resource(AssetStorage::<Mesh>::new())
|
.add_resource(AssetStorage::<Mesh>::new())
|
||||||
|
|||||||
@ -4,40 +4,18 @@ use crate::{
|
|||||||
render_resource::{
|
render_resource::{
|
||||||
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
||||||
},
|
},
|
||||||
|
renderer_2::RenderContext,
|
||||||
shader::AsUniforms,
|
shader::AsUniforms,
|
||||||
Renderable, Vertex, renderer_2::RenderContext,
|
Vertex,
|
||||||
};
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use legion::{filter::*, prelude::*};
|
use legion::prelude::*;
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
pub struct MeshResourceProvider {
|
#[derive(Default)]
|
||||||
pub mesh_query: Query<
|
pub struct MeshResourceProvider;
|
||||||
(Read<Handle<Mesh>>, Read<Renderable>),
|
|
||||||
EntityFilterTuple<
|
|
||||||
And<(
|
|
||||||
ComponentFilter<Handle<Mesh>>,
|
|
||||||
ComponentFilter<Renderable>,
|
|
||||||
ComponentFilter<Handle<Mesh>>,
|
|
||||||
)>,
|
|
||||||
And<(Passthrough, Passthrough)>,
|
|
||||||
And<(
|
|
||||||
Passthrough,
|
|
||||||
Passthrough,
|
|
||||||
ComponentChangedFilter<Handle<Mesh>>,
|
|
||||||
)>,
|
|
||||||
>,
|
|
||||||
>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MeshResourceProvider {
|
impl MeshResourceProvider {
|
||||||
pub fn new() -> Self {
|
|
||||||
MeshResourceProvider {
|
|
||||||
mesh_query: <(Read<Handle<Mesh>>, Read<Renderable>)>::query()
|
|
||||||
.filter(changed::<Handle<Mesh>>()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_mesh_resources(
|
fn setup_mesh_resources(
|
||||||
render_context: &mut dyn RenderContext,
|
render_context: &mut dyn RenderContext,
|
||||||
mesh_storage: &AssetStorage<Mesh>,
|
mesh_storage: &AssetStorage<Mesh>,
|
||||||
@ -45,36 +23,34 @@ impl MeshResourceProvider {
|
|||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_assignments: &mut RenderResourceAssignments,
|
||||||
) {
|
) {
|
||||||
let render_resources = render_context.resources_mut();
|
let render_resources = render_context.resources_mut();
|
||||||
let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = render_resources
|
let (vertex_buffer, index_buffer) =
|
||||||
.get_mesh_vertices_resource(handle)
|
if let Some(vertex_buffer) = render_resources.get_mesh_vertices_resource(handle) {
|
||||||
{
|
(
|
||||||
(
|
vertex_buffer,
|
||||||
vertex_buffer,
|
render_resources.get_mesh_indices_resource(handle),
|
||||||
render_resources
|
)
|
||||||
.get_mesh_indices_resource(handle),
|
} else {
|
||||||
)
|
let mesh_asset = mesh_storage.get(&handle).unwrap();
|
||||||
} else {
|
let vertex_buffer = render_resources.create_buffer_with_data(
|
||||||
let mesh_asset = mesh_storage.get(&handle).unwrap();
|
BufferInfo {
|
||||||
let vertex_buffer = render_resources.create_buffer_with_data(
|
buffer_usage: BufferUsage::VERTEX,
|
||||||
BufferInfo {
|
..Default::default()
|
||||||
buffer_usage: BufferUsage::VERTEX,
|
},
|
||||||
..Default::default()
|
mesh_asset.vertices.as_bytes(),
|
||||||
},
|
);
|
||||||
mesh_asset.vertices.as_bytes(),
|
let index_buffer = render_resources.create_buffer_with_data(
|
||||||
);
|
BufferInfo {
|
||||||
let index_buffer = render_resources.create_buffer_with_data(
|
buffer_usage: BufferUsage::INDEX,
|
||||||
BufferInfo {
|
..Default::default()
|
||||||
buffer_usage: BufferUsage::INDEX,
|
},
|
||||||
..Default::default()
|
mesh_asset.indices.as_bytes(),
|
||||||
},
|
);
|
||||||
mesh_asset.indices.as_bytes(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let asset_resources = render_resources.asset_resources_mut();
|
let asset_resources = render_resources.asset_resources_mut();
|
||||||
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
||||||
asset_resources.set_mesh_indices_resource(handle, index_buffer);
|
asset_resources.set_mesh_indices_resource(handle, index_buffer);
|
||||||
(vertex_buffer, Some(index_buffer))
|
(vertex_buffer, Some(index_buffer))
|
||||||
};
|
};
|
||||||
|
|
||||||
render_resource_assignments.set_vertex_buffer("Vertex", vertex_buffer, 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());
|
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(
|
fn finish_update(
|
||||||
|
|||||||
@ -167,9 +167,8 @@ where
|
|||||||
fn update_uniform_handles_info(&mut self, world: &World, resources: &Resources) {
|
fn update_uniform_handles_info(&mut self, world: &World, resources: &Resources) {
|
||||||
let handle_query = self.handle_query.take().unwrap();
|
let handle_query = self.handle_query.take().unwrap();
|
||||||
let assets = resources.get::<AssetStorage<T>>();
|
let assets = resources.get::<AssetStorage<T>>();
|
||||||
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
|
|
||||||
if let Some(assets) = assets {
|
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 {
|
if !renderable.is_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -187,7 +186,6 @@ where
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
asset_batchers.set_entity_handle(entity, *handle);
|
|
||||||
let uniforms = assets
|
let uniforms = assets
|
||||||
.get(&handle)
|
.get(&handle)
|
||||||
.expect("Handle points to a non-existent resource");
|
.expect("Handle points to a non-existent resource");
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use crate::{
|
|||||||
color::ColorSource,
|
color::ColorSource,
|
||||||
pipeline::{BindType, VertexBufferDescriptor},
|
pipeline::{BindType, VertexBufferDescriptor},
|
||||||
texture::Texture,
|
texture::Texture,
|
||||||
Renderable,
|
Renderable, render_resource::AssetBatchers,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
@ -49,6 +49,10 @@ where
|
|||||||
.with_query(<(Read<Handle<T>>, Write<Renderable>)>::query())
|
.with_query(<(Read<Handle<T>>, Write<Renderable>)>::query())
|
||||||
.build(|_, world, asset_storage, query| {
|
.build(|_, world, asset_storage, query| {
|
||||||
for (uniform_handle, mut renderable) in query.iter_mut(world) {
|
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();
|
let uniforms = asset_storage.get(&uniform_handle).unwrap();
|
||||||
if let Some(shader_defs) = uniforms.get_shader_defs() {
|
if let Some(shader_defs) = uniforms.get_shader_defs() {
|
||||||
renderable.render_resource_assignments.shader_defs.extend(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 {
|
pub trait ShaderDefSuffixProvider {
|
||||||
fn get_shader_def(&self) -> Option<&'static str>;
|
fn get_shader_def(&self) -> Option<&'static str>;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -231,7 +231,7 @@ impl WgpuRenderer {
|
|||||||
device: Arc<wgpu::Device>,
|
device: Arc<wgpu::Device>,
|
||||||
global_wgpu_resources: &WgpuResources,
|
global_wgpu_resources: &WgpuResources,
|
||||||
) -> (Vec::<wgpu::CommandBuffer>, Vec::<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 (sender, receiver) = crossbeam_channel::bounded(max_thread_count);
|
||||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
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
|
let chunk_size = (render_graph.resource_providers.len() + max_thread_count - 1) / max_thread_count; // divide ints rounding remainder up
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
use bevy::{prelude::*};
|
use bevy::{prelude::*, render::shader};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
App::build()
|
App::build()
|
||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
|
.add_system_to_stage(stage::POST_UPDATE, shader::asset_handle_batcher_system::<MyMaterial>())
|
||||||
.setup(setup)
|
.setup(setup)
|
||||||
.run();
|
.run();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,10 @@ fn main() {
|
|||||||
App::build()
|
App::build()
|
||||||
.add_default_plugins()
|
.add_default_plugins()
|
||||||
.setup(setup)
|
.setup(setup)
|
||||||
|
.add_system_to_stage(
|
||||||
|
stage::POST_UPDATE,
|
||||||
|
shader::asset_handle_batcher_system::<MyMaterial>(),
|
||||||
|
)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
stage::POST_UPDATE,
|
stage::POST_UPDATE,
|
||||||
shader::asset_handle_shader_def_system::<MyMaterial>(),
|
shader::asset_handle_shader_def_system::<MyMaterial>(),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user