asset handle batcher system
This commit is contained in:
parent
32bce28b00
commit
1d44b4034f
@ -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())
|
||||
|
||||
@ -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(
|
||||
|
||||
@ -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");
|
||||
|
||||
@ -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>;
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
}
|
||||
|
||||
@ -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>(),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user