RenderGraph is now a Resource. RenderGraph owns vertex buffer descriptors. Assorted cleanup

This commit is contained in:
Carter Anderson 2020-03-21 19:57:59 -07:00
parent 7660b8bf3f
commit a4eed18800
26 changed files with 226 additions and 264 deletions

View file

@ -2,6 +2,7 @@
"cSpell.words": [
"Bitmask",
"MSAA",
"Renderable",
"Wgpu",
"Zunstable",
"bools",

View file

@ -26,14 +26,14 @@ fn setup(world: &mut World, resources: &mut Resources) {
.add_entity(MeshEntity {
mesh: plane_handle,
material: plane_material_handle,
renderable: Renderable::instanced(),
// renderable: Renderable::instanced(),
..Default::default()
})
// cube
.add_entity(MeshEntity {
mesh: cube_handle,
material: cube_material_handle,
renderable: Renderable::instanced(),
// renderable: Renderable::instanced(),
translation: Translation::new(-1.5, 0.0, 1.0),
..Default::default()
})
@ -41,7 +41,7 @@ fn setup(world: &mut World, resources: &mut Resources) {
.add_entity(MeshEntity {
mesh: cube_handle,
material: cube_material_handle,
renderable: Renderable::instanced(),
// renderable: Renderable::instanced(),
translation: Translation::new(1.5, 0.0, 1.0),
..Default::default()
})

View file

@ -6,18 +6,13 @@ use winit::{
use legion::prelude::*;
use crate::{
app::AppBuilder,
core::Time,
render::{render_graph::RenderGraph, renderer::Renderer},
};
use crate::{app::AppBuilder, core::Time, render::renderer::Renderer};
pub struct App {
pub universe: Universe,
pub world: World,
pub resources: Resources,
pub renderer: Option<Box<dyn Renderer>>,
pub render_graph: RenderGraph,
pub schedule: Schedule,
}
@ -28,7 +23,6 @@ impl App {
schedule: Schedule,
resources: Resources,
renderer: Option<Box<dyn Renderer>>,
render_graph: RenderGraph,
) -> App {
App {
universe,
@ -36,7 +30,6 @@ impl App {
schedule,
renderer,
resources,
render_graph,
}
}
@ -51,11 +44,7 @@ impl App {
self.schedule.execute(&mut self.world, &mut self.resources);
if let Some(ref mut renderer) = self.renderer {
renderer.process_render_graph(
&mut self.render_graph,
&mut self.world,
&mut self.resources,
);
renderer.update(&mut self.world, &mut self.resources);
}
if let Some(mut time) = self.resources.get_mut::<Time>() {
@ -79,7 +68,7 @@ impl App {
log::info!("Initializing the example...");
if let Some(ref mut renderer) = self.renderer {
renderer.initialize(&mut self.world, &mut self.resources, &mut self.render_graph);
renderer.initialize(&mut self.world, &mut self.resources);
}
log::info!("Entering render loop...");
@ -91,17 +80,11 @@ impl App {
};
match event {
event::Event::WindowEvent {
event: WindowEvent::Resized(size),
event: WindowEvent::Resized(_size),
..
} => {
if let Some(ref mut renderer) = self.renderer {
renderer.resize(
&mut self.world,
&mut self.resources,
&mut self.render_graph,
size.width,
size.height,
);
renderer.resize(&mut self.world, &mut self.resources);
}
}
event::Event::WindowEvent { event, .. } => match event {

View file

@ -15,7 +15,9 @@ use crate::{
use bevy_transform::{prelude::LocalToWorld, transform_system_bundle};
use pipeline::PipelineDescriptor;
use render_graph::RenderGraphBuilder;
use render_resource::{EntityRenderResourceAssignments, AssetBatchers, RenderResourceAssignmentsProvider};
use render_resource::{
AssetBatchers, EntityRenderResourceAssignments, RenderResourceAssignmentsProvider,
};
use shader::Shader;
use std::collections::HashMap;
@ -67,13 +69,15 @@ impl AppBuilder {
}
}
let render_graph = self.render_graph_builder.build();
self.resources.insert(render_graph);
App::new(
self.universe,
self.world,
schedule_builder.build(),
self.resources,
self.renderer,
self.render_graph_builder.build(),
)
}
@ -134,8 +138,10 @@ impl AppBuilder {
.insert(AssetStorage::<PipelineDescriptor>::new());
self.resources.insert(ShaderPipelineAssignments::new());
self.resources.insert(CompiledShaderMap::new());
self.resources.insert(RenderResourceAssignmentsProvider::default());
self.resources.insert(EntityRenderResourceAssignments::default());
self.resources
.insert(RenderResourceAssignmentsProvider::default());
self.resources
.insert(EntityRenderResourceAssignments::default());
self.resources.insert(asset_batchers);
self
}

View file

@ -6,7 +6,7 @@ use std::{
hash::{Hash, Hasher},
};
use std::{collections::HashMap, marker::PhantomData, any::TypeId};
use std::{any::TypeId, collections::HashMap, marker::PhantomData};
pub type HandleId = usize;
@ -71,8 +71,10 @@ pub struct HandleUntyped {
pub type_id: TypeId,
}
impl<T> From<Handle<T>> for HandleUntyped where T: 'static {
impl<T> From<Handle<T>> for HandleUntyped
where
T: 'static,
{
fn from(handle: Handle<T>) -> Self {
HandleUntyped {
id: handle.id,
@ -81,7 +83,10 @@ impl<T> From<Handle<T>> for HandleUntyped where T: 'static {
}
}
impl<T> From<HandleUntyped> for Handle<T> where T: 'static {
impl<T> From<HandleUntyped> for Handle<T>
where
T: 'static,
{
fn from(handle: HandleUntyped) -> Self {
if TypeId::of::<T>() != handle.type_id {
panic!("attempted to convert untyped handle to incorrect typed handle");

View file

@ -17,13 +17,13 @@ impl DrawTarget for AssignedBatchesDrawTarget {
&self,
_world: &World,
resources: &Resources,
render_pass: &mut dyn RenderPass,
_render_pass: &mut dyn RenderPass,
_pipeline_handle: Handle<PipelineDescriptor>,
) {
let asset_batches = resources.get::<AssetBatchers>().unwrap();
// let renderer = render_pass.get_renderer();
// println!("Drawing batches");
for batch in asset_batches.get_batches() {
for _batch in asset_batches.get_batches() {
// println!("{:?}", batch);
// render_pass.set_bind_groups(batch.render_resource_assignments.as_ref());
// render_pass.draw_indexed(0..1, 0, 0..1);

View file

@ -5,7 +5,7 @@ use crate::{
draw_target::DrawTarget,
mesh::Mesh,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo, EntityRenderResourceAssignments},
render_resource::{resource_name, EntityRenderResourceAssignments, ResourceInfo},
renderer::{RenderPass, Renderer},
Renderable, ShaderPipelineAssignments,
},
@ -23,7 +23,8 @@ impl DrawTarget for AssignedMeshesDrawTarget {
pipeline_handle: Handle<PipelineDescriptor>,
) {
let shader_pipeline_assignments = resources.get::<ShaderPipelineAssignments>().unwrap();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
let entity_render_resource_assignments =
resources.get::<EntityRenderResourceAssignments>().unwrap();
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
@ -81,7 +82,8 @@ impl DrawTarget for AssignedMeshesDrawTarget {
.assignments
.get(&pipeline_handle);
let pipeline_storage = resources.get::<AssetStorage<PipelineDescriptor>>().unwrap();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
let entity_render_resource_assignments =
resources.get::<EntityRenderResourceAssignments>().unwrap();
let pipeline_descriptor = pipeline_storage.get(&pipeline_handle).unwrap();
if let Some(assigned_entities) = assigned_entities {
for entity in assigned_entities.iter() {
@ -91,7 +93,9 @@ impl DrawTarget for AssignedMeshesDrawTarget {
continue;
}
if let Some(render_resource_assignments) = entity_render_resource_assignments.get(*entity) {
if let Some(render_resource_assignments) =
entity_render_resource_assignments.get(*entity)
{
renderer.setup_bind_groups(render_resource_assignments, pipeline_descriptor);
}
}

View file

@ -5,7 +5,7 @@ use crate::{
draw_target::DrawTarget,
mesh::Mesh,
pipeline::PipelineDescriptor,
render_resource::{resource_name, ResourceInfo, EntityRenderResourceAssignments},
render_resource::{resource_name, EntityRenderResourceAssignments, ResourceInfo},
renderer::RenderPass,
Renderable,
},
@ -25,7 +25,8 @@ impl DrawTarget for MeshesDrawTarget {
let mut current_mesh_handle = None;
let mut current_mesh_index_len = 0;
let mesh_query = <(Read<Handle<Mesh>>, Read<Renderable>)>::query();
let entity_render_resource_assignments = resources.get::<EntityRenderResourceAssignments>().unwrap();
let entity_render_resource_assignments =
resources.get::<EntityRenderResourceAssignments>().unwrap();
for (entity, (mesh, renderable)) in mesh_query.iter_entities(world) {
if !renderable.is_visible || renderable.is_instanced {

View file

@ -1,33 +1,25 @@
use crate::{
asset::Handle,
render::{
draw_target::DrawTarget, pass::PassDescriptor, pipeline::PipelineDescriptor,
render_resource::ResourceProvider, texture::TextureDescriptor,
draw_target::DrawTarget,
pass::PassDescriptor,
pipeline::{PipelineDescriptor, VertexBufferDescriptor},
render_resource::ResourceProvider,
texture::TextureDescriptor,
},
};
use std::collections::{HashMap, HashSet};
#[derive(Default)]
pub struct RenderGraph {
pub pipeline_descriptors: HashSet<Handle<PipelineDescriptor>>,
// TODO: make this ordered
pub pass_descriptors: HashMap<String, PassDescriptor>,
pub pass_pipelines: HashMap<String, Vec<Handle<PipelineDescriptor>>>,
pub resource_providers: Vec<Box<dyn ResourceProvider>>,
pub resource_providers: Vec<Box<dyn ResourceProvider + Send + Sync>>,
pub queued_textures: Vec<(String, TextureDescriptor)>,
pub draw_targets: HashMap<String, Box<dyn DrawTarget>>,
}
impl Default for RenderGraph {
fn default() -> Self {
RenderGraph {
pipeline_descriptors: HashSet::new(),
pass_descriptors: HashMap::new(),
pass_pipelines: HashMap::new(),
resource_providers: Vec::new(),
queued_textures: Vec::new(),
draw_targets: HashMap::new(),
}
}
pub draw_targets: HashMap<String, Box<dyn DrawTarget + Send + Sync>>,
pub vertex_buffer_descriptors: HashMap<String, VertexBufferDescriptor>,
}
impl RenderGraph {
@ -41,4 +33,18 @@ impl RenderGraph {
let pass_pipelines = self.pass_pipelines.get_mut(pass).unwrap();
pass_pipelines.push(pipeline);
}
pub fn set_vertex_buffer_descriptor(
&mut self,
vertex_buffer_descriptor: VertexBufferDescriptor,
) {
self.vertex_buffer_descriptors.insert(
vertex_buffer_descriptor.name.to_string(),
vertex_buffer_descriptor,
);
}
pub fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor> {
self.vertex_buffer_descriptors.get(name)
}
}

View file

@ -62,7 +62,7 @@ impl RenderGraphBuilder {
pub fn add_resource_provider<T>(mut self, resource_provider: T) -> Self
where
T: ResourceProvider + 'static,
T: ResourceProvider + Send + Sync + 'static,
{
self.render_graph
.resource_providers
@ -79,7 +79,7 @@ impl RenderGraphBuilder {
pub fn add_draw_target<T>(mut self, draw_target: T) -> Self
where
T: DrawTarget + 'static,
T: DrawTarget + Send + Sync + 'static,
{
self.render_graph
.draw_targets

View file

@ -270,19 +270,17 @@ impl AssetBatchers {
T: 'static,
{
let handle_type = TypeId::of::<T>();
self.handle_batchers
.get(&handle_type)
.unwrap()
.iter()
self.handle_batchers.get(&handle_type).unwrap().iter()
}
pub fn get_batches_from_batcher(&self, index: usize) -> impl Iterator<Item = &Batch>
{
pub fn get_batches_from_batcher(&self, index: usize) -> impl Iterator<Item = &Batch> {
self.asset_batchers[index].get_batches()
}
pub fn get_batches_from_batcher_mut(&mut self, index: usize) -> impl Iterator<Item = &mut Batch>
{
pub fn get_batches_from_batcher_mut(
&mut self,
index: usize,
) -> impl Iterator<Item = &mut Batch> {
self.asset_batchers[index].get_batches_mut()
}

View file

@ -1,17 +1,17 @@
mod asset_batcher;
mod buffer;
mod entity_render_resource_assignments;
mod render_resource;
mod render_resource_assignments;
mod resource_info;
pub mod resource_name;
mod resource_provider;
mod entity_render_resource_assignments;
mod render_resource_assignments;
pub mod resource_providers;
pub use asset_batcher::*;
pub use buffer::*;
pub use entity_render_resource_assignments::*;
pub use render_resource::*;
pub use render_resource_assignments::*;
pub use resource_info::*;
pub use resource_provider::*;
pub use entity_render_resource_assignments::*;
pub use render_resource_assignments::*;

View file

@ -41,4 +41,4 @@ impl RenderResourceAssignmentsProvider {
self.current_id += 1;
assignments
}
}
}

View file

@ -1,5 +1,5 @@
use crate::render::render_resource::BufferUsage;
use super::RenderResourceAssignmentsId;
use crate::render::render_resource::BufferUsage;
use std::collections::HashMap;
#[derive(Default)]

View file

@ -11,7 +11,12 @@ pub trait ResourceProvider {
}
fn update(&mut self, _renderer: &mut dyn Renderer, _world: &mut World, _resources: &Resources) {
}
fn finish_update(&mut self, _renderer: &mut dyn Renderer, _world: &mut World, _resources: &Resources) {
fn finish_update(
&mut self,
_renderer: &mut dyn Renderer,
_world: &mut World,
_resources: &Resources,
) {
}
fn resize(
&mut self,

View file

@ -1,5 +1,5 @@
use crate::render::{
render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider, BufferInfo},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResource, ResourceProvider},
renderer::Renderer,
ActiveCamera2d, Camera,
};
@ -19,13 +19,11 @@ impl ResourceProvider for Camera2dResourceProvider {
_world: &mut World,
_resources: &Resources,
) {
let buffer = renderer.create_buffer(
BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>() as u64,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
}
);
let buffer = renderer.create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>() as u64,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
renderer
.get_render_resources_mut()

View file

@ -1,5 +1,5 @@
use crate::render::{
render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider, BufferInfo},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResource, ResourceProvider},
renderer::Renderer,
ActiveCamera, Camera,
};
@ -20,13 +20,11 @@ impl ResourceProvider for CameraResourceProvider {
_world: &mut World,
_resources: &Resources,
) {
let buffer = renderer.create_buffer(
BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>() as u64,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
}
);
let buffer = renderer.create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>() as u64,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default()
});
renderer
.get_render_resources_mut()

View file

@ -1,5 +1,5 @@
use crate::render::{
render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider, BufferInfo},
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResource, ResourceProvider},
renderer::Renderer,
Light, LightRaw,
};
@ -44,13 +44,11 @@ impl ResourceProvider for LightResourceProvider {
+ self.max_lights * std::mem::size_of::<LightRaw>())
as u64;
let buffer = renderer.create_buffer(
BufferInfo {
size: light_uniform_size,
buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST,
..Default::default()
}
);
let buffer = renderer.create_buffer(BufferInfo {
size: light_uniform_size,
buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST,
..Default::default()
});
renderer
.get_render_resources_mut()
.set_named_resource(resource_name::uniform::LIGHTS, buffer);
@ -99,7 +97,7 @@ impl ResourceProvider for LightResourceProvider {
BufferInfo {
size: light_count_size as u64,
buffer_usage: BufferUsage::COPY_SRC,
..Default::default()
..Default::default()
},
&mut |data| {
data.copy_from_slice([light_count as u32, 0, 0, 0].as_bytes());

View file

@ -2,7 +2,10 @@ use crate::{
ecs,
prelude::Node,
render::{
render_resource::{resource_name, BufferUsage, RenderResource, ResourceProvider, BufferInfo, BufferArrayInfo},
render_resource::{
resource_name, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
ResourceProvider,
},
renderer::Renderer,
},
};
@ -69,7 +72,6 @@ impl UiResourceProvider {
let size = std::mem::size_of::<RectData>() as u64;
let data_len = data.len() as u64;
if let Some(old_instance_buffer) = self.instance_buffer {
renderer.remove_buffer(old_instance_buffer);
}
@ -81,7 +83,7 @@ impl UiResourceProvider {
array_info: Some(BufferArrayInfo {
item_capacity: data_len,
item_count: data_len,
item_size: size,
item_size: size,
}),
..Default::default()
},

View file

@ -2,6 +2,7 @@ use crate::{
asset::{AssetStorage, Handle},
render::{
pipeline::BindType,
render_graph::RenderGraph,
render_resource::{
AssetBatchers, BufferArrayInfo, BufferDynamicUniformInfo, BufferInfo, BufferUsage,
EntityRenderResourceAssignments, RenderResource, RenderResourceAssignments,
@ -438,12 +439,13 @@ where
}
}
fn initialize_vertex_buffer_descriptor(&self, renderer: &mut dyn Renderer) {
fn initialize_vertex_buffer_descriptor(&self, render_graph: &mut RenderGraph) {
let vertex_buffer_descriptor = T::get_vertex_buffer_descriptor();
if let Some(vertex_buffer_descriptor) = vertex_buffer_descriptor {
if let None = renderer.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name) {
if let None = render_graph.get_vertex_buffer_descriptor(&vertex_buffer_descriptor.name)
{
println!("{:#?}", vertex_buffer_descriptor);
renderer.set_vertex_buffer_descriptor(vertex_buffer_descriptor.clone());
render_graph.set_vertex_buffer_descriptor(vertex_buffer_descriptor.clone());
}
}
}
@ -463,7 +465,8 @@ where
}
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
self.initialize_vertex_buffer_descriptor(renderer);
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
self.initialize_vertex_buffer_descriptor(&mut render_graph);
// TODO: this breaks down in multiple ways:
// (SOLVED 1) resource_info will be set after the first run so this won't update.

View file

@ -106,11 +106,7 @@ fn try_compiling_shader_with_macros(
Some(compiled_shader_handle)
}
}
pub fn update_shader_assignments(
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
) {
pub fn update_shader_assignments(world: &mut World, resources: &mut Resources) {
// 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
{
@ -118,6 +114,7 @@ pub fn update_shader_assignments(
resources.get_mut::<ShaderPipelineAssignments>().unwrap();
let mut compiled_shader_map = resources.get_mut::<CompiledShaderMap>().unwrap();
let mut shader_storage = resources.get_mut::<AssetStorage<Shader>>().unwrap();
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
let mut pipeline_descriptor_storage = resources
.get_mut::<AssetStorage<PipelineDescriptor>>()
.unwrap();

View file

@ -1,37 +1,20 @@
use crate::{
legion::prelude::*,
render::{
pipeline::{PipelineDescriptor, VertexBufferDescriptor},
render_graph::RenderGraph,
render_resource::{RenderResource, RenderResources, ResourceInfo, RenderResourceAssignments, BufferInfo},
pipeline::PipelineDescriptor,
render_resource::{
BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
},
texture::{SamplerDescriptor, TextureDescriptor},
},
};
use std::ops::Range;
pub trait Renderer {
fn initialize(
&mut self,
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
);
fn resize(
&mut self,
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
width: u32,
height: u32,
);
fn process_render_graph(
&mut self,
render_graph: &mut RenderGraph,
world: &mut World,
resources: &mut Resources,
);
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8])
-> RenderResource;
fn initialize(&mut self, world: &mut World, resources: &mut Resources);
fn resize(&mut self, world: &mut World, resources: &mut Resources);
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,
@ -64,8 +47,6 @@ pub trait Renderer {
render_resource_assignments: &RenderResourceAssignments,
pipeline_descriptor: &PipelineDescriptor,
);
fn set_vertex_buffer_descriptor(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor);
fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor>;
}
pub trait RenderPass {

View file

@ -1,7 +1,7 @@
use super::{WgpuRenderer, WgpuResources};
use crate::render::{
pipeline::{BindType, PipelineDescriptor},
render_resource::{RenderResource, RenderResourceAssignments, ResourceInfo, BufferInfo},
render_resource::{BufferInfo, RenderResource, RenderResourceAssignments, ResourceInfo},
renderer::{RenderPass, Renderer},
};
use std::ops::Range;
@ -74,7 +74,8 @@ impl<'a, 'b, 'c, 'd> RenderPass for WgpuRenderPass<'a, 'b, 'c, 'd> {
if let Some(ResourceInfo::Buffer(BufferInfo {
dynamic_uniform_info: Some(dynamic_uniform_info),
..
})) = self.wgpu_resources.resource_info.get(&resource) {
})) = self.wgpu_resources.resource_info.get(&resource)
{
let index = dynamic_uniform_info
.offsets
.get(&render_resource_assignments.unwrap().get_id())

View file

@ -7,19 +7,16 @@ use crate::{
PassDescriptor, RenderPassColorAttachmentDescriptor,
RenderPassDepthStencilAttachmentDescriptor,
},
pipeline::{
BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType,
VertexBufferDescriptor,
},
pipeline::{BindType, PipelineDescriptor, PipelineLayout, PipelineLayoutType},
render_graph::RenderGraph,
render_resource::{
resource_name, BufferInfo, RenderResource, RenderResourceAssignments,
RenderResources, ResourceInfo,
resource_name, BufferInfo, RenderResource, RenderResourceAssignments, RenderResources,
ResourceInfo,
},
renderer::Renderer,
shader::{Shader},
shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor},
update_shader_assignments, Vertex,
update_shader_assignments,
},
};
use std::{collections::HashMap, ops::Deref};
@ -31,7 +28,6 @@ pub struct WgpuRenderer {
pub encoder: Option<wgpu::CommandEncoder>,
pub swap_chain_descriptor: wgpu::SwapChainDescriptor,
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub vertex_buffer_descriptors: HashMap<String, VertexBufferDescriptor>,
pub wgpu_resources: WgpuResources,
}
@ -68,7 +64,6 @@ impl WgpuRenderer {
swap_chain_descriptor,
wgpu_resources: WgpuResources::new(),
render_pipelines: HashMap::new(),
vertex_buffer_descriptors: HashMap::new(),
}
}
@ -335,12 +330,8 @@ impl WgpuRenderer {
device.create_shader_module(&shader.get_spirv(macros))
}
pub fn initialize_resource_providers(
&mut self,
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
) {
pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
self.encoder = Some(
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
@ -353,77 +344,9 @@ impl WgpuRenderer {
let command_buffer = self.encoder.take().unwrap().finish();
self.queue.submit(&[command_buffer]);
}
}
impl Renderer for WgpuRenderer {
fn initialize(
&mut self,
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
) {
let (surface, window_size) = {
let window = resources.get::<winit::window::Window>().unwrap();
let surface = wgpu::Surface::create(window.deref());
let window_size = window.inner_size();
(surface, window_size)
};
self.surface = Some(surface);
self.initialize_resource_providers(world, resources, render_graph);
self.resize(
world,
resources,
render_graph,
window_size.width,
window_size.height,
);
}
fn resize(
&mut self,
world: &mut World,
resources: &mut Resources,
render_graph: &mut RenderGraph,
width: u32,
height: u32,
) {
self.encoder = Some(
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
);
self.swap_chain_descriptor.width = width;
self.swap_chain_descriptor.height = height;
let swap_chain = self
.device
.create_swap_chain(self.surface.as_ref().unwrap(), &self.swap_chain_descriptor);
// WgpuRenderer can't own swap_chain without creating lifetime ergonomics issues, so lets just store it in World.
resources.insert(swap_chain);
for resource_provider in render_graph.resource_providers.iter_mut() {
resource_provider.resize(self, world, resources, width, height);
}
// consume current encoder
let command_buffer = self.encoder.take().unwrap().finish();
self.queue.submit(&[command_buffer]);
}
fn process_render_graph(
&mut self,
render_graph: &mut RenderGraph,
world: &mut World,
resources: &mut Resources,
) {
// TODO: this self.encoder handoff is a bit gross, but its here to give resource providers access to buffer copies without
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
self.encoder = Some(
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
);
pub fn update_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
for resource_provider in render_graph.resource_providers.iter_mut() {
resource_provider.update(self, world, resources);
}
@ -431,15 +354,76 @@ impl Renderer for WgpuRenderer {
for resource_provider in render_graph.resource_providers.iter_mut() {
resource_provider.finish_update(self, world, resources);
}
}
update_shader_assignments(world, resources, render_graph);
pub fn create_queued_textures(&mut self, resources: &mut Resources) {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
for (name, texture_descriptor) in render_graph.queued_textures.drain(..) {
let resource = self.create_texture(&texture_descriptor, None);
self.wgpu_resources
.render_resources
.set_named_resource(&name, resource);
}
}
pub fn create_surface(&mut self, resources: &Resources) {
let window = resources.get::<winit::window::Window>().unwrap();
let surface = wgpu::Surface::create(window.deref());
self.surface = Some(surface);
}
}
impl Renderer for WgpuRenderer {
fn initialize(&mut self, world: &mut World, resources: &mut Resources) {
self.create_surface(resources);
self.initialize_resource_providers(world, resources);
self.resize(world, resources);
}
fn resize(&mut self, world: &mut World, resources: &mut Resources) {
let window_size = {
let window = resources.get::<winit::window::Window>().unwrap();
window.inner_size()
};
self.encoder = Some(
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
);
self.swap_chain_descriptor.width = window_size.width;
self.swap_chain_descriptor.height = window_size.height;
let swap_chain = self
.device
.create_swap_chain(self.surface.as_ref().unwrap(), &self.swap_chain_descriptor);
// WgpuRenderer can't own swap_chain without creating lifetime ergonomics issues, so lets just store it in World.
resources.insert(swap_chain);
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
for resource_provider in render_graph.resource_providers.iter_mut() {
resource_provider.resize(
self,
world,
resources,
window_size.width,
window_size.height,
);
}
// consume current encoder
let command_buffer = self.encoder.take().unwrap().finish();
self.queue.submit(&[command_buffer]);
}
fn update(&mut self, world: &mut World, resources: &mut Resources) {
// TODO: this self.encoder handoff is a bit gross, but its here to give resource providers access to buffer copies without
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
self.encoder = Some(
self.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { todo: 0 }),
);
self.update_resource_providers(world, resources);
update_shader_assignments(world, resources);
self.create_queued_textures(resources);
let mut encoder = self.encoder.take().unwrap();
@ -455,7 +439,8 @@ impl Renderer for WgpuRenderer {
.get_mut::<AssetStorage<PipelineDescriptor>>()
.unwrap();
let shader_storage = resources.get::<AssetStorage<Shader>>().unwrap();
let render_graph = resources.get::<RenderGraph>().unwrap();
let mut render_graph_mut = resources.get_mut::<RenderGraph>().unwrap();
for pipeline_descriptor_handle in render_graph.pipeline_descriptors.iter() {
let pipeline_descriptor = pipeline_storage
.get_mut(pipeline_descriptor_handle)
@ -498,8 +483,10 @@ impl Renderer for WgpuRenderer {
for pass_pipeline in pass_pipelines.iter() {
let pipeline_descriptor = pipeline_storage.get(pass_pipeline).unwrap();
for draw_target_name in pipeline_descriptor.draw_targets.iter() {
let draw_target =
render_graph.draw_targets.get_mut(draw_target_name).unwrap();
let draw_target = render_graph_mut
.draw_targets
.get_mut(draw_target_name)
.unwrap();
draw_target.setup(world, resources, self, *pass_pipeline);
}
}
@ -644,13 +631,4 @@ impl Renderer for WgpuRenderer {
}
}
}
fn set_vertex_buffer_descriptor(&mut self, vertex_buffer_descriptor: VertexBufferDescriptor) {
self.vertex_buffer_descriptors.insert(
vertex_buffer_descriptor.name.to_string(),
vertex_buffer_descriptor,
);
}
fn get_vertex_buffer_descriptor(&self, name: &str) -> Option<&VertexBufferDescriptor> {
self.vertex_buffer_descriptors.get(name)
}
}

View file

@ -1,11 +1,10 @@
use crate::{
render::{
pipeline::{BindGroup, BindType},
render_resource::{
RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, RenderResourceAssignmentsId, BufferInfo,
},
texture::{SamplerDescriptor, TextureDescriptor},
use crate::render::{
pipeline::{BindGroup, BindType},
render_resource::{
BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceAssignmentsId,
RenderResources, ResourceInfo,
},
texture::{SamplerDescriptor, TextureDescriptor},
};
use std::collections::HashMap;
@ -74,8 +73,7 @@ impl WgpuResources {
dynamic: _,
properties: _,
} => {
if let ResourceInfo::Buffer(buffer_info) = resource_info
{
if let ResourceInfo::Buffer(buffer_info) = resource_info {
let buffer = self.buffers.get(&resource).unwrap();
wgpu::BindingResource::Buffer {
buffer,
@ -107,7 +105,8 @@ impl WgpuResources {
render_resource_assignment_id: RenderResourceAssignmentsId,
bind_group_id: u64,
) -> Option<&BindGroupInfo> {
self.assignment_bind_groups.get(&(render_resource_assignment_id, bind_group_id))
self.assignment_bind_groups
.get(&(render_resource_assignment_id, bind_group_id))
}
pub fn create_assignments_bind_group(
@ -160,7 +159,8 @@ impl WgpuResources {
} else {
panic!(
"No resource assigned to uniform \"{}\" for RenderResourceAssignments {:?}",
binding.name, render_resource_assignments.get_id()
binding.name,
render_resource_assignments.get_id()
);
}
})
@ -173,8 +173,10 @@ impl WgpuResources {
let bind_group = device.create_bind_group(&bind_group_descriptor);
// TODO: storing a large number entity bind groups might actually be really bad. make sure this is ok
self.assignment_bind_groups
.insert((render_resource_assignments.get_id(), bind_group_id), BindGroupInfo { bind_group });
self.assignment_bind_groups.insert(
(render_resource_assignments.get_id(), bind_group_id),
BindGroupInfo { bind_group },
);
}
pub fn create_buffer(
@ -203,10 +205,7 @@ impl WgpuResources {
buffer_info.size = data.len() as u64;
let resource = self.render_resources.get_next_resource();
let buffer = device.create_buffer_with_data(data, buffer_info.buffer_usage.into());
self.add_resource_info(
resource,
ResourceInfo::Buffer(buffer_info),
);
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
self.buffers.insert(resource, buffer);
resource
@ -227,15 +226,13 @@ impl WgpuResources {
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8]),
) -> RenderResource {
let mut mapped = device.create_buffer_mapped(buffer_info.size as usize, buffer_info.buffer_usage.into());
let mut mapped =
device.create_buffer_mapped(buffer_info.size as usize, buffer_info.buffer_usage.into());
setup_data(&mut mapped.data);
let buffer = mapped.finish();
let resource = self.render_resources.get_next_resource();
self.add_resource_info(
resource,
ResourceInfo::Buffer(buffer_info),
);
self.add_resource_info(resource, ResourceInfo::Buffer(buffer_info));
self.buffers.insert(resource, buffer);
resource

View file

@ -189,4 +189,4 @@ impl GetTexture for ColorSource {
pub struct UniformInfo<'a> {
pub name: &'a str,
pub bind_type: BindType,
}
}