mirror of
https://github.com/bevyengine/bevy
synced 2024-11-29 16:10:19 +00:00
Port remaining functionality to RenderContext and remove Renderer
This commit is contained in:
parent
a8f5402ff1
commit
837e1dc139
42 changed files with 916 additions and 779 deletions
|
@ -4,7 +4,9 @@ use crate::{
|
|||
stage, App, Events,
|
||||
};
|
||||
|
||||
use legion::prelude::{Resources, Runnable, Schedulable, Universe, World, SystemBuilder, CommandBuffer};
|
||||
use legion::prelude::{
|
||||
CommandBuffer, Resources, Runnable, Schedulable, SystemBuilder, Universe, World,
|
||||
};
|
||||
|
||||
static APP_MISSING_MESSAGE: &str = "This AppBuilder no longer has an App. Check to see if you already called run(). A call to app_builder.run() consumes the AppBuilder's App.";
|
||||
|
||||
|
@ -121,9 +123,12 @@ impl AppBuilder {
|
|||
self.add_system_to_stage(stage::UPDATE, system)
|
||||
}
|
||||
|
||||
pub fn add_system_fn(&mut self, name: &'static str, system: impl Fn(&mut CommandBuffer) + Send + Sync + 'static) -> &mut Self {
|
||||
let built_system = SystemBuilder::new(name)
|
||||
.build(move |command_buffer, _, _, _| {
|
||||
pub fn add_system_fn(
|
||||
&mut self,
|
||||
name: &'static str,
|
||||
system: impl Fn(&mut CommandBuffer) + Send + Sync + 'static,
|
||||
) -> &mut Self {
|
||||
let built_system = SystemBuilder::new(name).build(move |command_buffer, _, _, _| {
|
||||
system(command_buffer);
|
||||
});
|
||||
self.add_system_to_stage(stage::UPDATE, built_system);
|
||||
|
|
|
@ -164,8 +164,8 @@ impl<T> AssetStorage<T> {
|
|||
self.assets.get_mut(&handle.id)
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item=(Handle<T>, &T)> {
|
||||
self.assets.iter().map(|(k,v)| (Handle::new(*k), v))
|
||||
pub fn iter(&self) -> impl Iterator<Item = (Handle<T>, &T)> {
|
||||
self.assets.iter().map(|(k, v)| (Handle::new(*k), v))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,10 +160,7 @@ impl<'a> CommandBufferBuilder<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_children(
|
||||
&mut self,
|
||||
build_children: impl Fn(&mut Self) -> &mut Self,
|
||||
) -> &mut Self {
|
||||
pub fn add_children(&mut self, build_children: impl Fn(&mut Self) -> &mut Self) -> &mut Self {
|
||||
self.parent_entity = self.current_entity;
|
||||
self.current_entity = None;
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
use crate::{
|
||||
pipeline::PipelineDescriptor,
|
||||
renderer::{RenderPass, Renderer},
|
||||
};
|
||||
use crate::{pass::RenderPass, pipeline::PipelineDescriptor, renderer_2::RenderContext};
|
||||
use bevy_asset::Handle;
|
||||
use legion::prelude::{Resources, World};
|
||||
|
||||
|
@ -18,7 +15,7 @@ pub trait DrawTarget {
|
|||
&mut self,
|
||||
_world: &World,
|
||||
_resources: &Resources,
|
||||
_renderer: &mut dyn Renderer,
|
||||
_render_context: &mut dyn RenderContext,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
_pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
pass::RenderPass,
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{resource_name, AssetBatchers, RenderResourceAssignments},
|
||||
renderer::{RenderPass, Renderer},
|
||||
renderer_2::RenderContext,
|
||||
Renderable,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
|
@ -64,13 +65,13 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
&mut self,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
render_context: &mut dyn RenderContext,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let mut asset_batches = resources.get_mut::<AssetBatchers>().unwrap();
|
||||
let asset_batches = resources.get::<AssetBatchers>().unwrap();
|
||||
|
||||
let mut global_render_resource_assignments =
|
||||
let global_render_resource_assignments =
|
||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||
|
||||
log::trace!(
|
||||
|
@ -79,19 +80,18 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
pipeline_descriptor.name,
|
||||
);
|
||||
log::trace!("setting up global bind groups");
|
||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||
render_context.setup_bind_groups(pipeline_descriptor, &global_render_resource_assignments);
|
||||
|
||||
for batch in asset_batches.get_batches_mut() {
|
||||
for batch in asset_batches.get_batches() {
|
||||
log::trace!(
|
||||
"setting up batch bind groups: {:?}",
|
||||
batch.render_resource_assignments.id
|
||||
);
|
||||
log::trace!("{:#?}", batch);
|
||||
renderer.setup_bind_groups(&mut batch.render_resource_assignments, pipeline_descriptor);
|
||||
render_context
|
||||
.setup_bind_groups(pipeline_descriptor, &batch.render_resource_assignments);
|
||||
for batched_entity in batch.entities.iter() {
|
||||
let renderable = world
|
||||
.get_component::<Renderable>(*batched_entity)
|
||||
.unwrap();
|
||||
let renderable = world.get_component::<Renderable>(*batched_entity).unwrap();
|
||||
if !renderable.is_visible || renderable.is_instanced {
|
||||
continue;
|
||||
}
|
||||
|
@ -101,9 +101,9 @@ impl DrawTarget for AssignedBatchesDrawTarget {
|
|||
batched_entity,
|
||||
batch.render_resource_assignments.id
|
||||
);
|
||||
renderer.setup_bind_groups(
|
||||
&renderable.render_resource_assignments,
|
||||
render_context.setup_bind_groups(
|
||||
pipeline_descriptor,
|
||||
&renderable.render_resource_assignments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,11 +4,12 @@ use legion::prelude::*;
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
mesh::Mesh,
|
||||
pipeline::{PipelineDescriptor, PipelineAssignments},
|
||||
pass::RenderPass,
|
||||
pipeline::{PipelineAssignments, PipelineDescriptor},
|
||||
render_resource::{
|
||||
resource_name, EntityRenderResourceAssignments, RenderResourceAssignments, ResourceInfo,
|
||||
},
|
||||
renderer::{RenderPass, Renderer},
|
||||
renderer_2::RenderContext,
|
||||
Renderable,
|
||||
};
|
||||
|
||||
|
@ -48,15 +49,18 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
}
|
||||
|
||||
let mesh = *world.get_component::<Handle<Mesh>>(*entity).unwrap();
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
let render_context = render_pass.get_render_context();
|
||||
let render_resources = render_context.resources();
|
||||
if current_mesh_handle != Some(mesh) {
|
||||
if let Some(vertex_buffer_resource) =
|
||||
render_resources.get_mesh_vertices_resource(mesh)
|
||||
{
|
||||
let index_buffer_resource =
|
||||
render_resources.get_mesh_indices_resource(mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
match render_resources
|
||||
.get_resource_info(index_buffer_resource)
|
||||
.unwrap()
|
||||
{
|
||||
ResourceInfo::Buffer(buffer_info) => {
|
||||
current_mesh_index_len = (buffer_info.size / 2) as u32
|
||||
}
|
||||
|
@ -80,19 +84,18 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
&mut self,
|
||||
world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
render_context: &mut dyn RenderContext,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let pipeline_assignments = resources.get::<PipelineAssignments>().unwrap();
|
||||
let entity_render_resource_assignments =
|
||||
resources.get::<EntityRenderResourceAssignments>().unwrap();
|
||||
let assigned_render_resource_assignments = pipeline_assignments
|
||||
.assignments
|
||||
.get(&pipeline_handle);
|
||||
let mut global_render_resource_assignments =
|
||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||
let assigned_render_resource_assignments =
|
||||
pipeline_assignments.assignments.get(&pipeline_handle);
|
||||
let global_render_resource_assignments =
|
||||
resources.get::<RenderResourceAssignments>().unwrap();
|
||||
render_context.setup_bind_groups(pipeline_descriptor, &global_render_resource_assignments);
|
||||
if let Some(assigned_render_resource_assignments) = assigned_render_resource_assignments {
|
||||
for assignment_id in assigned_render_resource_assignments.iter() {
|
||||
let entity = entity_render_resource_assignments
|
||||
|
@ -103,9 +106,9 @@ impl DrawTarget for AssignedMeshesDrawTarget {
|
|||
continue;
|
||||
}
|
||||
|
||||
renderer.setup_bind_groups(
|
||||
&renderable.render_resource_assignments,
|
||||
render_context.setup_bind_groups(
|
||||
pipeline_descriptor,
|
||||
&renderable.render_resource_assignments,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
mesh::Mesh,
|
||||
pass::RenderPass,
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{resource_name, ResourceInfo},
|
||||
renderer::RenderPass,
|
||||
Renderable,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
|
@ -28,15 +28,18 @@ impl DrawTarget for MeshesDrawTarget {
|
|||
continue;
|
||||
}
|
||||
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_resources = renderer.get_render_resources();
|
||||
let render_context = render_pass.get_render_context();
|
||||
let render_resources = render_context.resources();
|
||||
if current_mesh_handle != Some(*mesh) {
|
||||
if let Some(vertex_buffer_resource) =
|
||||
render_resources.get_mesh_vertices_resource(*mesh)
|
||||
{
|
||||
let index_buffer_resource =
|
||||
render_resources.get_mesh_indices_resource(*mesh).unwrap();
|
||||
match renderer.get_resource_info(index_buffer_resource).unwrap() {
|
||||
match render_resources
|
||||
.get_resource_info(index_buffer_resource)
|
||||
.unwrap()
|
||||
{
|
||||
ResourceInfo::Buffer(buffer_info) => {
|
||||
current_mesh_index_len = (buffer_info.size / 2) as u32
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::{
|
||||
draw_target::DrawTarget,
|
||||
mesh::{Mesh, MeshType},
|
||||
pass::RenderPass,
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
||||
ResourceInfo,
|
||||
},
|
||||
renderer::{RenderPass, Renderer},
|
||||
renderer_2::RenderContext,
|
||||
};
|
||||
use bevy_asset::{Asset, Handle};
|
||||
use legion::prelude::*;
|
||||
|
@ -38,11 +39,13 @@ impl DrawTarget for UiDrawTarget {
|
|||
};
|
||||
|
||||
let index_count = {
|
||||
let renderer = render_pass.get_renderer();
|
||||
let render_context = render_pass.get_render_context();
|
||||
if let Some(ResourceInfo::Buffer(BufferInfo {
|
||||
array_info: Some(array_info),
|
||||
..
|
||||
})) = renderer.get_resource_info(ui_instances_buffer)
|
||||
})) = render_context
|
||||
.resources()
|
||||
.get_resource_info(ui_instances_buffer)
|
||||
{
|
||||
Some(array_info.item_capacity)
|
||||
} else {
|
||||
|
@ -67,7 +70,7 @@ impl DrawTarget for UiDrawTarget {
|
|||
&mut self,
|
||||
_world: &World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
render_context: &mut dyn RenderContext,
|
||||
_pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
|
@ -79,14 +82,14 @@ impl DrawTarget for UiDrawTarget {
|
|||
let quad = Mesh::load(MeshType::Quad {
|
||||
size: glam::vec2(1.0, 1.0),
|
||||
});
|
||||
self.mesh_vertex_buffer = Some(renderer.create_buffer_with_data(
|
||||
self.mesh_vertex_buffer = Some(render_context.resources_mut().create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::VERTEX,
|
||||
..Default::default()
|
||||
},
|
||||
quad.vertices.as_bytes(),
|
||||
));
|
||||
self.mesh_index_buffer = Some(renderer.create_buffer_with_data(
|
||||
self.mesh_index_buffer = Some(render_context.resources_mut().create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::INDEX,
|
||||
..Default::default()
|
||||
|
@ -95,9 +98,9 @@ impl DrawTarget for UiDrawTarget {
|
|||
));
|
||||
self.mesh_index_length = quad.indices.len();
|
||||
|
||||
let mut global_render_resource_assignments =
|
||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||
renderer.setup_bind_groups(&mut global_render_resource_assignments, pipeline_descriptor);
|
||||
let global_render_resource_assignments =
|
||||
resources.get::<RenderResourceAssignments>().unwrap();
|
||||
render_context.setup_bind_groups(pipeline_descriptor, &global_render_resource_assignments);
|
||||
}
|
||||
fn get_name(&self) -> String {
|
||||
resource_name::draw_target::UI.to_string()
|
||||
|
|
|
@ -23,7 +23,6 @@ pub mod pass;
|
|||
pub mod pipeline;
|
||||
pub mod render_resource;
|
||||
mod renderable;
|
||||
pub mod renderer;
|
||||
pub mod texture;
|
||||
|
||||
pub use once_cell;
|
||||
|
@ -35,8 +34,8 @@ use self::{
|
|||
mesh::Mesh,
|
||||
pass::passes::ForwardPassBuilder,
|
||||
pipeline::{
|
||||
pipelines::ForwardPipelineBuilder, PipelineCompiler, PipelineDescriptor,
|
||||
PipelineAssignments, VertexBufferDescriptors,
|
||||
pipelines::ForwardPipelineBuilder, PipelineAssignments, PipelineCompiler,
|
||||
PipelineDescriptor, VertexBufferDescriptors,
|
||||
},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{
|
||||
|
@ -98,8 +97,14 @@ impl AppPlugin for RenderPlugin {
|
|||
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_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())
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::{render_resource::AssetBatchers, Vertex, Renderable};
|
||||
use bevy_asset::{Handle, Asset};
|
||||
use crate::{render_resource::AssetBatchers, Renderable, Vertex};
|
||||
use bevy_asset::{Asset, Handle};
|
||||
use glam::*;
|
||||
use legion::prelude::*;
|
||||
|
||||
|
@ -120,11 +120,12 @@ pub fn create_plane(size: f32) -> (Vec<Vertex>, Vec<u16>) {
|
|||
create_quad(vec2(size, size))
|
||||
}
|
||||
|
||||
|
||||
pub fn mesh_batcher_system() -> Box<dyn Schedulable> {
|
||||
SystemBuilder::new("mesh_batcher")
|
||||
.write_resource::<AssetBatchers>()
|
||||
.with_query(<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(changed::<Handle<Mesh>>()))
|
||||
.with_query(
|
||||
<(Read<Handle<Mesh>>, Read<Renderable>)>::query().filter(changed::<Handle<Mesh>>()),
|
||||
)
|
||||
.build(|_, world, asset_batchers, query| {
|
||||
for (entity, (mesh_handle, _renderable)) in query.iter_entities(world) {
|
||||
asset_batchers.set_entity_handle(entity, *mesh_handle);
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
mod ops;
|
||||
mod pass;
|
||||
pub mod passes;
|
||||
mod render_pass;
|
||||
|
||||
pub use ops::*;
|
||||
pub use pass::*;
|
||||
pub use render_pass::*;
|
||||
|
|
18
bevy_render/src/pass/render_pass.rs
Normal file
18
bevy_render/src/pass/render_pass.rs
Normal file
|
@ -0,0 +1,18 @@
|
|||
use crate::{
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{RenderResource, RenderResourceAssignments},
|
||||
renderer_2::RenderContext,
|
||||
};
|
||||
use std::ops::Range;
|
||||
|
||||
pub trait RenderPass {
|
||||
fn get_render_context(&self) -> &dyn RenderContext;
|
||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
|
||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||
fn set_render_resources(
|
||||
&mut self,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> Option<Range<u32>>;
|
||||
}
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
render_resource::{
|
||||
BufferInfo, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo,
|
||||
},
|
||||
renderer::Renderer,
|
||||
renderer_2::RenderContext,
|
||||
shader::{Shader, ShaderSource},
|
||||
Renderable,
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ impl PipelineCompiler {
|
|||
shader_storage: &AssetStorage<Shader>,
|
||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
pipeline_descriptor: &mut PipelineDescriptor,
|
||||
renderer: &dyn Renderer,
|
||||
render_context: &dyn RenderContext,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) {
|
||||
let vertex_spirv = shader_storage
|
||||
|
@ -61,7 +61,9 @@ impl PipelineCompiler {
|
|||
for binding in bind_group.bindings.iter_mut() {
|
||||
if let Some(render_resource) = render_resource_assignments.get(&binding.name) {
|
||||
if let Some(ResourceInfo::Buffer(BufferInfo { is_dynamic, .. })) =
|
||||
renderer.get_resource_info(render_resource)
|
||||
render_context
|
||||
.resources()
|
||||
.get_resource_info(render_resource)
|
||||
{
|
||||
if let BindType::Uniform {
|
||||
ref mut dynamic, ..
|
||||
|
@ -114,7 +116,7 @@ impl PipelineCompiler {
|
|||
&mut self,
|
||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
shader_storage: &mut AssetStorage<Shader>,
|
||||
renderer: &dyn Renderer,
|
||||
render_context: &dyn RenderContext,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> PipelineDescriptor {
|
||||
|
@ -141,7 +143,7 @@ impl PipelineCompiler {
|
|||
shader_storage,
|
||||
vertex_buffer_descriptors,
|
||||
&mut compiled_pipeline_descriptor,
|
||||
renderer,
|
||||
render_context,
|
||||
render_resource_assignments,
|
||||
);
|
||||
|
||||
|
@ -152,7 +154,7 @@ impl PipelineCompiler {
|
|||
&mut self,
|
||||
vertex_buffer_descriptors: &VertexBufferDescriptors,
|
||||
shader_pipeline_assignments: &mut PipelineAssignments,
|
||||
renderer: &dyn Renderer,
|
||||
render_context: &dyn RenderContext,
|
||||
pipeline_storage: &mut AssetStorage<PipelineDescriptor>,
|
||||
shader_storage: &mut AssetStorage<Shader>,
|
||||
pipelines: &[Handle<PipelineDescriptor>],
|
||||
|
@ -178,7 +180,7 @@ impl PipelineCompiler {
|
|||
let compiled_pipeline = self.compile_pipeline(
|
||||
vertex_buffer_descriptors,
|
||||
shader_storage,
|
||||
renderer,
|
||||
render_context,
|
||||
pipeline_descriptor,
|
||||
render_resource_assignments,
|
||||
);
|
||||
|
@ -238,13 +240,12 @@ impl PipelineAssignments {
|
|||
pub fn update_shader_assignments(
|
||||
world: &mut World,
|
||||
resources: &mut Resources,
|
||||
renderer: &dyn Renderer,
|
||||
render_context: &dyn RenderContext,
|
||||
) {
|
||||
// PERF: this seems like a lot of work for things that don't change that often.
|
||||
// lots of string + hashset allocations. sees uniform_resource_provider for more context
|
||||
{
|
||||
let mut shader_pipeline_assignments =
|
||||
resources.get_mut::<PipelineAssignments>().unwrap();
|
||||
let mut shader_pipeline_assignments = resources.get_mut::<PipelineAssignments>().unwrap();
|
||||
let mut pipeline_compiler = resources.get_mut::<PipelineCompiler>().unwrap();
|
||||
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
|
||||
let vertex_buffer_descriptors = resources.get::<VertexBufferDescriptors>().unwrap();
|
||||
|
@ -265,7 +266,7 @@ pub fn update_shader_assignments(
|
|||
pipeline_compiler.update_shader_assignments(
|
||||
&vertex_buffer_descriptors,
|
||||
&mut shader_pipeline_assignments,
|
||||
renderer,
|
||||
render_context,
|
||||
&mut pipeline_descriptor_storage,
|
||||
&mut shader_storage,
|
||||
&renderable.pipelines,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
pass::PassDescriptor,
|
||||
pipeline::{PipelineCompiler, PipelineDescriptor},
|
||||
render_resource::ResourceProvider,
|
||||
renderer::Renderer,
|
||||
renderer_2::RenderContext,
|
||||
shader::Shader,
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
|
@ -51,7 +51,7 @@ impl RenderGraph {
|
|||
&mut self,
|
||||
world: &mut World,
|
||||
resources: &Resources,
|
||||
renderer: &mut dyn Renderer,
|
||||
render_context: &mut dyn RenderContext,
|
||||
) {
|
||||
let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap();
|
||||
let pipeline_compiler = resources.get::<PipelineCompiler>().unwrap();
|
||||
|
@ -70,7 +70,7 @@ impl RenderGraph {
|
|||
pipeline_storage.get_mut(compiled_pipeline_handle).unwrap();
|
||||
|
||||
// create wgpu pipeline if it doesn't exist
|
||||
renderer.setup_render_pipeline(
|
||||
render_context.create_render_pipeline(
|
||||
*compiled_pipeline_handle,
|
||||
compiled_pipeline_descriptor,
|
||||
&shader_storage,
|
||||
|
@ -84,7 +84,7 @@ impl RenderGraph {
|
|||
draw_target.setup(
|
||||
world,
|
||||
resources,
|
||||
renderer,
|
||||
render_context,
|
||||
*compiled_pipeline_handle,
|
||||
compiled_pipeline_descriptor,
|
||||
);
|
||||
|
|
|
@ -40,7 +40,11 @@ impl<'a, 'b, 'c> RenderGraphBuilder<'a, 'b, 'c> {
|
|||
self
|
||||
}
|
||||
|
||||
pub fn add_default_pipeline(&mut self, name: &str, build: impl Fn(&mut PipelineBuilder)) -> &mut Self {
|
||||
pub fn add_default_pipeline(
|
||||
&mut self,
|
||||
name: &str,
|
||||
build: impl Fn(&mut PipelineBuilder),
|
||||
) -> &mut Self {
|
||||
if let Some(ref pass) = self.current_pass {
|
||||
let mut builder = PipelineBuilder::new(name, &mut self.shaders);
|
||||
build(&mut builder);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -26,10 +26,14 @@ pub struct AssetResources {
|
|||
impl AssetResources {
|
||||
pub fn consume(&mut self, render_resources: AssetResources) {
|
||||
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
||||
self.texture_to_resource.extend(render_resources.texture_to_resource);
|
||||
self.texture_to_sampler_resource.extend(render_resources.texture_to_sampler_resource);
|
||||
self.mesh_to_vertices_resource.extend(render_resources.mesh_to_vertices_resource);
|
||||
self.mesh_to_indices_resource.extend(render_resources.mesh_to_indices_resource);
|
||||
self.texture_to_resource
|
||||
.extend(render_resources.texture_to_resource);
|
||||
self.texture_to_sampler_resource
|
||||
.extend(render_resources.texture_to_sampler_resource);
|
||||
self.mesh_to_vertices_resource
|
||||
.extend(render_resources.mesh_to_vertices_resource);
|
||||
self.mesh_to_indices_resource
|
||||
.extend(render_resources.mesh_to_indices_resource);
|
||||
}
|
||||
|
||||
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
||||
|
|
|
@ -199,8 +199,7 @@ mod tests {
|
|||
assert_ne!(different_set_id, None);
|
||||
assert_ne!(different_set_id, set_id);
|
||||
|
||||
let equal_set_id =
|
||||
equal_assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
let equal_set_id = equal_assignments.update_render_resource_set_id(&bind_group_descriptor);
|
||||
assert_ne!(equal_set_id, None);
|
||||
assert_eq!(equal_set_id, set_id);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{renderer_2::RenderContext};
|
||||
use crate::renderer_2::RenderContext;
|
||||
use legion::prelude::*;
|
||||
|
||||
pub trait ResourceProvider {
|
||||
|
@ -10,7 +10,12 @@ pub trait ResourceProvider {
|
|||
) {
|
||||
}
|
||||
|
||||
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,
|
||||
) {
|
||||
}
|
||||
|
||||
// TODO: remove this
|
||||
|
@ -23,8 +28,11 @@ pub trait ResourceProvider {
|
|||
}
|
||||
|
||||
/// Runs after resources have been created on the gpu. In general systems here write gpu-related resources back to entities in this step
|
||||
fn post_update(&mut self, _render_context: &dyn RenderContext, _world: &mut World, _resources: &Resources) {
|
||||
|
||||
fn post_update(
|
||||
&mut self,
|
||||
_render_context: &dyn RenderContext,
|
||||
_world: &mut World,
|
||||
_resources: &Resources,
|
||||
) {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::{
|
||||
render_resource::{RenderResourceAssignments, ResourceProvider},
|
||||
texture::TextureDescriptor, renderer_2::RenderContext,
|
||||
renderer_2::RenderContext,
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
use bevy_window::Windows;
|
||||
use legion::prelude::*;
|
||||
|
@ -24,7 +25,12 @@ impl FrameTextureResourceProvider {
|
|||
}
|
||||
|
||||
impl ResourceProvider for FrameTextureResourceProvider {
|
||||
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,
|
||||
) {
|
||||
let windows = resources.get::<Windows>().unwrap();
|
||||
let window = windows.get_primary().unwrap();
|
||||
|
||||
|
|
|
@ -738,16 +738,8 @@ where
|
|||
self.setup_buffer_arrays(render_context);
|
||||
|
||||
let staging_buffer_size = self.update_staging_buffer_offsets();
|
||||
self.setup_uniforms_texture_resources(
|
||||
world,
|
||||
resources,
|
||||
render_context,
|
||||
);
|
||||
self.setup_handles_texture_resources(
|
||||
world,
|
||||
resources,
|
||||
render_context,
|
||||
);
|
||||
self.setup_uniforms_texture_resources(world, resources, render_context);
|
||||
self.setup_handles_texture_resources(world, resources, render_context);
|
||||
// self.setup_batched_texture_resources(world, resources, renderer, staging_buffer);
|
||||
if staging_buffer_size == 0 {
|
||||
let mut staging_buffer: [u8; 0] = [];
|
||||
|
@ -771,11 +763,7 @@ where
|
|||
..Default::default()
|
||||
},
|
||||
&mut |staging_buffer, render_resources| {
|
||||
self.setup_uniforms_buffer_resources(
|
||||
world,
|
||||
render_resources,
|
||||
staging_buffer,
|
||||
);
|
||||
self.setup_uniforms_buffer_resources(world, render_resources, staging_buffer);
|
||||
self.setup_handles_buffer_resources(
|
||||
world,
|
||||
resources,
|
||||
|
|
|
@ -23,9 +23,7 @@ impl Default for Renderable {
|
|||
fn default() -> Self {
|
||||
Renderable {
|
||||
is_visible: true,
|
||||
pipelines: vec![
|
||||
Handle::default(),
|
||||
],
|
||||
pipelines: vec![Handle::default()],
|
||||
render_resource_assignments: RenderResourceAssignments::default(),
|
||||
is_instanced: false,
|
||||
}
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
use crate::{
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
BufferInfo, RenderResource, RenderResourceAssignments, AssetResources, ResourceInfo,
|
||||
},
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, TextureDescriptor},
|
||||
};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use legion::prelude::*;
|
||||
use std::ops::Range;
|
||||
|
||||
pub trait Renderer {
|
||||
fn update(&mut self, world: &mut World, resources: &mut Resources);
|
||||
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource;
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource;
|
||||
fn create_texture(
|
||||
&mut self,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: Option<&[u8]>,
|
||||
) -> RenderResource;
|
||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource;
|
||||
fn create_buffer_mapped(
|
||||
&mut self,
|
||||
buffer_info: BufferInfo,
|
||||
func: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
|
||||
) -> RenderResource;
|
||||
fn remove_buffer(&mut self, resource: RenderResource);
|
||||
fn remove_texture(&mut self, resource: RenderResource);
|
||||
fn remove_sampler(&mut self, resource: RenderResource);
|
||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo>;
|
||||
fn get_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo>;
|
||||
fn copy_buffer_to_buffer(
|
||||
&mut self,
|
||||
source_buffer: RenderResource,
|
||||
source_offset: u64,
|
||||
destination_buffer: RenderResource,
|
||||
destination_offset: u64,
|
||||
size: u64,
|
||||
);
|
||||
fn get_render_resources(&self) -> &AssetResources;
|
||||
fn get_render_resources_mut(&mut self) -> &mut AssetResources;
|
||||
fn setup_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &mut PipelineDescriptor,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
);
|
||||
fn setup_bind_groups(
|
||||
&mut self,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
);
|
||||
}
|
||||
|
||||
pub trait RenderPass {
|
||||
fn get_renderer(&self) -> &dyn Renderer;
|
||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor;
|
||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64);
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64);
|
||||
fn draw_indexed(&mut self, indices: Range<u32>, base_vertex: i32, instances: Range<u32>);
|
||||
fn set_render_resources(
|
||||
&mut self,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> Option<Range<u32>>;
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
use crate::{render_resource::RenderResource, texture::TextureDescriptor};
|
||||
use super::RenderResourceContext;
|
||||
use crate::{
|
||||
pipeline::{BindGroupDescriptor, PipelineDescriptor},
|
||||
render_resource::{RenderResource, RenderResourceAssignments, RenderResourceSetId},
|
||||
shader::Shader,
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
|
||||
pub trait RenderContext {
|
||||
// fn setup_render_pipeline(
|
||||
|
@ -38,4 +44,25 @@ pub trait RenderContext {
|
|||
// destination_offset: u64,
|
||||
// size: u64,
|
||||
// );
|
||||
fn create_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> Option<RenderResourceSetId>;
|
||||
fn create_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &mut PipelineDescriptor,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
);
|
||||
fn setup_bind_groups(
|
||||
&mut self,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) {
|
||||
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
self.create_bind_group(bind_group, render_resource_assignments);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::{
|
||||
render_resource::{
|
||||
BufferInfo, RenderResource, AssetResources, ResourceInfo,
|
||||
},
|
||||
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
|
||||
mesh::Mesh,
|
||||
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
|
||||
pub struct GlobalRenderResourceContext {
|
||||
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
|
||||
|
@ -13,10 +13,7 @@ pub struct GlobalRenderResourceContext {
|
|||
// TODO: Rename to RenderResources after cleaning up AssetResources rename
|
||||
pub trait RenderResourceContext {
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource;
|
||||
fn create_texture(
|
||||
&mut self,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
) -> RenderResource;
|
||||
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource;
|
||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource;
|
||||
fn create_buffer_mapped(
|
||||
&mut self,
|
||||
|
@ -24,6 +21,11 @@ pub trait RenderResourceContext {
|
|||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
|
||||
) -> RenderResource;
|
||||
fn create_buffer_with_data(&mut 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);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::{
|
||||
color::ColorSource,
|
||||
pipeline::{BindType, VertexBufferDescriptor},
|
||||
render_resource::AssetBatchers,
|
||||
texture::Texture,
|
||||
Renderable, render_resource::AssetBatchers,
|
||||
Renderable,
|
||||
};
|
||||
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
|
@ -23,15 +24,15 @@ pub fn shader_def_system<T>() -> Box<dyn Schedulable>
|
|||
where
|
||||
T: AsUniforms + Send + Sync + 'static,
|
||||
{
|
||||
SystemBuilder::new(format!(
|
||||
"shader_def::{}",
|
||||
std::any::type_name::<T>()
|
||||
))
|
||||
SystemBuilder::new(format!("shader_def::{}", std::any::type_name::<T>()))
|
||||
.with_query(<(Read<T>, Write<Renderable>)>::query())
|
||||
.build(|_, world, _, query| {
|
||||
for (uniforms, mut renderable) in query.iter_mut(world) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -55,7 +56,10 @@ where
|
|||
|
||||
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)
|
||||
renderable
|
||||
.render_resource_assignments
|
||||
.shader_defs
|
||||
.extend(shader_defs)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
pub mod renderer_2;
|
||||
mod wgpu_render_pass;
|
||||
mod wgpu_renderer;
|
||||
mod wgpu_resources;
|
||||
mod wgpu_type_converter;
|
||||
pub mod renderer_2;
|
||||
|
||||
pub use wgpu_render_pass::*;
|
||||
pub use wgpu_renderer::*;
|
||||
pub use wgpu_resources::*;
|
||||
|
||||
use bevy_app::{AppBuilder, AppPlugin, Events};
|
||||
use bevy_render::{renderer::Renderer, RENDER_STAGE};
|
||||
use bevy_render::RENDER_STAGE;
|
||||
use bevy_window::{WindowCreated, WindowResized};
|
||||
use legion::prelude::*;
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
mod systems;
|
||||
mod wgpu_render_context;
|
||||
mod wgpu_render_resource_context;
|
||||
mod wgpu_transactional_render_resource_context;
|
||||
mod systems;
|
||||
|
||||
pub use systems::*;
|
||||
pub use wgpu_render_context::*;
|
||||
pub use wgpu_render_resource_context::*;
|
||||
pub use wgpu_transactional_render_resource_context::*;
|
||||
pub use systems::*;
|
|
@ -1,8 +1,9 @@
|
|||
use bevy_asset::AssetStorage;
|
||||
use bevy_render::{
|
||||
pipeline::{PipelineCompiler, PipelineDescriptor, PipelineAssignments},
|
||||
pipeline::{PipelineAssignments, PipelineCompiler, PipelineDescriptor},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{EntityRenderResourceAssignments, RenderResourceAssignments}, Renderable,
|
||||
render_resource::{EntityRenderResourceAssignments, RenderResourceAssignments},
|
||||
Renderable,
|
||||
};
|
||||
use legion::prelude::*;
|
||||
|
||||
|
@ -29,28 +30,36 @@ pub fn render_resource_sets_system() -> Box<dyn Schedulable> {
|
|||
_| {
|
||||
// PERF: consider doing a par-iter over all renderable components so this can be parallelized
|
||||
for handle in render_graph.pipeline_descriptors.iter() {
|
||||
for compiled_pipeline_handle in pipeline_compiler.iter_compiled_pipelines(*handle).unwrap() {
|
||||
if let Some(compiled_pipeline_assignments) =
|
||||
pipeline_assignments.assignments.get(compiled_pipeline_handle)
|
||||
for compiled_pipeline_handle in
|
||||
pipeline_compiler.iter_compiled_pipelines(*handle).unwrap()
|
||||
{
|
||||
let compiled_pipeline = pipelines.get(compiled_pipeline_handle).unwrap();
|
||||
if let Some(compiled_pipeline_assignments) = pipeline_assignments
|
||||
.assignments
|
||||
.get(compiled_pipeline_handle)
|
||||
{
|
||||
let compiled_pipeline =
|
||||
pipelines.get(compiled_pipeline_handle).unwrap();
|
||||
let pipeline_layout = compiled_pipeline.get_layout().unwrap();
|
||||
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
global_render_resource_assignments.update_render_resource_set_id(bind_group);
|
||||
global_render_resource_assignments
|
||||
.update_render_resource_set_id(bind_group);
|
||||
}
|
||||
|
||||
for assignment_id in compiled_pipeline_assignments.iter() {
|
||||
let entity = entity_render_resource_assignments
|
||||
.get(*assignment_id)
|
||||
.unwrap();
|
||||
let mut renderable = world.get_component_mut::<Renderable>(*entity).unwrap();
|
||||
let mut renderable =
|
||||
world.get_component_mut::<Renderable>(*entity).unwrap();
|
||||
if !renderable.is_visible || renderable.is_instanced {
|
||||
continue;
|
||||
}
|
||||
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
renderable.render_resource_assignments.update_render_resource_set_id(bind_group);
|
||||
renderable
|
||||
.render_resource_assignments
|
||||
.update_render_resource_set_id(bind_group);
|
||||
// TODO: also setup bind groups here if possible
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,13 @@
|
|||
use super::WgpuRenderResourceContextTrait;
|
||||
use crate::wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use bevy_render::{
|
||||
render_resource::RenderResource,
|
||||
pipeline::{BindGroupDescriptor, BindType, PipelineDescriptor},
|
||||
render_resource::{
|
||||
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer_2::{RenderContext, RenderResourceContext},
|
||||
shader::Shader,
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
@ -122,4 +128,241 @@ where
|
|||
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext {
|
||||
&mut self.render_resources
|
||||
}
|
||||
fn create_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> Option<RenderResourceSetId> {
|
||||
if let Some((render_resource_set_id, _indices)) =
|
||||
render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id)
|
||||
{
|
||||
if let None = self
|
||||
.render_resources
|
||||
.get_bind_group(bind_group_descriptor.id, *render_resource_set_id)
|
||||
{
|
||||
log::trace!(
|
||||
"start creating bind group for RenderResourceSet {:?}",
|
||||
render_resource_set_id
|
||||
);
|
||||
let wgpu_bind_group = {
|
||||
let bindings = bind_group_descriptor
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| {
|
||||
if let Some(resource) = render_resource_assignments.get(&binding.name) {
|
||||
let resource_info =
|
||||
self.resources().get_resource_info(resource).unwrap();
|
||||
log::trace!(
|
||||
"found binding {} ({}) resource: {:?} {:?}",
|
||||
binding.index,
|
||||
binding.name,
|
||||
resource,
|
||||
resource_info
|
||||
);
|
||||
wgpu::Binding {
|
||||
binding: binding.index,
|
||||
resource: match &binding.bind_type {
|
||||
BindType::SampledTexture { .. } => {
|
||||
if let ResourceInfo::Texture = resource_info {
|
||||
let texture = self
|
||||
.render_resources
|
||||
.get_texture(resource)
|
||||
.unwrap();
|
||||
wgpu::BindingResource::TextureView(texture)
|
||||
} else {
|
||||
panic!("expected a Texture resource");
|
||||
}
|
||||
}
|
||||
BindType::Sampler { .. } => {
|
||||
if let ResourceInfo::Sampler = resource_info {
|
||||
let sampler = self
|
||||
.render_resources
|
||||
.get_sampler(resource)
|
||||
.unwrap();
|
||||
wgpu::BindingResource::Sampler(sampler)
|
||||
} else {
|
||||
panic!("expected a Sampler resource");
|
||||
}
|
||||
}
|
||||
BindType::Uniform { .. } => {
|
||||
if let ResourceInfo::Buffer(buffer_info) = resource_info
|
||||
{
|
||||
let buffer = self
|
||||
.render_resources
|
||||
.get_buffer(resource)
|
||||
.unwrap();
|
||||
wgpu::BindingResource::Buffer {
|
||||
buffer,
|
||||
range: 0..buffer_info.size as u64,
|
||||
}
|
||||
} else {
|
||||
panic!("expected a Buffer resource");
|
||||
}
|
||||
}
|
||||
_ => panic!("unsupported bind type"),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
panic!(
|
||||
"No resource assigned to uniform \"{}\" for RenderResourceAssignments {:?}",
|
||||
binding.name,
|
||||
render_resource_assignments.id
|
||||
);
|
||||
}
|
||||
})
|
||||
.collect::<Vec<wgpu::Binding>>();
|
||||
let bind_group_layout = self
|
||||
.render_resources
|
||||
.get_bind_group_layout(bind_group_descriptor.id)
|
||||
.unwrap();
|
||||
let wgpu_bind_group_descriptor = wgpu::BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: bind_group_layout,
|
||||
bindings: bindings.as_slice(),
|
||||
};
|
||||
self.render_resources
|
||||
.create_bind_group(*render_resource_set_id, &wgpu_bind_group_descriptor)
|
||||
};
|
||||
self.render_resources.set_bind_group(
|
||||
bind_group_descriptor.id,
|
||||
*render_resource_set_id,
|
||||
wgpu_bind_group,
|
||||
);
|
||||
return Some(*render_resource_set_id);
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
fn create_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &mut PipelineDescriptor,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
) {
|
||||
if let Some(_) = self.render_resources.get_pipeline(pipeline_handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
let layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in layout.bind_groups.iter() {
|
||||
if let None = self.render_resources.get_bind_group_layout(bind_group.id) {
|
||||
let bind_group_layout_binding = bind_group
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| wgpu::BindGroupLayoutEntry {
|
||||
binding: binding.index,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: (&binding.bind_type).wgpu_into(),
|
||||
})
|
||||
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
||||
self.render_resources.create_bind_group_layout(
|
||||
bind_group.id,
|
||||
&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: bind_group_layout_binding.as_slice(),
|
||||
label: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// setup and collect bind group layouts
|
||||
let bind_group_layouts = layout
|
||||
.bind_groups
|
||||
.iter()
|
||||
.map(|bind_group| {
|
||||
self.render_resources
|
||||
.get_bind_group_layout(bind_group.id)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
||||
|
||||
let pipeline_layout = self
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||
});
|
||||
|
||||
let owned_vertex_buffer_descriptors = layout
|
||||
.vertex_buffer_descriptors
|
||||
.iter()
|
||||
.map(|v| v.wgpu_into())
|
||||
.collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
|
||||
|
||||
let color_states = pipeline_descriptor
|
||||
.color_states
|
||||
.iter()
|
||||
.map(|c| c.wgpu_into())
|
||||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
||||
|
||||
if let None = self
|
||||
.render_resources
|
||||
.get_shader_module(pipeline_descriptor.shader_stages.vertex)
|
||||
{
|
||||
self.render_resources
|
||||
.create_shader_module(pipeline_descriptor.shader_stages.vertex, shader_storage);
|
||||
}
|
||||
|
||||
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
||||
if let None = self.render_resources.get_shader_module(fragment_handle) {
|
||||
self.render_resources
|
||||
.create_shader_module(fragment_handle, shader_storage);
|
||||
}
|
||||
};
|
||||
let wgpu_pipeline = {
|
||||
let vertex_shader_module = self
|
||||
.render_resources
|
||||
.get_shader_module(pipeline_descriptor.shader_stages.vertex)
|
||||
.unwrap();
|
||||
|
||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
||||
Some(fragment_handle) => Some(
|
||||
self.render_resources
|
||||
.get_shader_module(fragment_handle)
|
||||
.unwrap(),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||
layout: &pipeline_layout,
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: &vertex_shader_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: match pipeline_descriptor.shader_stages.fragment {
|
||||
Some(_) => Some(wgpu::ProgrammableStageDescriptor {
|
||||
entry_point: "main",
|
||||
module: fragment_shader_module.as_ref().unwrap(),
|
||||
}),
|
||||
None => None,
|
||||
},
|
||||
rasterization_state: pipeline_descriptor
|
||||
.rasterization_state
|
||||
.as_ref()
|
||||
.map(|r| r.wgpu_into()),
|
||||
primitive_topology: pipeline_descriptor.primitive_topology.wgpu_into(),
|
||||
color_states: &color_states,
|
||||
depth_stencil_state: pipeline_descriptor
|
||||
.depth_stencil_state
|
||||
.as_ref()
|
||||
.map(|d| d.wgpu_into()),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: pipeline_descriptor.index_format.wgpu_into(),
|
||||
vertex_buffers: &owned_vertex_buffer_descriptors
|
||||
.iter()
|
||||
.map(|v| v.into())
|
||||
.collect::<Vec<wgpu::VertexBufferDescriptor>>(),
|
||||
},
|
||||
sample_count: pipeline_descriptor.sample_count,
|
||||
sample_mask: pipeline_descriptor.sample_mask,
|
||||
alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled,
|
||||
};
|
||||
|
||||
self.render_resources
|
||||
.create_render_pipeline(&render_pipeline_descriptor)
|
||||
};
|
||||
self.render_resources
|
||||
.set_render_pipeline(pipeline_handle, wgpu_pipeline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
use crate::WgpuResources;
|
||||
|
||||
use bevy_asset::Handle;
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use bevy_render::{
|
||||
mesh::Mesh,
|
||||
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
|
||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||
render_resource::{
|
||||
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer_2::RenderResourceContext,
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
|
@ -16,13 +20,52 @@ pub struct WgpuRenderResourceContext {
|
|||
|
||||
// TODO: make this name not terrible
|
||||
pub trait WgpuRenderResourceContextTrait {
|
||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer>;
|
||||
fn create_texture_with_data(
|
||||
&mut self,
|
||||
command_encoder: &mut wgpu::CommandEncoder,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: &[u8],
|
||||
) -> RenderResource;
|
||||
|
||||
fn create_bind_group(
|
||||
&self,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
descriptor: &wgpu::BindGroupDescriptor,
|
||||
) -> wgpu::BindGroup;
|
||||
fn set_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
bind_group: wgpu::BindGroup,
|
||||
);
|
||||
fn create_bind_group_layout(
|
||||
&mut self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
||||
);
|
||||
fn create_render_pipeline(
|
||||
&self,
|
||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
||||
) -> wgpu::RenderPipeline;
|
||||
fn set_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
);
|
||||
fn get_bind_group(
|
||||
&self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
) -> Option<&wgpu::BindGroup>;
|
||||
fn get_bind_group_layout(
|
||||
&self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
) -> Option<&wgpu::BindGroupLayout>;
|
||||
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer>;
|
||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView>;
|
||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler>;
|
||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline>;
|
||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule>;
|
||||
}
|
||||
|
||||
impl WgpuRenderResourceContextTrait for WgpuRenderResourceContext {
|
||||
|
@ -35,14 +78,82 @@ impl WgpuRenderResourceContextTrait for WgpuRenderResourceContext {
|
|||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: &[u8],
|
||||
) -> RenderResource {
|
||||
self.wgpu_resources
|
||||
.create_texture_with_data(
|
||||
self.wgpu_resources.create_texture_with_data(
|
||||
&self.device,
|
||||
command_encoder,
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
}
|
||||
fn create_bind_group(
|
||||
&self,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
descriptor: &wgpu::BindGroupDescriptor,
|
||||
) -> wgpu::BindGroup {
|
||||
self.wgpu_resources
|
||||
.create_bind_group(&self.device, render_resource_set_id, descriptor)
|
||||
}
|
||||
fn create_bind_group_layout(
|
||||
&mut self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
||||
) {
|
||||
self.wgpu_resources
|
||||
.create_bind_group_layout(&self.device, bind_group_id, descriptor);
|
||||
}
|
||||
fn create_render_pipeline(
|
||||
&self,
|
||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
||||
) -> wgpu::RenderPipeline {
|
||||
self.wgpu_resources
|
||||
.create_render_pipeline(&self.device, descriptor)
|
||||
}
|
||||
fn get_bind_group(
|
||||
&self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
) -> Option<&wgpu::BindGroup> {
|
||||
self.wgpu_resources
|
||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id)
|
||||
}
|
||||
fn get_bind_group_layout(
|
||||
&self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
) -> Option<&wgpu::BindGroupLayout> {
|
||||
self.wgpu_resources.bind_group_layouts.get(&bind_group_id)
|
||||
}
|
||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView> {
|
||||
self.wgpu_resources.textures.get(&render_resource)
|
||||
}
|
||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler> {
|
||||
self.wgpu_resources.samplers.get(&render_resource)
|
||||
}
|
||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline> {
|
||||
self.wgpu_resources.render_pipelines.get(&pipeline)
|
||||
}
|
||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule> {
|
||||
self.wgpu_resources.shader_modules.get(&shader)
|
||||
}
|
||||
fn set_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
bind_group: wgpu::BindGroup,
|
||||
) {
|
||||
self.wgpu_resources.set_bind_group(
|
||||
bind_group_descriptor_id,
|
||||
render_resource_set_id,
|
||||
bind_group,
|
||||
);
|
||||
}
|
||||
fn set_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
) {
|
||||
self.wgpu_resources
|
||||
.set_render_pipeline(pipeline_handle, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
impl WgpuRenderResourceContext {
|
||||
|
@ -130,4 +241,17 @@ impl RenderResourceContext for WgpuRenderResourceContext {
|
|||
fn asset_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self.wgpu_resources.asset_resources
|
||||
}
|
||||
fn create_shader_module(
|
||||
&mut self,
|
||||
shader_handle: Handle<Shader>,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
) {
|
||||
if self.get_shader_module(shader_handle).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let shader = shader_storage.get(&shader_handle).unwrap();
|
||||
self.wgpu_resources
|
||||
.create_shader_module(&self.device, shader_handle, shader);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,18 @@
|
|||
use crate::WgpuResources;
|
||||
|
||||
use super::WgpuRenderResourceContextTrait;
|
||||
use bevy_asset::Handle;
|
||||
use bevy_render::{
|
||||
mesh::Mesh,
|
||||
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
|
||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||
render_resource::{
|
||||
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer_2::RenderResourceContext,
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use super::WgpuRenderResourceContextTrait;
|
||||
|
||||
pub struct WgpuTransactionalRenderResourceContext<'a> {
|
||||
pub device: Arc<wgpu::Device>,
|
||||
|
@ -33,14 +37,108 @@ impl<'a> WgpuRenderResourceContextTrait for WgpuTransactionalRenderResourceConte
|
|||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: &[u8],
|
||||
) -> RenderResource {
|
||||
self.local_resources
|
||||
.create_texture_with_data(
|
||||
self.local_resources.create_texture_with_data(
|
||||
&self.device,
|
||||
command_encoder,
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
}
|
||||
fn create_bind_group(
|
||||
&self,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
descriptor: &wgpu::BindGroupDescriptor,
|
||||
) -> wgpu::BindGroup {
|
||||
self.local_resources
|
||||
.create_bind_group(&self.device, render_resource_set_id, descriptor)
|
||||
}
|
||||
fn create_bind_group_layout(
|
||||
&mut self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
||||
) {
|
||||
self.local_resources
|
||||
.create_bind_group_layout(&self.device, bind_group_id, descriptor);
|
||||
}
|
||||
fn create_render_pipeline(
|
||||
&self,
|
||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
||||
) -> wgpu::RenderPipeline {
|
||||
self.local_resources
|
||||
.create_render_pipeline(&self.device, descriptor)
|
||||
}
|
||||
fn get_bind_group(
|
||||
&self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
) -> Option<&wgpu::BindGroup> {
|
||||
let local = self
|
||||
.local_resources
|
||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources
|
||||
.get_bind_group(bind_group_descriptor_id, render_resource_set_id)
|
||||
}
|
||||
fn get_bind_group_layout(
|
||||
&self,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
) -> Option<&wgpu::BindGroupLayout> {
|
||||
let local = self.local_resources.bind_group_layouts.get(&bind_group_id);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources.bind_group_layouts.get(&bind_group_id)
|
||||
}
|
||||
fn get_texture(&self, render_resource: RenderResource) -> Option<&wgpu::TextureView> {
|
||||
let local = self.local_resources.textures.get(&render_resource);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources.textures.get(&render_resource)
|
||||
}
|
||||
fn get_sampler(&self, render_resource: RenderResource) -> Option<&wgpu::Sampler> {
|
||||
let local = self.local_resources.samplers.get(&render_resource);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources.samplers.get(&render_resource)
|
||||
}
|
||||
fn get_pipeline(&self, pipeline: Handle<PipelineDescriptor>) -> Option<&wgpu::RenderPipeline> {
|
||||
let local = self.local_resources.render_pipelines.get(&pipeline);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources.render_pipelines.get(&pipeline)
|
||||
}
|
||||
fn get_shader_module(&self, shader: Handle<Shader>) -> Option<&wgpu::ShaderModule> {
|
||||
let local = self.local_resources.shader_modules.get(&shader);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
self.parent_resources.shader_modules.get(&shader)
|
||||
}
|
||||
fn set_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
bind_group: wgpu::BindGroup,
|
||||
) {
|
||||
self.local_resources.set_bind_group(
|
||||
bind_group_descriptor_id,
|
||||
render_resource_set_id,
|
||||
bind_group,
|
||||
);
|
||||
}
|
||||
fn set_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline: wgpu::RenderPipeline,
|
||||
) {
|
||||
self.local_resources
|
||||
.set_render_pipeline(pipeline_handle, pipeline);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> WgpuTransactionalRenderResourceContext<'a> {
|
||||
|
@ -64,7 +162,8 @@ impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|||
.create_texture(&self.device, texture_descriptor)
|
||||
}
|
||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
|
||||
self.local_resources.create_buffer(&self.device, buffer_info)
|
||||
self.local_resources
|
||||
.create_buffer(&self.device, buffer_info)
|
||||
}
|
||||
|
||||
// TODO: clean this up
|
||||
|
@ -100,18 +199,22 @@ impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|||
}
|
||||
|
||||
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
|
||||
let local = self.local_resources
|
||||
let local = self
|
||||
.local_resources
|
||||
.asset_resources
|
||||
.get_texture_resource(texture);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
|
||||
self.parent_resources.asset_resources.get_texture_resource(texture)
|
||||
self.parent_resources
|
||||
.asset_resources
|
||||
.get_texture_resource(texture)
|
||||
}
|
||||
|
||||
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
|
||||
let local = self.local_resources
|
||||
let local = self
|
||||
.local_resources
|
||||
.asset_resources
|
||||
.get_texture_sampler_resource(texture);
|
||||
|
||||
|
@ -119,29 +222,37 @@ impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|||
return local;
|
||||
}
|
||||
|
||||
self.parent_resources.asset_resources.get_texture_sampler_resource(texture)
|
||||
self.parent_resources
|
||||
.asset_resources
|
||||
.get_texture_sampler_resource(texture)
|
||||
}
|
||||
|
||||
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
|
||||
let local = self.local_resources
|
||||
let local = self
|
||||
.local_resources
|
||||
.asset_resources
|
||||
.get_mesh_vertices_resource(mesh);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
|
||||
self.parent_resources.asset_resources.get_mesh_vertices_resource(mesh)
|
||||
self.parent_resources
|
||||
.asset_resources
|
||||
.get_mesh_vertices_resource(mesh)
|
||||
}
|
||||
|
||||
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
|
||||
let local = self.local_resources
|
||||
let local = self
|
||||
.local_resources
|
||||
.asset_resources
|
||||
.get_mesh_indices_resource(mesh);
|
||||
if local.is_some() {
|
||||
return local;
|
||||
}
|
||||
|
||||
self.parent_resources.asset_resources.get_mesh_indices_resource(mesh)
|
||||
self.parent_resources
|
||||
.asset_resources
|
||||
.get_mesh_indices_resource(mesh)
|
||||
}
|
||||
|
||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||
|
@ -159,4 +270,17 @@ impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
|
|||
fn asset_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self.local_resources.asset_resources
|
||||
}
|
||||
fn create_shader_module(
|
||||
&mut self,
|
||||
shader_handle: Handle<Shader>,
|
||||
shader_storage: &bevy_asset::AssetStorage<Shader>,
|
||||
) {
|
||||
if self.get_shader_module(shader_handle).is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
let shader = shader_storage.get(&shader_handle).unwrap();
|
||||
self.local_resources
|
||||
.create_shader_module(&self.device, shader_handle, shader);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,24 +1,30 @@
|
|||
use super::{WgpuRenderer, WgpuResources};
|
||||
use crate::renderer_2::{WgpuRenderContext, WgpuRenderResourceContextTrait};
|
||||
use bevy_render::{
|
||||
pass::RenderPass,
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
RenderResource, RenderResourceAssignments, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer::{RenderPass, Renderer},
|
||||
renderer_2::{RenderContext, RenderResourceContext},
|
||||
};
|
||||
use std::{collections::HashMap, ops::Range};
|
||||
|
||||
pub struct WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||
pub struct WgpuRenderPass<'a, 'b, 'c, T>
|
||||
where
|
||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
||||
{
|
||||
pub render_pass: &'b mut wgpu::RenderPass<'a>,
|
||||
pub pipeline_descriptor: &'c PipelineDescriptor,
|
||||
pub wgpu_resources: &'a WgpuResources,
|
||||
pub renderer: &'d WgpuRenderer,
|
||||
pub render_context: &'a WgpuRenderContext<T>,
|
||||
pub bound_bind_groups: HashMap<u32, RenderResourceSetId>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
||||
fn get_renderer(&self) -> &dyn Renderer {
|
||||
self.renderer
|
||||
impl<'a, 'b, 'c, T> RenderPass for WgpuRenderPass<'a, 'b, 'c, T>
|
||||
where
|
||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
||||
{
|
||||
fn get_render_context(&self) -> &dyn RenderContext {
|
||||
self.render_context
|
||||
}
|
||||
|
||||
fn get_pipeline_descriptor(&self) -> &PipelineDescriptor {
|
||||
|
@ -26,13 +32,21 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
}
|
||||
|
||||
fn set_vertex_buffer(&mut self, start_slot: u32, resource: RenderResource, offset: u64) {
|
||||
let buffer = self.wgpu_resources.buffers.get(&resource).unwrap();
|
||||
let buffer = self
|
||||
.render_context
|
||||
.render_resources
|
||||
.get_buffer(resource)
|
||||
.unwrap();
|
||||
self.render_pass
|
||||
.set_vertex_buffer(start_slot, &buffer, offset, 0);
|
||||
}
|
||||
|
||||
fn set_index_buffer(&mut self, resource: RenderResource, offset: u64) {
|
||||
let buffer = self.wgpu_resources.buffers.get(&resource).unwrap();
|
||||
let buffer = self
|
||||
.render_context
|
||||
.render_resources
|
||||
.get_buffer(resource)
|
||||
.unwrap();
|
||||
self.render_pass.set_index_buffer(&buffer, offset, 0);
|
||||
}
|
||||
|
||||
|
@ -69,7 +83,12 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
index_buffer
|
||||
);
|
||||
self.set_index_buffer(index_buffer, 0);
|
||||
match self.renderer.get_resource_info(index_buffer).unwrap() {
|
||||
match self
|
||||
.render_context
|
||||
.resources()
|
||||
.get_resource_info(index_buffer)
|
||||
.unwrap()
|
||||
{
|
||||
ResourceInfo::Buffer(buffer_info) => {
|
||||
indices = Some(0..(buffer_info.size / 2) as u32)
|
||||
}
|
||||
|
@ -84,7 +103,8 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
|
|||
render_resource_assignments.get_render_resource_set_id(bind_group.id)
|
||||
{
|
||||
if let Some(wgpu_bind_group) = self
|
||||
.wgpu_resources
|
||||
.render_context
|
||||
.render_resources
|
||||
.get_bind_group(bind_group.id, *render_resource_set_id)
|
||||
{
|
||||
const EMPTY: &'static [u32] = &[];
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use super::{
|
||||
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
||||
WgpuRenderPass, WgpuResources,
|
||||
};
|
||||
use super::{wgpu_type_converter::WgpuInto, WgpuRenderPass, WgpuResources};
|
||||
use crate::renderer_2::{
|
||||
WgpuRenderContext, WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext, render_resource_sets_system,
|
||||
render_resource_sets_system, WgpuRenderContext, WgpuRenderResourceContext,
|
||||
WgpuRenderResourceContextTrait, WgpuTransactionalRenderResourceContext,
|
||||
};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use bevy_asset::AssetStorage;
|
||||
use bevy_render::{
|
||||
pass::{
|
||||
PassDescriptor, RenderPassColorAttachmentDescriptor,
|
||||
|
@ -14,13 +12,8 @@ use bevy_render::{
|
|||
},
|
||||
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{
|
||||
resource_name, AssetResources, BufferInfo, RenderResource, RenderResourceAssignments,
|
||||
ResourceInfo,
|
||||
},
|
||||
renderer::Renderer,
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, TextureDescriptor},
|
||||
render_resource::{resource_name, RenderResourceAssignments},
|
||||
renderer_2::RenderContext,
|
||||
};
|
||||
use bevy_window::{WindowCreated, WindowResized, Windows};
|
||||
use legion::prelude::*;
|
||||
|
@ -34,7 +27,6 @@ pub struct WgpuRenderer {
|
|||
pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
|
||||
pub queue: wgpu::Queue,
|
||||
pub encoder: Option<wgpu::CommandEncoder>,
|
||||
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
||||
pub window_created_event_reader: EventReader<WindowCreated>,
|
||||
pub intialized: bool,
|
||||
|
@ -74,7 +66,6 @@ impl WgpuRenderer {
|
|||
window_resized_event_reader,
|
||||
window_created_event_reader,
|
||||
intialized: false,
|
||||
render_pipelines: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,11 +221,12 @@ impl WgpuRenderer {
|
|||
resources: &Resources,
|
||||
device: Arc<wgpu::Device>,
|
||||
global_wgpu_resources: &WgpuResources,
|
||||
) -> (Vec::<wgpu::CommandBuffer>, Vec::<WgpuResources>) {
|
||||
) -> (Vec<wgpu::CommandBuffer>, Vec<WgpuResources>) {
|
||||
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
|
||||
let chunk_size =
|
||||
(render_graph.resource_providers.len() + max_thread_count - 1) / max_thread_count; // divide ints rounding remainder up
|
||||
// println!("chunk {} {}", chunk_size, render_graph.resource_providers.len());
|
||||
let mut actual_thread_count = 0;
|
||||
crossbeam_utils::thread::scope(|s| {
|
||||
|
@ -261,11 +253,12 @@ impl WgpuRenderer {
|
|||
sender.send(render_context.finish()).unwrap();
|
||||
});
|
||||
}
|
||||
}).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let mut command_buffers = Vec::new();
|
||||
let mut local_resources = Vec::new();
|
||||
for i in 0..actual_thread_count {
|
||||
for _i in 0..actual_thread_count {
|
||||
let (command_buffer, render_resources) = receiver.recv().unwrap();
|
||||
if let Some(command_buffer) = command_buffer {
|
||||
command_buffers.push(command_buffer);
|
||||
|
@ -286,7 +279,12 @@ impl WgpuRenderer {
|
|||
device: Arc<wgpu::Device>,
|
||||
global_wgpu_resources: &mut WgpuResources,
|
||||
) {
|
||||
let (mut command_buffers, local_resources) = Self::parallel_resource_provider_update(world, resources, device.clone(), global_wgpu_resources);
|
||||
let (mut command_buffers, local_resources) = Self::parallel_resource_provider_update(
|
||||
world,
|
||||
resources,
|
||||
device.clone(),
|
||||
global_wgpu_resources,
|
||||
);
|
||||
for local_resource in local_resources {
|
||||
global_wgpu_resources.consume(local_resource);
|
||||
}
|
||||
|
@ -339,7 +337,10 @@ impl WgpuRenderer {
|
|||
let mut render_resource_assignments =
|
||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||
for (name, texture_descriptor) in render_graph.queued_textures.drain(..) {
|
||||
let resource = self.create_texture(&texture_descriptor, None);
|
||||
let resource = self
|
||||
.global_context
|
||||
.resources_mut()
|
||||
.create_texture(&texture_descriptor);
|
||||
render_resource_assignments.set(&name, resource);
|
||||
}
|
||||
}
|
||||
|
@ -425,10 +426,8 @@ impl WgpuRenderer {
|
|||
.collect::<HashMap<String, wgpu::SwapChainOutput>>();
|
||||
(primary_swap_chain, swap_chain_outputs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Renderer for WgpuRenderer {
|
||||
fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
Self::handle_window_created_events(
|
||||
resources,
|
||||
&self.global_context.device,
|
||||
|
@ -463,14 +462,14 @@ impl Renderer for WgpuRenderer {
|
|||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
||||
);
|
||||
update_shader_assignments(world, resources, self);
|
||||
update_shader_assignments(world, resources, &self.global_context);
|
||||
self.create_queued_textures(resources);
|
||||
let mut encoder = self.encoder.take().unwrap();
|
||||
|
||||
render_resource_sets_system().run(world, resources);
|
||||
// setup draw targets
|
||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||
render_graph.setup_pipeline_draw_targets(world, resources, self);
|
||||
render_graph.setup_pipeline_draw_targets(world, resources, &mut self.global_context);
|
||||
|
||||
let (primary_swap_chain, swap_chain_outputs) = self.get_swap_chain_outputs(resources);
|
||||
|
||||
|
@ -499,18 +498,17 @@ impl Renderer for WgpuRenderer {
|
|||
for compiled_pipeline_handle in compiled_pipelines_iter {
|
||||
let pipeline_descriptor =
|
||||
pipeline_storage.get(compiled_pipeline_handle).unwrap();
|
||||
let render_pipeline =
|
||||
self.render_pipelines.get(compiled_pipeline_handle).unwrap();
|
||||
let render_pipeline = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.get_pipeline(*compiled_pipeline_handle)
|
||||
.unwrap();
|
||||
render_pass.set_pipeline(render_pipeline);
|
||||
|
||||
let mut wgpu_render_pass = WgpuRenderPass {
|
||||
render_pass: &mut render_pass,
|
||||
pipeline_descriptor,
|
||||
wgpu_resources: &self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources,
|
||||
renderer: &self,
|
||||
render_context: &self.global_context,
|
||||
bound_bind_groups: HashMap::default(),
|
||||
};
|
||||
|
||||
|
@ -533,344 +531,4 @@ impl Renderer for WgpuRenderer {
|
|||
let command_buffer = encoder.finish();
|
||||
self.queue.submit(&[command_buffer]);
|
||||
}
|
||||
|
||||
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_buffer_with_data(&self.global_context.device, buffer_info, data)
|
||||
}
|
||||
|
||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_buffer(&self.global_context.device, buffer_info)
|
||||
}
|
||||
|
||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.resource_info
|
||||
.get(&resource)
|
||||
}
|
||||
|
||||
fn get_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo> {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.resource_info
|
||||
.get_mut(&resource)
|
||||
}
|
||||
|
||||
fn remove_buffer(&mut self, resource: RenderResource) {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.remove_buffer(resource);
|
||||
}
|
||||
|
||||
fn create_buffer_mapped(
|
||||
&mut self,
|
||||
buffer_info: BufferInfo,
|
||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
|
||||
) -> RenderResource {
|
||||
let buffer = WgpuResources::begin_create_buffer_mapped(&buffer_info, self, setup_data);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.assign_buffer(buffer, buffer_info)
|
||||
}
|
||||
|
||||
fn copy_buffer_to_buffer(
|
||||
&mut self,
|
||||
source_buffer: RenderResource,
|
||||
source_offset: u64,
|
||||
destination_buffer: RenderResource,
|
||||
destination_offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.copy_buffer_to_buffer(
|
||||
self.encoder.as_mut().unwrap(),
|
||||
source_buffer,
|
||||
source_offset,
|
||||
destination_buffer,
|
||||
destination_offset,
|
||||
size,
|
||||
);
|
||||
}
|
||||
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_sampler(&self.global_context.device, sampler_descriptor)
|
||||
}
|
||||
|
||||
fn create_texture(
|
||||
&mut self,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: Option<&[u8]>,
|
||||
) -> RenderResource {
|
||||
if let Some(bytes) = bytes {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_texture_with_data(
|
||||
&self.global_context.device,
|
||||
self.encoder.as_mut().unwrap(),
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
} else {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_texture(&self.global_context.device, texture_descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
fn remove_texture(&mut self, resource: RenderResource) {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.remove_texture(resource);
|
||||
}
|
||||
|
||||
fn remove_sampler(&mut self, resource: RenderResource) {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.remove_sampler(resource);
|
||||
}
|
||||
|
||||
fn get_render_resources(&self) -> &AssetResources {
|
||||
&self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.asset_resources
|
||||
}
|
||||
|
||||
fn get_render_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.asset_resources
|
||||
}
|
||||
|
||||
fn setup_bind_groups(
|
||||
&mut self,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
pipeline_descriptor: &PipelineDescriptor,
|
||||
) {
|
||||
let pipeline_layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in pipeline_layout.bind_groups.iter() {
|
||||
if let Some((render_resource_set_id, _indices)) =
|
||||
render_resource_assignments.get_render_resource_set_id(bind_group.id)
|
||||
{
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.get_bind_group(bind_group.id, *render_resource_set_id)
|
||||
{
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_bind_group(
|
||||
&self.global_context.device,
|
||||
bind_group,
|
||||
render_resource_assignments,
|
||||
);
|
||||
} else {
|
||||
log::trace!(
|
||||
"reusing RenderResourceSet {:?} for bind group {}",
|
||||
render_resource_set_id,
|
||||
bind_group.index
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn setup_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
pipeline_descriptor: &mut PipelineDescriptor,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
) {
|
||||
if self.render_pipelines.contains_key(&pipeline_handle) {
|
||||
return;
|
||||
}
|
||||
|
||||
let layout = pipeline_descriptor.get_layout().unwrap();
|
||||
for bind_group in layout.bind_groups.iter() {
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.bind_group_layouts
|
||||
.get(&bind_group.id)
|
||||
{
|
||||
let bind_group_layout_binding = bind_group
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| wgpu::BindGroupLayoutEntry {
|
||||
binding: binding.index,
|
||||
visibility: wgpu::ShaderStage::VERTEX | wgpu::ShaderStage::FRAGMENT,
|
||||
ty: (&binding.bind_type).wgpu_into(),
|
||||
})
|
||||
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
||||
let wgpu_bind_group_layout = self.global_context.device.create_bind_group_layout(
|
||||
&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: bind_group_layout_binding.as_slice(),
|
||||
label: None,
|
||||
},
|
||||
);
|
||||
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.bind_group_layouts
|
||||
.insert(bind_group.id, wgpu_bind_group_layout);
|
||||
}
|
||||
}
|
||||
|
||||
// setup and collect bind group layouts
|
||||
let bind_group_layouts = layout
|
||||
.bind_groups
|
||||
.iter()
|
||||
.map(|bind_group| {
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.bind_group_layouts
|
||||
.get(&bind_group.id)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
||||
|
||||
let pipeline_layout =
|
||||
self.global_context
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||
});
|
||||
|
||||
let owned_vertex_buffer_descriptors = layout
|
||||
.vertex_buffer_descriptors
|
||||
.iter()
|
||||
.map(|v| v.wgpu_into())
|
||||
.collect::<Vec<OwnedWgpuVertexBufferDescriptor>>();
|
||||
|
||||
let color_states = pipeline_descriptor
|
||||
.color_states
|
||||
.iter()
|
||||
.map(|c| c.wgpu_into())
|
||||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
||||
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||
{
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_shader_module(
|
||||
&self.global_context.device,
|
||||
pipeline_descriptor.shader_stages.vertex,
|
||||
shader_storage,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&fragment_handle)
|
||||
{
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_shader_module(
|
||||
&self.global_context.device,
|
||||
fragment_handle,
|
||||
shader_storage,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let vertex_shader_module = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||
.unwrap();
|
||||
|
||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
||||
Some(fragment_handle) => Some(
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&fragment_handle)
|
||||
.unwrap(),
|
||||
),
|
||||
None => None,
|
||||
};
|
||||
|
||||
let mut render_pipeline_descriptor = wgpu::RenderPipelineDescriptor {
|
||||
layout: &pipeline_layout,
|
||||
vertex_stage: wgpu::ProgrammableStageDescriptor {
|
||||
module: &vertex_shader_module,
|
||||
entry_point: "main",
|
||||
},
|
||||
fragment_stage: match pipeline_descriptor.shader_stages.fragment {
|
||||
Some(_) => Some(wgpu::ProgrammableStageDescriptor {
|
||||
entry_point: "main",
|
||||
module: fragment_shader_module.as_ref().unwrap(),
|
||||
}),
|
||||
None => None,
|
||||
},
|
||||
rasterization_state: pipeline_descriptor
|
||||
.rasterization_state
|
||||
.as_ref()
|
||||
.map(|r| r.wgpu_into()),
|
||||
primitive_topology: pipeline_descriptor.primitive_topology.wgpu_into(),
|
||||
color_states: &color_states,
|
||||
depth_stencil_state: pipeline_descriptor
|
||||
.depth_stencil_state
|
||||
.as_ref()
|
||||
.map(|d| d.wgpu_into()),
|
||||
vertex_state: wgpu::VertexStateDescriptor {
|
||||
index_format: pipeline_descriptor.index_format.wgpu_into(),
|
||||
vertex_buffers: &owned_vertex_buffer_descriptors
|
||||
.iter()
|
||||
.map(|v| v.into())
|
||||
.collect::<Vec<wgpu::VertexBufferDescriptor>>(),
|
||||
},
|
||||
sample_count: pipeline_descriptor.sample_count,
|
||||
sample_mask: pipeline_descriptor.sample_mask,
|
||||
alpha_to_coverage_enabled: pipeline_descriptor.alpha_to_coverage_enabled,
|
||||
};
|
||||
|
||||
let render_pipeline = self
|
||||
.global_context
|
||||
.device
|
||||
.create_render_pipeline(&mut render_pipeline_descriptor);
|
||||
self.render_pipelines
|
||||
.insert(pipeline_handle, render_pipeline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
use super::WgpuRenderer;
|
||||
use crate::{
|
||||
renderer_2::{WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext},
|
||||
wgpu_type_converter::WgpuInto,
|
||||
};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use bevy_asset::Handle;
|
||||
use bevy_render::{
|
||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, BindType},
|
||||
pipeline::{BindGroupDescriptorId, PipelineDescriptor},
|
||||
render_resource::{
|
||||
AssetResources, BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId,
|
||||
ResourceInfo,
|
||||
AssetResources, BufferInfo, RenderResource, RenderResourceSetId, ResourceInfo,
|
||||
},
|
||||
renderer::Renderer,
|
||||
renderer_2::RenderResourceContext,
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, TextureDescriptor},
|
||||
|
@ -34,6 +31,7 @@ pub struct WgpuResources {
|
|||
pub samplers: HashMap<RenderResource, wgpu::Sampler>,
|
||||
pub resource_info: HashMap<RenderResource, ResourceInfo>,
|
||||
pub shader_modules: HashMap<Handle<Shader>, wgpu::ShaderModule>,
|
||||
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
||||
pub bind_groups: HashMap<BindGroupDescriptorId, WgpuBindGroupInfo>,
|
||||
pub bind_group_layouts: HashMap<BindGroupDescriptorId, wgpu::BindGroupLayout>,
|
||||
}
|
||||
|
@ -90,96 +88,32 @@ impl WgpuResources {
|
|||
}
|
||||
|
||||
pub fn create_bind_group(
|
||||
&mut self,
|
||||
&self,
|
||||
device: &wgpu::Device,
|
||||
bind_group_descriptor: &BindGroupDescriptor,
|
||||
render_resource_assignments: &RenderResourceAssignments,
|
||||
) -> bool {
|
||||
if let Some((render_resource_set_id, _indices)) =
|
||||
render_resource_assignments.get_render_resource_set_id(bind_group_descriptor.id)
|
||||
{
|
||||
log::trace!(
|
||||
"start creating bind group for RenderResourceSet {:?}",
|
||||
render_resource_set_id
|
||||
);
|
||||
let bindings = bind_group_descriptor
|
||||
.bindings
|
||||
.iter()
|
||||
.map(|binding| {
|
||||
if let Some(resource) = render_resource_assignments.get(&binding.name) {
|
||||
|
||||
let resource_info = self.resource_info.get(&resource).unwrap();
|
||||
log::trace!("found binding {} ({}) resource: {:?} {:?}", binding.index, binding.name, resource, resource_info);
|
||||
wgpu::Binding {
|
||||
binding: binding.index,
|
||||
resource: match &binding.bind_type {
|
||||
BindType::SampledTexture { .. } => {
|
||||
if let ResourceInfo::Texture = resource_info {
|
||||
let texture = self.textures.get(&resource).unwrap();
|
||||
wgpu::BindingResource::TextureView(texture)
|
||||
} else {
|
||||
panic!("expected a Texture resource");
|
||||
}
|
||||
}
|
||||
BindType::Sampler { .. } => {
|
||||
if let ResourceInfo::Sampler = resource_info {
|
||||
let sampler = self.samplers.get(&resource).unwrap();
|
||||
wgpu::BindingResource::Sampler(sampler)
|
||||
} else {
|
||||
panic!("expected a Sampler resource");
|
||||
}
|
||||
}
|
||||
BindType::Uniform { .. } => {
|
||||
if let ResourceInfo::Buffer(buffer_info) = resource_info {
|
||||
let buffer = self.buffers.get(&resource).unwrap();
|
||||
wgpu::BindingResource::Buffer {
|
||||
buffer,
|
||||
range: 0..buffer_info.size as u64,
|
||||
}
|
||||
} else {
|
||||
panic!("expected a Buffer resource");
|
||||
}
|
||||
}
|
||||
_ => panic!("unsupported bind type"),
|
||||
},
|
||||
}
|
||||
} else {
|
||||
panic!(
|
||||
"No resource assigned to uniform \"{}\" for RenderResourceAssignments {:?}",
|
||||
binding.name,
|
||||
render_resource_assignments.id
|
||||
);
|
||||
}
|
||||
})
|
||||
.collect::<Vec<wgpu::Binding>>();
|
||||
let bind_group_layout = self
|
||||
.bind_group_layouts
|
||||
.get(&bind_group_descriptor.id)
|
||||
.unwrap();
|
||||
let wgpu_bind_group_descriptor = wgpu::BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: bind_group_layout,
|
||||
bindings: bindings.as_slice(),
|
||||
};
|
||||
|
||||
let bind_group = device.create_bind_group(&wgpu_bind_group_descriptor);
|
||||
let bind_group_info = self
|
||||
.bind_groups
|
||||
.entry(bind_group_descriptor.id)
|
||||
.or_insert_with(|| WgpuBindGroupInfo::default());
|
||||
bind_group_info
|
||||
.bind_groups
|
||||
.insert(*render_resource_set_id, bind_group);
|
||||
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
bind_group_descriptor: &wgpu::BindGroupDescriptor,
|
||||
) -> wgpu::BindGroup {
|
||||
log::trace!(
|
||||
"created bind group for RenderResourceSet {:?}",
|
||||
render_resource_set_id
|
||||
);
|
||||
log::trace!("{:#?}", bind_group_descriptor);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
device.create_bind_group(bind_group_descriptor)
|
||||
}
|
||||
|
||||
pub fn set_bind_group(
|
||||
&mut self,
|
||||
bind_group_descriptor_id: BindGroupDescriptorId,
|
||||
render_resource_set_id: RenderResourceSetId,
|
||||
bind_group: wgpu::BindGroup,
|
||||
) {
|
||||
let bind_group_info = self
|
||||
.bind_groups
|
||||
.entry(bind_group_descriptor_id)
|
||||
.or_insert_with(|| WgpuBindGroupInfo::default());
|
||||
bind_group_info
|
||||
.bind_groups
|
||||
.insert(render_resource_set_id, bind_group);
|
||||
}
|
||||
|
||||
pub fn create_buffer(
|
||||
|
@ -231,21 +165,6 @@ impl WgpuResources {
|
|||
resource
|
||||
}
|
||||
|
||||
pub fn begin_create_buffer_mapped(
|
||||
buffer_info: &BufferInfo,
|
||||
renderer: &mut WgpuRenderer,
|
||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
|
||||
) -> wgpu::Buffer {
|
||||
let device = renderer.global_context.device.clone();
|
||||
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: buffer_info.size as u64,
|
||||
usage: buffer_info.buffer_usage.wgpu_into(),
|
||||
label: None,
|
||||
});
|
||||
setup_data(&mut mapped.data, renderer);
|
||||
mapped.finish()
|
||||
}
|
||||
|
||||
// TODO: clean this up
|
||||
pub fn begin_create_buffer_mapped_render_context(
|
||||
buffer_info: &BufferInfo,
|
||||
|
@ -295,12 +214,10 @@ impl WgpuResources {
|
|||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
shader_handle: Handle<Shader>,
|
||||
shader_storage: &AssetStorage<Shader>,
|
||||
shader: &Shader,
|
||||
) {
|
||||
self.shader_modules.entry(shader_handle).or_insert_with(|| {
|
||||
let shader = shader_storage.get(&shader_handle).unwrap();
|
||||
device.create_shader_module(&shader.get_spirv(None))
|
||||
});
|
||||
let shader_module = device.create_shader_module(&shader.get_spirv(None));
|
||||
self.shader_modules.insert(shader_handle, shader_module);
|
||||
}
|
||||
|
||||
pub fn create_sampler(
|
||||
|
@ -380,4 +297,32 @@ impl WgpuResources {
|
|||
pub fn get_render_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self.asset_resources
|
||||
}
|
||||
|
||||
pub fn create_bind_group_layout(
|
||||
&mut self,
|
||||
device: &wgpu::Device,
|
||||
bind_group_id: BindGroupDescriptorId,
|
||||
descriptor: &wgpu::BindGroupLayoutDescriptor,
|
||||
) {
|
||||
let wgpu_bind_group_layout = device.create_bind_group_layout(descriptor);
|
||||
self.bind_group_layouts
|
||||
.insert(bind_group_id, wgpu_bind_group_layout);
|
||||
}
|
||||
|
||||
pub fn create_render_pipeline(
|
||||
&self,
|
||||
device: &wgpu::Device,
|
||||
descriptor: &wgpu::RenderPipelineDescriptor,
|
||||
) -> wgpu::RenderPipeline {
|
||||
device.create_render_pipeline(&descriptor)
|
||||
}
|
||||
|
||||
pub fn set_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
render_pipeline: wgpu::RenderPipeline,
|
||||
) {
|
||||
self.render_pipelines
|
||||
.insert(pipeline_handle, render_pipeline);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build()
|
||||
.add_default_plugins()
|
||||
.setup(setup)
|
||||
.run();
|
||||
App::build().add_default_plugins().setup(setup).run();
|
||||
}
|
||||
|
||||
/// set up a simple scene
|
||||
|
|
|
@ -3,7 +3,10 @@ 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>())
|
||||
.add_system_to_stage(
|
||||
stage::POST_UPDATE,
|
||||
shader::asset_handle_batcher_system::<MyMaterial>(),
|
||||
)
|
||||
.setup(setup)
|
||||
.run();
|
||||
}
|
||||
|
|
|
@ -1,18 +1,38 @@
|
|||
pub use crate::AddDefaultPlugins;
|
||||
pub use crate::app::{App, AppBuilder, AppPlugin, EntityArchetype, EventReader, Events, GetEventReader, stage};
|
||||
#[cfg(feature = "asset")]
|
||||
pub use crate::asset::{Asset, AssetStorage, Handle};
|
||||
#[cfg(feature = "derive")]
|
||||
pub use crate::derive::*;
|
||||
#[cfg(feature = "transform")]
|
||||
pub use crate::transform::prelude::*;
|
||||
#[cfg(feature = "core")]
|
||||
pub use crate::core::{
|
||||
time::Time,
|
||||
transform::{CommandBufferBuilderSource, WorldBuilder, WorldBuilderSource},
|
||||
};
|
||||
#[cfg(feature = "derive")]
|
||||
pub use crate::derive::*;
|
||||
#[cfg(feature = "diagnostic")]
|
||||
pub use crate::diagnostic::DiagnosticsPlugin;
|
||||
#[cfg(feature = "render")]
|
||||
pub use crate::render::{
|
||||
entity::*,
|
||||
mesh::{Mesh, MeshType},
|
||||
pipeline::PipelineDescriptor,
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{resource_name, resource_providers::UniformResourceProvider, AssetBatchers},
|
||||
shader::{uniforms::StandardMaterial, Shader, ShaderDefSuffixProvider, ShaderStage},
|
||||
texture::{Texture, TextureType},
|
||||
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Light, Renderable,
|
||||
};
|
||||
#[cfg(feature = "transform")]
|
||||
pub use crate::transform::prelude::*;
|
||||
#[cfg(feature = "ui")]
|
||||
pub use crate::ui::{entity::*, Anchors, Margins, Node};
|
||||
#[cfg(feature = "window")]
|
||||
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
|
||||
pub use crate::{
|
||||
app::{
|
||||
stage, App, AppBuilder, AppPlugin, EntityArchetype, EventReader, Events, GetEventReader,
|
||||
},
|
||||
math::{self, Mat3, Mat4, Quat, Vec2, Vec3, Vec4},
|
||||
AddDefaultPlugins,
|
||||
};
|
||||
pub use legion::{
|
||||
command::CommandBuffer,
|
||||
entity::Entity,
|
||||
|
@ -27,19 +47,3 @@ pub use legion::{
|
|||
},
|
||||
world::{Universe, World},
|
||||
};
|
||||
pub use crate::math::{self, Mat3, Mat4, Quat, Vec2, Vec3, Vec4};
|
||||
#[cfg(feature = "render")]
|
||||
pub use crate::render::{
|
||||
entity::*,
|
||||
mesh::{Mesh, MeshType},
|
||||
pipeline::PipelineDescriptor,
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{resource_name, resource_providers::UniformResourceProvider, AssetBatchers},
|
||||
shader::{uniforms::StandardMaterial, Shader, ShaderDefSuffixProvider, ShaderStage},
|
||||
texture::{Texture, TextureType},
|
||||
ActiveCamera, ActiveCamera2d, Camera, CameraType, Color, ColorSource, Light, Renderable,
|
||||
};
|
||||
#[cfg(feature = "ui")]
|
||||
pub use crate::ui::{entity::*, Anchors, Margins, Node};
|
||||
#[cfg(feature = "window")]
|
||||
pub use crate::window::{Window, WindowDescriptor, WindowPlugin, Windows};
|
||||
|
|
Loading…
Reference in a new issue