RenderContext, RenderResourceContext and wgpu implementations

This commit is contained in:
Carter Anderson 2020-04-11 18:40:30 -07:00
parent 08abef1c75
commit 394b7ce940
18 changed files with 850 additions and 359 deletions

View File

@ -16,15 +16,15 @@ impl RenderResource {
// TODO: consider scoping breaking these mappings up by type: Texture, Sampler, etc // TODO: consider scoping breaking these mappings up by type: Texture, Sampler, etc
// the overlap could cause accidents. // the overlap could cause accidents.
#[derive(Default)] #[derive(Default)]
pub struct RenderResources { pub struct AssetResources {
pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>, pub texture_to_resource: HashMap<Handle<Texture>, RenderResource>,
pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>, pub texture_to_sampler_resource: HashMap<Handle<Texture>, RenderResource>,
pub mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>, pub mesh_to_vertices_resource: HashMap<Handle<Mesh>, RenderResource>,
pub mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>, pub mesh_to_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
} }
impl RenderResources { impl AssetResources {
pub fn consume(&mut self, render_resources: RenderResources) { pub fn consume(&mut self, render_resources: AssetResources) {
// TODO: this is brittle. consider a single change-stream-based approach instead? // 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_resource.extend(render_resources.texture_to_resource);
self.texture_to_sampler_resource.extend(render_resources.texture_to_sampler_resource); self.texture_to_sampler_resource.extend(render_resources.texture_to_sampler_resource);

View File

@ -48,10 +48,10 @@ impl Camera2dResourceProvider {
let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d(); let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d();
if let Some(old_tmp_buffer) = self.tmp_buffer { if let Some(old_tmp_buffer) = self.tmp_buffer {
render_context.remove_buffer(old_tmp_buffer); render_context.resources_mut().remove_buffer(old_tmp_buffer);
} }
self.tmp_buffer = Some(render_context.create_buffer_mapped( self.tmp_buffer = Some(render_context.resources_mut().create_buffer_mapped(
BufferInfo { BufferInfo {
size: matrix_size, size: matrix_size,
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
@ -81,7 +81,7 @@ impl ResourceProvider for Camera2dResourceProvider {
_world: &mut World, _world: &mut World,
resources: &Resources, resources: &Resources,
) { ) {
let buffer = render_context.create_buffer(BufferInfo { let buffer = render_context.resources_mut().create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>(), size: std::mem::size_of::<[[f32; 4]; 4]>(),
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default() ..Default::default()

View File

@ -45,10 +45,10 @@ impl CameraResourceProvider {
(camera.view_matrix * local_to_world.0).to_cols_array_2d(); (camera.view_matrix * local_to_world.0).to_cols_array_2d();
if let Some(old_tmp_buffer) = self.tmp_buffer { if let Some(old_tmp_buffer) = self.tmp_buffer {
render_context.remove_buffer(old_tmp_buffer); render_context.resources_mut().remove_buffer(old_tmp_buffer);
} }
self.tmp_buffer = Some(render_context.create_buffer_mapped( self.tmp_buffer = Some(render_context.resources_mut().create_buffer_mapped(
BufferInfo { BufferInfo {
size: matrix_size, size: matrix_size,
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
@ -78,7 +78,7 @@ impl ResourceProvider for CameraResourceProvider {
_world: &mut World, _world: &mut World,
resources: &Resources, resources: &Resources,
) { ) {
let buffer = render_context.create_buffer(BufferInfo { let buffer = render_context.resources_mut().create_buffer(BufferInfo {
size: std::mem::size_of::<[[f32; 4]; 4]>(), size: std::mem::size_of::<[[f32; 4]; 4]>(),
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default() ..Default::default()

View File

@ -34,11 +34,12 @@ impl FrameTextureResourceProvider {
let mut render_resource_assignments = let mut render_resource_assignments =
resources.get_mut::<RenderResourceAssignments>().unwrap(); resources.get_mut::<RenderResourceAssignments>().unwrap();
let render_resources = render_context.resources_mut();
if let Some(old_resource) = render_resource_assignments.get(&self.name) { if let Some(old_resource) = render_resource_assignments.get(&self.name) {
render_context.remove_texture(old_resource); render_resources.remove_texture(old_resource);
} }
let texture_resource = render_context.create_texture(&self.descriptor); let texture_resource = render_resources.create_texture(&self.descriptor);
render_resource_assignments.set(&self.name, texture_resource); render_resource_assignments.set(&self.name, texture_resource);
} }
} }

View File

@ -46,16 +46,17 @@ impl LightResourceProvider {
let size = std::mem::size_of::<LightRaw>(); let size = std::mem::size_of::<LightRaw>();
let total_size = size * light_count; let total_size = size * light_count;
let light_count_size = std::mem::size_of::<LightCount>(); let light_count_size = std::mem::size_of::<LightCount>();
let render_resources = render_context.resources_mut();
if let Some(old_tmp_light_buffer) = self.tmp_light_buffer { if let Some(old_tmp_light_buffer) = self.tmp_light_buffer {
render_context.remove_buffer(old_tmp_light_buffer); render_resources.remove_buffer(old_tmp_light_buffer);
} }
if let Some(old_tmp_count_buffer) = self.tmp_count_buffer { if let Some(old_tmp_count_buffer) = self.tmp_count_buffer {
render_context.remove_buffer(old_tmp_count_buffer); render_resources.remove_buffer(old_tmp_count_buffer);
} }
self.tmp_light_buffer = Some(render_context.create_buffer_mapped( self.tmp_light_buffer = Some(render_resources.create_buffer_mapped(
BufferInfo { BufferInfo {
size: total_size, size: total_size,
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
@ -71,7 +72,7 @@ impl LightResourceProvider {
} }
}, },
)); ));
self.tmp_count_buffer = Some(render_context.create_buffer_mapped( self.tmp_count_buffer = Some(render_resources.create_buffer_mapped(
BufferInfo { BufferInfo {
size: light_count_size, size: light_count_size,
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
@ -111,7 +112,7 @@ impl ResourceProvider for LightResourceProvider {
let light_uniform_size = let light_uniform_size =
std::mem::size_of::<LightCount>() + self.max_lights * std::mem::size_of::<LightRaw>(); std::mem::size_of::<LightCount>() + self.max_lights * std::mem::size_of::<LightRaw>();
let buffer = render_context.create_buffer(BufferInfo { let buffer = render_context.resources_mut().create_buffer(BufferInfo {
size: light_uniform_size, size: light_uniform_size,
buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST, buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST,
..Default::default() ..Default::default()

View File

@ -44,24 +44,25 @@ impl MeshResourceProvider {
handle: Handle<Mesh>, handle: Handle<Mesh>,
render_resource_assignments: &mut RenderResourceAssignments, render_resource_assignments: &mut RenderResourceAssignments,
) { ) {
let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = render_context let render_resources = render_context.resources_mut();
let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = render_resources
.get_mesh_vertices_resource(handle) .get_mesh_vertices_resource(handle)
{ {
( (
vertex_buffer, vertex_buffer,
render_context render_resources
.get_mesh_indices_resource(handle), .get_mesh_indices_resource(handle),
) )
} else { } else {
let mesh_asset = mesh_storage.get(&handle).unwrap(); let mesh_asset = mesh_storage.get(&handle).unwrap();
let vertex_buffer = render_context.create_buffer_with_data( let vertex_buffer = render_resources.create_buffer_with_data(
BufferInfo { BufferInfo {
buffer_usage: BufferUsage::VERTEX, buffer_usage: BufferUsage::VERTEX,
..Default::default() ..Default::default()
}, },
mesh_asset.vertices.as_bytes(), mesh_asset.vertices.as_bytes(),
); );
let index_buffer = render_context.create_buffer_with_data( let index_buffer = render_resources.create_buffer_with_data(
BufferInfo { BufferInfo {
buffer_usage: BufferUsage::INDEX, buffer_usage: BufferUsage::INDEX,
..Default::default() ..Default::default()
@ -69,9 +70,9 @@ impl MeshResourceProvider {
mesh_asset.indices.as_bytes(), mesh_asset.indices.as_bytes(),
); );
let render_resources = render_context.local_render_resources_mut(); let asset_resources = render_resources.asset_resources_mut();
render_resources.set_mesh_vertices_resource(handle, vertex_buffer); asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
render_resources.set_mesh_indices_resource(handle, index_buffer); asset_resources.set_mesh_indices_resource(handle, index_buffer);
(vertex_buffer, Some(index_buffer)) (vertex_buffer, Some(index_buffer))
}; };
@ -90,7 +91,7 @@ impl ResourceProvider for MeshResourceProvider {
vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap()); vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
} }
fn update(&mut self, _render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) { fn update(&mut self, _render_context: &mut dyn RenderContext, _world: &mut World, _resources: &Resources) {
} }
fn finish_update( fn finish_update(
@ -99,7 +100,7 @@ impl ResourceProvider for MeshResourceProvider {
_world: &mut World, _world: &mut World,
resources: &Resources, resources: &Resources,
) { ) {
let mut mesh_storage = resources.get::<AssetStorage<Mesh>>().unwrap(); let mesh_storage = resources.get::<AssetStorage<Mesh>>().unwrap();
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap(); let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
// this scope is necessary because the Fetch<AssetBatchers> pointer behaves weirdly // this scope is necessary because the Fetch<AssetBatchers> pointer behaves weirdly

View File

@ -2,11 +2,12 @@ use crate::{
pipeline::VertexBufferDescriptors, pipeline::VertexBufferDescriptors,
render_resource::{ render_resource::{
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource, AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
RenderResourceAssignments, ResourceInfo, ResourceProvider, RenderResourceAssignmentsId, RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, ResourceProvider,
}, },
renderer_2::{RenderContext, RenderResourceContext},
shader::{AsUniforms, FieldBindType}, shader::{AsUniforms, FieldBindType},
texture::{SamplerDescriptor, Texture, TextureDescriptor}, texture::{SamplerDescriptor, Texture, TextureDescriptor},
Renderable, renderer_2::RenderContext, Renderable,
}; };
use bevy_asset::{AssetStorage, Handle}; use bevy_asset::{AssetStorage, Handle};
use legion::{filter::*, prelude::*}; use legion::{filter::*, prelude::*};
@ -51,6 +52,7 @@ struct QueuedBufferWrite {
offset: usize, offset: usize,
} }
// TODO: make these queries only update changed T components
type UniformQuery<T> = Query< type UniformQuery<T> = Query<
(Read<T>, Write<Renderable>), (Read<T>, Write<Renderable>),
EntityFilterTuple< EntityFilterTuple<
@ -262,11 +264,10 @@ where
} }
} }
fn setup_uniform_resources( fn setup_uniform_buffer_resources(
&mut self, &mut self,
uniforms: &T, uniforms: &T,
render_context: &mut dyn RenderContext, render_resources: &mut dyn RenderResourceContext,
resources: &Resources,
render_resource_assignments: &mut RenderResourceAssignments, render_resource_assignments: &mut RenderResourceAssignments,
staging_buffer: &mut [u8], staging_buffer: &mut [u8],
) { ) {
@ -282,10 +283,10 @@ where
array_info: Some(ref array_info), array_info: Some(ref array_info),
is_dynamic: true, is_dynamic: true,
.. ..
})) = render_context.get_resource_info(buffer) })) = render_resources.get_resource_info(buffer)
{ {
let index = let index = uniform_buffer_status
uniform_buffer_status.get_or_assign_index(render_resource_assignments.id); .get_or_assign_index(render_resource_assignments.id);
render_resource_assignments.set_indexed( render_resource_assignments.set_indexed(
&field_info.uniform_name, &field_info.uniform_name,
buffer, buffer,
@ -301,7 +302,7 @@ where
{ {
Some(render_resource) => render_resource, Some(render_resource) => render_resource,
None => { None => {
let resource = render_context.create_buffer(BufferInfo { let resource = render_resources.create_buffer(BufferInfo {
size, size,
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM, buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
..Default::default() ..Default::default()
@ -351,16 +352,33 @@ where
offset: target_offset, offset: target_offset,
}); });
} }
_ => {}
}
}
}
fn setup_uniform_texture_resources(
&mut self,
uniforms: &T,
render_context: &mut dyn RenderContext,
resources: &Resources,
render_resource_assignments: &mut RenderResourceAssignments,
) {
for field_info in T::get_field_infos().iter() {
let bind_type = uniforms.get_field_bind_type(&field_info.name);
match bind_type {
Some(FieldBindType::Texture) => { Some(FieldBindType::Texture) => {
let texture_handle = uniforms let texture_handle = uniforms
.get_uniform_texture(&field_info.texture_name) .get_uniform_texture(&field_info.texture_name)
.unwrap(); .unwrap();
let (texture_resource, sampler_resource) = match render_context let (texture_resource, sampler_resource) = match render_context
.resources()
.get_texture_resource(texture_handle) .get_texture_resource(texture_handle)
{ {
Some(texture_resource) => ( Some(texture_resource) => (
texture_resource, texture_resource,
render_context render_context
.resources()
.get_texture_sampler_resource(texture_handle) .get_texture_sampler_resource(texture_handle)
.unwrap(), .unwrap(),
), ),
@ -369,15 +387,17 @@ where
let texture = storage.get(&texture_handle).unwrap(); let texture = storage.get(&texture_handle).unwrap();
let texture_descriptor: TextureDescriptor = texture.into(); let texture_descriptor: TextureDescriptor = texture.into();
let texture_resource = let texture_resource = render_context
render_context.create_texture_with_data(&texture_descriptor, &texture.data); .create_texture_with_data(&texture_descriptor, &texture.data);
let render_resources = render_context.resources_mut();
let sampler_descriptor: SamplerDescriptor = texture.into(); let sampler_descriptor: SamplerDescriptor = texture.into();
let sampler_resource = render_context.create_sampler(&sampler_descriptor); let sampler_resource =
render_resources.create_sampler(&sampler_descriptor);
let render_resources = render_context.local_render_resources_mut(); let asset_resources = render_resources.asset_resources_mut();
render_resources.set_texture_resource(texture_handle, texture_resource); asset_resources.set_texture_resource(texture_handle, texture_resource);
render_resources asset_resources
.set_texture_sampler_resource(texture_handle, sampler_resource); .set_texture_sampler_resource(texture_handle, sampler_resource);
(texture_resource, sampler_resource) (texture_resource, sampler_resource)
} }
@ -386,16 +406,17 @@ where
render_resource_assignments.set(field_info.texture_name, texture_resource); render_resource_assignments.set(field_info.texture_name, texture_resource);
render_resource_assignments.set(field_info.sampler_name, sampler_resource); render_resource_assignments.set(field_info.sampler_name, sampler_resource);
} }
None => {} _ => {}
} }
} }
} }
fn setup_uniforms_resources( // TODO: the current WgpuRenderContext mapped-memory interface forced these to be separate, but thats inefficient / redundant
// try to merge setup_uniforms_buffer_resources and setup_uniforms_texture_resources if possible
fn setup_uniforms_buffer_resources(
&mut self, &mut self,
world: &mut World, world: &mut World,
resources: &Resources, render_resources: &mut dyn RenderResourceContext,
render_context: &mut dyn RenderContext,
staging_buffer: &mut [u8], staging_buffer: &mut [u8],
) { ) {
let query_finish = self.query_finish.take().unwrap(); let query_finish = self.query_finish.take().unwrap();
@ -410,12 +431,41 @@ where
std::any::type_name::<T>() std::any::type_name::<T>()
); );
} else { } else {
self.setup_uniform_resources( self.setup_uniform_buffer_resources(
&uniforms,
render_resources,
&mut renderable.render_resource_assignments,
staging_buffer,
);
}
}
self.query_finish = Some(query_finish);
}
fn setup_uniforms_texture_resources(
&mut self,
world: &mut World,
resources: &Resources,
render_context: &mut dyn RenderContext,
) {
let query_finish = self.query_finish.take().unwrap();
for (uniforms, mut renderable) in query_finish.iter_mut(world) {
if !renderable.is_visible {
return;
}
if renderable.is_instanced {
panic!(
"Cannot instance uniforms of type {0}. Only Handle<{0}> can be instanced.",
std::any::type_name::<T>()
);
} else {
self.setup_uniform_texture_resources(
&uniforms, &uniforms,
render_context, render_context,
resources, resources,
&mut renderable.render_resource_assignments, &mut renderable.render_resource_assignments,
staging_buffer,
) )
} }
} }
@ -423,11 +473,11 @@ where
self.query_finish = Some(query_finish); self.query_finish = Some(query_finish);
} }
fn setup_handles_resources( fn setup_handles_buffer_resources(
&mut self, &mut self,
world: &mut World, world: &mut World,
resources: &Resources, resources: &Resources,
render_context: &mut dyn RenderContext, render_resources: &mut dyn RenderResourceContext,
staging_buffer: &mut [u8], staging_buffer: &mut [u8],
) { ) {
let assets = resources.get::<AssetStorage<T>>(); let assets = resources.get::<AssetStorage<T>>();
@ -441,12 +491,40 @@ where
let uniforms = assets let uniforms = assets
.get(&handle) .get(&handle)
.expect("Handle points to a non-existent resource"); .expect("Handle points to a non-existent resource");
self.setup_uniform_resources( self.setup_uniform_buffer_resources(
&uniforms,
render_resources,
&mut renderable.render_resource_assignments,
staging_buffer,
);
}
self.handle_query_finish = Some(handle_query_finish);
}
}
fn setup_handles_texture_resources(
&mut self,
world: &mut World,
resources: &Resources,
render_context: &mut dyn RenderContext,
) {
let assets = resources.get::<AssetStorage<T>>();
if let Some(assets) = assets {
let handle_query_finish = self.handle_query_finish.take().unwrap();
for (handle, mut renderable) in handle_query_finish.iter_mut(world) {
if !renderable.is_visible || renderable.is_instanced {
return;
}
let uniforms = assets
.get(&handle)
.expect("Handle points to a non-existent resource");
self.setup_uniform_texture_resources(
&uniforms, &uniforms,
render_context, render_context,
resources, resources,
&mut renderable.render_resource_assignments, &mut renderable.render_resource_assignments,
staging_buffer,
) )
} }
@ -476,12 +554,17 @@ where
.unwrap(); .unwrap();
if let Some(uniforms) = asset_storage.get(&handle) { if let Some(uniforms) = asset_storage.get(&handle) {
self.setup_uniform_resources( self.setup_uniform_buffer_resources(
uniforms, &uniforms,
render_context.resources_mut(),
&mut batch.render_resource_assignments,
staging_buffer,
);
self.setup_uniform_texture_resources(
&uniforms,
render_context, render_context,
resources, resources,
&mut batch.render_resource_assignments, &mut batch.render_resource_assignments,
staging_buffer,
); );
Self::update_shader_defs(&uniforms, &mut batch.render_resource_assignments); Self::update_shader_defs(&uniforms, &mut batch.render_resource_assignments);
@ -516,7 +599,7 @@ where
if let Some(ResourceInfo::Buffer(BufferInfo { if let Some(ResourceInfo::Buffer(BufferInfo {
array_info: Some(array_info), array_info: Some(array_info),
.. ..
})) = render_context.get_resource_info(buffer) })) = render_context.resources().get_resource_info(buffer)
{ {
if array_info.item_capacity < buffer_array_status.new_item_count { if array_info.item_capacity < buffer_array_status.new_item_count {
// over capacity. lets resize // over capacity. lets resize
@ -544,7 +627,7 @@ where
let total_size = item_size * new_capacity; let total_size = item_size * new_capacity;
let buffer = render_context.create_buffer(BufferInfo { let buffer = render_context.resources_mut().create_buffer(BufferInfo {
array_info: Some(BufferArrayInfo { array_info: Some(BufferArrayInfo {
item_capacity: new_capacity, item_capacity: new_capacity,
item_size, item_size,
@ -634,7 +717,12 @@ where
self.update(render_context, world, resources); self.update(render_context, world, resources);
} }
fn update(&mut self, _render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) { fn update(
&mut self,
_render_context: &mut dyn RenderContext,
world: &mut World,
resources: &Resources,
) {
self.reset_buffer_array_status_counts(); self.reset_buffer_array_status_counts();
self.update_uniforms_info(world); self.update_uniforms_info(world);
self.update_uniform_handles_info(world, resources); self.update_uniform_handles_info(world, resources);
@ -650,27 +738,56 @@ where
self.setup_buffer_arrays(render_context); self.setup_buffer_arrays(render_context);
let staging_buffer_size = self.update_staging_buffer_offsets(); 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_batched_texture_resources(world, resources, renderer, staging_buffer);
if staging_buffer_size == 0 { if staging_buffer_size == 0 {
let mut staging_buffer: [u8; 0] = []; let mut staging_buffer: [u8; 0] = [];
self.setup_uniforms_resources(world, resources, render_context, &mut staging_buffer); self.setup_uniforms_buffer_resources(
self.setup_handles_resources(world, resources, render_context, &mut staging_buffer); world,
// self.setup_batched_resources(world, resources, renderer, &mut staging_buffer); render_context.resources_mut(),
&mut staging_buffer,
);
self.setup_handles_buffer_resources(
world,
resources,
render_context.resources_mut(),
&mut staging_buffer,
);
// self.setup_batched_buffer_resources(world, resources, renderer, &mut staging_buffer);
} else { } else {
let staging_buffer = render_context.create_buffer_mapped( let staging_buffer = render_context.resources_mut().create_buffer_mapped(
BufferInfo { BufferInfo {
buffer_usage: BufferUsage::COPY_SRC, buffer_usage: BufferUsage::COPY_SRC,
size: staging_buffer_size, size: staging_buffer_size,
..Default::default() ..Default::default()
}, },
&mut |staging_buffer, renderer| { &mut |staging_buffer, render_resources| {
self.setup_uniforms_resources(world, resources, renderer, staging_buffer); self.setup_uniforms_buffer_resources(
self.setup_handles_resources(world, resources, renderer, staging_buffer); world,
// self.setup_batched_resources(world, resources, renderer, staging_buffer); render_resources,
staging_buffer,
);
self.setup_handles_buffer_resources(
world,
resources,
render_resources,
staging_buffer,
);
// self.setup_batched_buffer_resources(world, resources, renderer, staging_buffer);
}, },
); );
self.copy_staging_buffer_to_final_buffers(render_context, staging_buffer); self.copy_staging_buffer_to_final_buffers(render_context, staging_buffer);
render_context.remove_buffer(staging_buffer); render_context.resources_mut().remove_buffer(staging_buffer);
} }
} }
} }

View File

@ -1,7 +1,7 @@
use crate::{ use crate::{
pipeline::PipelineDescriptor, pipeline::PipelineDescriptor,
render_resource::{ render_resource::{
BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo, BufferInfo, RenderResource, RenderResourceAssignments, AssetResources, ResourceInfo,
}, },
shader::Shader, shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor}, texture::{SamplerDescriptor, TextureDescriptor},
@ -38,8 +38,8 @@ pub trait Renderer {
destination_offset: u64, destination_offset: u64,
size: u64, size: u64,
); );
fn get_render_resources(&self) -> &RenderResources; fn get_render_resources(&self) -> &AssetResources;
fn get_render_resources_mut(&mut self) -> &mut RenderResources; fn get_render_resources_mut(&mut self) -> &mut AssetResources;
fn setup_render_pipeline( fn setup_render_pipeline(
&mut self, &mut self,
pipeline_handle: Handle<PipelineDescriptor>, pipeline_handle: Handle<PipelineDescriptor>,

View File

@ -1,3 +1,5 @@
mod render_context; mod render_context;
mod render_resource_context;
pub use render_context::*; pub use render_context::*;
pub use render_resource_context::*;

View File

@ -1,35 +1,7 @@
use crate::{ use crate::{render_resource::RenderResource, texture::TextureDescriptor};
render_resource::{ use super::RenderResourceContext;
BufferInfo, RenderResource, RenderResources, ResourceInfo,
},
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
};
use bevy_asset::Handle;
pub trait RenderContext { pub trait RenderContext {
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> 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,
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext),
) -> RenderResource;
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> 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_local_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo>;
fn local_render_resources(&self) -> &RenderResources;
fn local_render_resources_mut(&mut self) -> &mut RenderResources;
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
// fn setup_render_pipeline( // fn setup_render_pipeline(
// &mut self, // &mut self,
// pipeline_handle: Handle<PipelineDescriptor>, // pipeline_handle: Handle<PipelineDescriptor>,
@ -42,6 +14,9 @@ pub trait RenderContext {
// pipeline_descriptor: &PipelineDescriptor, // pipeline_descriptor: &PipelineDescriptor,
// ); // );
fn resources(&self) -> &dyn RenderResourceContext;
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext;
fn create_texture_with_data( fn create_texture_with_data(
&mut self, &mut self,
texture_descriptor: &TextureDescriptor, texture_descriptor: &TextureDescriptor,

View File

@ -0,0 +1,37 @@
use crate::{
render_resource::{
BufferInfo, RenderResource, AssetResources, ResourceInfo,
},
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
};
use bevy_asset::Handle;
pub struct GlobalRenderResourceContext {
pub context: Box<dyn RenderResourceContext + Send + Sync + 'static>,
}
// 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_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource;
fn create_buffer_mapped(
&mut self,
buffer_info: BufferInfo,
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 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 asset_resources(&self) -> &AssetResources;
fn asset_resources_mut(&mut self) -> &mut AssetResources;
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource>;
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource>;
}

View File

@ -1,3 +1,7 @@
mod wgpu_render_context; mod wgpu_render_context;
mod wgpu_render_resource_context;
mod wgpu_transactional_render_resource_context;
pub use wgpu_render_context::*; pub use wgpu_render_context::*;
pub use wgpu_render_resource_context::*;
pub use wgpu_transactional_render_resource_context::*;

View File

@ -1,12 +1,10 @@
use crate::WgpuResources; use super::WgpuRenderResourceContextTrait;
use bevy_render::{ use bevy_render::{
render_resource::{BufferInfo, RenderResource, RenderResources, ResourceInfo}, render_resource::RenderResource,
renderer_2::RenderContext, renderer_2::{RenderContext, RenderResourceContext},
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh, texture::TextureDescriptor,
}; };
use std::sync::Arc; use std::sync::Arc;
use bevy_asset::Handle;
#[derive(Default)] #[derive(Default)]
struct LazyCommandEncoder { struct LazyCommandEncoder {
@ -31,149 +29,71 @@ impl LazyCommandEncoder {
} }
} }
pub struct WgpuRenderContext<'a> { pub struct WgpuRenderContext<T>
where
T: RenderResourceContext,
{
pub device: Arc<wgpu::Device>, pub device: Arc<wgpu::Device>,
local_wgpu_resources: WgpuResources,
command_encoder: LazyCommandEncoder, command_encoder: LazyCommandEncoder,
global_wgpu_resources: &'a WgpuResources, pub render_resources: T,
removed_resources: Vec<RenderResource>,
} }
impl<'a> WgpuRenderContext<'a> { impl<T> WgpuRenderContext<T>
pub fn new(device: Arc<wgpu::Device>, global_wgpu_resources: &'a WgpuResources) -> Self { where
T: RenderResourceContext,
{
pub fn new(device: Arc<wgpu::Device>, resources: T) -> Self {
WgpuRenderContext { WgpuRenderContext {
device, device,
global_wgpu_resources: global_wgpu_resources, render_resources: resources,
command_encoder: LazyCommandEncoder::default(), command_encoder: LazyCommandEncoder::default(),
local_wgpu_resources: WgpuResources::default(),
removed_resources: Vec::new(),
} }
} }
pub fn finish(mut self) -> (Option<wgpu::CommandBuffer>, WgpuResources) { /// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
(self.command_encoder.take().map(|encoder| encoder.finish()), self.local_wgpu_resources) /// This is intended to be called from a worker thread right before synchronizing with the main thread.
pub fn finish(mut self) -> (Option<wgpu::CommandBuffer>, T) {
(
self.command_encoder.take().map(|encoder| encoder.finish()),
self.render_resources,
)
} }
fn get_buffer<'b>(render_resource: RenderResource, local_resources: &'b WgpuResources, global_resources: &'b WgpuResources) -> Option<&'b wgpu::Buffer> { /// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
let buffer = local_resources.buffers.get(&render_resource); /// This is intended to be called from a worker thread right before synchronizing with the main thread.
if buffer.is_some() { pub fn finish_encoder(&mut self) -> Option<wgpu::CommandBuffer> {
return buffer; self.command_encoder.take().map(|encoder| encoder.finish())
}
global_resources.buffers.get(&render_resource)
} }
// fn get_buffer<'b>(
// render_resource: RenderResource,
// local_resources: &'b WgpuResources,
// global_resources: &'b WgpuResources,
// ) -> Option<&'b wgpu::Buffer> {
// let buffer = local_resources.buffers.get(&render_resource);
// if buffer.is_some() {
// return buffer;
// }
// global_resources.buffers.get(&render_resource)
// }
} }
impl<'a> RenderContext for WgpuRenderContext<'a> { impl<T> RenderContext for WgpuRenderContext<T>
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource { where
self.local_wgpu_resources T: RenderResourceContext + WgpuRenderResourceContextTrait,
.create_sampler(&self.device, sampler_descriptor) {
}
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
self.local_wgpu_resources
.create_texture(&self.device, texture_descriptor)
}
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
self.local_wgpu_resources.create_buffer(&self.device, buffer_info)
}
// TODO: clean this up
fn create_buffer_mapped(
&mut self,
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext),
) -> RenderResource {
let buffer = WgpuResources::begin_create_buffer_mapped_render_context(
&buffer_info,
self,
setup_data,
);
self.local_wgpu_resources.assign_buffer(buffer, buffer_info)
}
fn create_texture_with_data( fn create_texture_with_data(
&mut self, &mut self,
texture_descriptor: &TextureDescriptor, texture_descriptor: &TextureDescriptor,
bytes: &[u8], bytes: &[u8],
) -> RenderResource { ) -> RenderResource {
self.local_wgpu_resources.create_texture_with_data( self.render_resources.create_texture_with_data(
&self.device,
self.command_encoder.get_or_create(&self.device), self.command_encoder.get_or_create(&self.device),
texture_descriptor, texture_descriptor,
bytes, bytes,
) )
} }
fn remove_buffer(&mut self, resource: RenderResource) {
self.local_wgpu_resources.remove_buffer(resource);
self.removed_resources.push(resource);
}
fn remove_texture(&mut self, resource: RenderResource) {
self.local_wgpu_resources.remove_texture(resource);
self.removed_resources.push(resource);
}
fn remove_sampler(&mut self, resource: RenderResource) {
self.local_wgpu_resources.remove_sampler(resource);
self.removed_resources.push(resource);
}
// TODO: this pattern is redundant and a bit confusing. make this cleaner if you can
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
let local = self.local_wgpu_resources.render_resources.get_texture_resource(texture);
if local.is_some() {
return local;
}
self.global_wgpu_resources.render_resources.get_texture_resource(texture)
}
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
let local = self.local_wgpu_resources.render_resources.get_texture_sampler_resource(texture);
if local.is_some() {
return local;
}
self.global_wgpu_resources.render_resources.get_texture_sampler_resource(texture)
}
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
let local = self.local_wgpu_resources.render_resources.get_mesh_vertices_resource(mesh);
if local.is_some() {
return local;
}
self.global_wgpu_resources.render_resources.get_mesh_vertices_resource(mesh)
}
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
let local = self.local_wgpu_resources.render_resources.get_mesh_indices_resource(mesh);
if local.is_some() {
return local;
}
self.global_wgpu_resources.render_resources.get_mesh_indices_resource(mesh)
}
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
let local_info = self.local_wgpu_resources.get_resource_info(resource);
if local_info.is_some() {
return local_info;
}
self.global_wgpu_resources.get_resource_info(resource)
}
fn get_local_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
self.local_wgpu_resources.resource_info.get(&resource)
}
fn local_render_resources(&self) -> &RenderResources {
&self.local_wgpu_resources.render_resources
}
fn local_render_resources_mut(&mut self) -> &mut RenderResources {
&mut self.local_wgpu_resources.render_resources
}
fn copy_buffer_to_buffer( fn copy_buffer_to_buffer(
&mut self, &mut self,
source_buffer: RenderResource, source_buffer: RenderResource,
@ -183,12 +103,23 @@ impl<'a> RenderContext for WgpuRenderContext<'a> {
size: u64, size: u64,
) { ) {
let command_encoder = self.command_encoder.get_or_create(&self.device); let command_encoder = self.command_encoder.get_or_create(&self.device);
let source_buffer = Self::get_buffer(source_buffer, &self.local_wgpu_resources, &self.global_wgpu_resources).unwrap(); let source = self.render_resources.get_buffer(source_buffer).unwrap();
let destination_buffer = Self::get_buffer(destination_buffer, &self.local_wgpu_resources, &self.global_wgpu_resources).unwrap(); let destination = self
command_encoder.copy_buffer_to_buffer(source_buffer, source_offset, destination_buffer, destination_offset, size); .render_resources
.get_buffer(destination_buffer)
.unwrap();
command_encoder.copy_buffer_to_buffer(
source,
source_offset,
destination,
destination_offset,
size,
);
} }
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource { fn resources(&self) -> &dyn RenderResourceContext {
self.local_wgpu_resources &self.render_resources
.create_buffer_with_data(&self.device, buffer_info, data) }
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext {
&mut self.render_resources
} }
} }

View File

@ -0,0 +1,133 @@
use crate::WgpuResources;
use bevy_asset::Handle;
use bevy_render::{
mesh::Mesh,
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
renderer_2::RenderResourceContext,
texture::{SamplerDescriptor, Texture, TextureDescriptor},
};
use std::sync::Arc;
pub struct WgpuRenderResourceContext {
pub device: Arc<wgpu::Device>,
pub wgpu_resources: WgpuResources,
}
// 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;
}
impl WgpuRenderResourceContextTrait for WgpuRenderResourceContext {
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer> {
self.wgpu_resources.buffers.get(&render_resource)
}
fn create_texture_with_data(
&mut self,
command_encoder: &mut wgpu::CommandEncoder,
texture_descriptor: &TextureDescriptor,
bytes: &[u8],
) -> RenderResource {
self.wgpu_resources
.create_texture_with_data(
&self.device,
command_encoder,
texture_descriptor,
bytes,
)
}
}
impl WgpuRenderResourceContext {
pub fn new(device: Arc<wgpu::Device>) -> Self {
WgpuRenderResourceContext {
device,
wgpu_resources: WgpuResources::default(),
}
}
}
impl RenderResourceContext for WgpuRenderResourceContext {
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
self.wgpu_resources
.create_sampler(&self.device, sampler_descriptor)
}
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
self.wgpu_resources
.create_texture(&self.device, texture_descriptor)
}
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
self.wgpu_resources.create_buffer(&self.device, buffer_info)
}
// TODO: clean this up
fn create_buffer_mapped(
&mut self,
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
) -> RenderResource {
let buffer = WgpuResources::begin_create_buffer_mapped_render_context(
&buffer_info,
self,
setup_data,
);
self.wgpu_resources.assign_buffer(buffer, buffer_info)
}
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource {
self.wgpu_resources
.create_buffer_with_data(&self.device, buffer_info, data)
}
fn remove_buffer(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_buffer(resource);
}
fn remove_texture(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_texture(resource);
}
fn remove_sampler(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_sampler(resource);
}
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_texture_resource(texture)
}
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_texture_sampler_resource(texture)
}
fn get_mesh_vertices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_mesh_vertices_resource(mesh)
}
fn get_mesh_indices_resource(&self, mesh: Handle<Mesh>) -> Option<RenderResource> {
self.wgpu_resources
.asset_resources
.get_mesh_indices_resource(mesh)
}
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
self.wgpu_resources.get_resource_info(resource)
}
fn asset_resources(&self) -> &AssetResources {
&self.wgpu_resources.asset_resources
}
fn asset_resources_mut(&mut self) -> &mut AssetResources {
&mut self.wgpu_resources.asset_resources
}
}

View File

@ -0,0 +1,162 @@
use crate::WgpuResources;
use bevy_asset::Handle;
use bevy_render::{
mesh::Mesh,
render_resource::{AssetResources, BufferInfo, RenderResource, ResourceInfo},
renderer_2::RenderResourceContext,
texture::{SamplerDescriptor, Texture, TextureDescriptor},
};
use std::sync::Arc;
use super::WgpuRenderResourceContextTrait;
pub struct WgpuTransactionalRenderResourceContext<'a> {
pub device: Arc<wgpu::Device>,
pub local_resources: WgpuResources,
pub parent_resources: &'a WgpuResources,
removed_resources: Vec<RenderResource>,
}
impl<'a> WgpuRenderResourceContextTrait for WgpuTransactionalRenderResourceContext<'a> {
fn get_buffer(&self, render_resource: RenderResource) -> Option<&wgpu::Buffer> {
let local = self.local_resources.buffers.get(&render_resource);
if local.is_some() {
return local;
}
self.parent_resources.buffers.get(&render_resource)
}
fn create_texture_with_data(
&mut self,
command_encoder: &mut wgpu::CommandEncoder,
texture_descriptor: &TextureDescriptor,
bytes: &[u8],
) -> RenderResource {
self.local_resources
.create_texture_with_data(
&self.device,
command_encoder,
texture_descriptor,
bytes,
)
}
}
impl<'a> WgpuTransactionalRenderResourceContext<'a> {
pub fn new(device: Arc<wgpu::Device>, parent_resources: &'a WgpuResources) -> Self {
WgpuTransactionalRenderResourceContext {
device,
local_resources: WgpuResources::default(),
parent_resources,
removed_resources: Vec::new(),
}
}
}
impl<'a> RenderResourceContext for WgpuTransactionalRenderResourceContext<'a> {
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
self.local_resources
.create_sampler(&self.device, sampler_descriptor)
}
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
self.local_resources
.create_texture(&self.device, texture_descriptor)
}
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
self.local_resources.create_buffer(&self.device, buffer_info)
}
// TODO: clean this up
fn create_buffer_mapped(
&mut self,
buffer_info: BufferInfo,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
) -> RenderResource {
let buffer = WgpuResources::begin_create_buffer_mapped_transactional_render_context(
&buffer_info,
self,
setup_data,
);
self.local_resources.assign_buffer(buffer, buffer_info)
}
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource {
self.local_resources
.create_buffer_with_data(&self.device, buffer_info, data)
}
fn remove_buffer(&mut self, resource: RenderResource) {
self.local_resources.remove_buffer(resource);
self.removed_resources.push(resource);
}
fn remove_texture(&mut self, resource: RenderResource) {
self.local_resources.remove_texture(resource);
self.removed_resources.push(resource);
}
fn remove_sampler(&mut self, resource: RenderResource) {
self.local_resources.remove_sampler(resource);
self.removed_resources.push(resource);
}
fn get_texture_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
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)
}
fn get_texture_sampler_resource(&self, texture: Handle<Texture>) -> Option<RenderResource> {
let local = self.local_resources
.asset_resources
.get_texture_sampler_resource(texture);
if local.is_some() {
return local;
}
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
.asset_resources
.get_mesh_vertices_resource(mesh);
if local.is_some() {
return local;
}
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
.asset_resources
.get_mesh_indices_resource(mesh);
if local.is_some() {
return local;
}
self.parent_resources.asset_resources.get_mesh_indices_resource(mesh)
}
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
let local = self.local_resources.get_resource_info(resource);
if local.is_some() {
return local;
}
self.parent_resources.get_resource_info(resource)
}
fn asset_resources(&self) -> &AssetResources {
&self.local_resources.asset_resources
}
fn asset_resources_mut(&mut self) -> &mut AssetResources {
&mut self.local_resources.asset_resources
}
}

View File

@ -2,7 +2,7 @@ use super::{
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto}, wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
WgpuRenderPass, WgpuResources, WgpuRenderPass, WgpuResources,
}; };
use crate::renderer_2::WgpuRenderContext; use crate::renderer_2::{WgpuRenderContext, WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext};
use bevy_app::{EventReader, Events}; use bevy_app::{EventReader, Events};
use bevy_asset::{AssetStorage, Handle}; use bevy_asset::{AssetStorage, Handle};
use bevy_render::{ use bevy_render::{
@ -13,7 +13,7 @@ use bevy_render::{
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor}, pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
render_graph::RenderGraph, render_graph::RenderGraph,
render_resource::{ render_resource::{
resource_name, BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, resource_name, AssetResources, BufferInfo, RenderResource, RenderResourceAssignments,
ResourceInfo, ResourceInfo,
}, },
renderer::Renderer, renderer::Renderer,
@ -29,11 +29,10 @@ use std::{
}; };
pub struct WgpuRenderer { pub struct WgpuRenderer {
pub device: Arc<wgpu::Device>, pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
pub queue: wgpu::Queue, pub queue: wgpu::Queue,
pub encoder: Option<wgpu::CommandEncoder>, pub encoder: Option<wgpu::CommandEncoder>,
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>, pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
pub wgpu_resources: WgpuResources,
pub window_resized_event_reader: EventReader<WindowResized>, pub window_resized_event_reader: EventReader<WindowResized>,
pub window_created_event_reader: EventReader<WindowCreated>, pub window_created_event_reader: EventReader<WindowCreated>,
pub intialized: bool, pub intialized: bool,
@ -62,15 +61,17 @@ impl WgpuRenderer {
limits: wgpu::Limits::default(), limits: wgpu::Limits::default(),
}) })
.await; .await;
let device = Arc::new(device);
WgpuRenderer { WgpuRenderer {
device: Arc::new(device), global_context: WgpuRenderContext::new(
device.clone(),
WgpuRenderResourceContext::new(device),
),
queue, queue,
encoder: None, encoder: None,
window_resized_event_reader, window_resized_event_reader,
window_created_event_reader, window_created_event_reader,
intialized: false, intialized: false,
wgpu_resources: WgpuResources::default(),
render_pipelines: HashMap::new(), render_pipelines: HashMap::new(),
} }
} }
@ -214,7 +215,7 @@ impl WgpuRenderer {
pub fn initialize_resource_providers( pub fn initialize_resource_providers(
world: &mut World, world: &mut World,
resources: &mut Resources, resources: &mut Resources,
render_context: &mut WgpuRenderContext, render_context: &mut WgpuRenderContext<WgpuRenderResourceContext>,
) { ) {
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap(); let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
for resource_provider in render_graph.resource_providers.iter_mut() { for resource_provider in render_graph.resource_providers.iter_mut() {
@ -235,58 +236,74 @@ impl WgpuRenderer {
let chunk_size = (render_graph.resource_providers.len() + thread_count - 1) / thread_count; // divide ints rounding remainder up let chunk_size = (render_graph.resource_providers.len() + thread_count - 1) / thread_count; // divide ints rounding remainder up
let mut results = Vec::new(); let mut results = Vec::new();
// crossbeam_utils::thread::scope(|s| { // crossbeam_utils::thread::scope(|s| {
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) { for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
let device = device.clone(); let device = device.clone();
// let sender = sender.clone(); let resource_device = device.clone();
// s.spawn(|_| { // let sender = sender.clone();
let mut render_context = WgpuRenderContext::new(device, global_wgpu_resources); // s.spawn(|_| {
for resource_provider in resource_provider_chunk.iter_mut() { // TODO: replace WgpuResources with Global+Local resources
resource_provider.update(&mut render_context, world, resources); let mut render_context =
} WgpuRenderContext::new(device, WgpuTransactionalRenderResourceContext::new(resource_device, global_wgpu_resources));
results.push(render_context.finish()); for resource_provider in resource_provider_chunk.iter_mut() {
// sender.send(render_context.finish()).unwrap(); resource_provider.update(&mut render_context, world, resources);
// });
} }
results.push(render_context.finish());
// sender.send(render_context.finish()).unwrap();
// });
}
// }); // });
let mut command_buffers = Vec::new(); let mut command_buffers = Vec::new();
for (command_buffer, wgpu_resources) in results { let mut local_resources = Vec::new();
// for i in 0..thread_count { for (command_buffer, render_resources) in results {
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap(); // for i in 0..thread_count {
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
if let Some(command_buffer) = command_buffer { if let Some(command_buffer) = command_buffer {
command_buffers.push(command_buffer); command_buffers.push(command_buffer);
} }
global_wgpu_resources.consume(wgpu_resources); local_resources.push(render_resources.local_resources);
// println!("got {}", i); // println!("got {}", i);
} }
for local_resource in local_resources {
global_wgpu_resources.consume(local_resource);
}
let mut results = Vec::new(); let mut results = Vec::new();
// crossbeam_utils::thread::scope(|s| { // crossbeam_utils::thread::scope(|s| {
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) { for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
let device = device.clone(); // TODO: try to unify this Device usage
// let sender = sender.clone(); let device = device.clone();
// s.spawn(|_| { let resource_device = device.clone();
let mut render_context = WgpuRenderContext::new(device, global_wgpu_resources); // let sender = sender.clone();
for resource_provider in resource_provider_chunk.iter_mut() { // s.spawn(|_| {
resource_provider.finish_update(&mut render_context, world, resources); // TODO: replace WgpuResources with Global+Local resources
} let mut render_context =
results.push(render_context.finish()); WgpuRenderContext::new(device, WgpuTransactionalRenderResourceContext::new(resource_device, global_wgpu_resources));
// sender.send(render_context.finish()).unwrap(); for resource_provider in resource_provider_chunk.iter_mut() {
// }); resource_provider.finish_update(&mut render_context, world, resources);
} }
results.push(render_context.finish());
// sender.send(render_context.finish()).unwrap();
// });
}
// }); // });
for (command_buffer, wgpu_resources) in results { let mut local_resources = Vec::new();
// for i in 0..thread_count { for (command_buffer, render_resources) in results {
// for i in 0..thread_count {
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap(); // let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
if let Some(command_buffer) = command_buffer { if let Some(command_buffer) = command_buffer {
command_buffers.push(command_buffer); command_buffers.push(command_buffer);
} }
global_wgpu_resources.consume(wgpu_resources); local_resources.push(render_resources.local_resources);
// println!("got {}", i); // println!("got {}", i);
} }
for local_resource in local_resources {
global_wgpu_resources.consume(local_resource);
}
queue.submit(&command_buffers); queue.submit(&command_buffers);
} }
@ -366,6 +383,8 @@ impl WgpuRenderer {
let primary_swap_chain = let primary_swap_chain =
primary_window_id.map(|primary_window_id| primary_window_id.to_string()); primary_window_id.map(|primary_window_id| primary_window_id.to_string());
let swap_chain_outputs = self let swap_chain_outputs = self
.global_context
.render_resources
.wgpu_resources .wgpu_resources
.window_swap_chains .window_swap_chains
.iter_mut() .iter_mut()
@ -386,21 +405,19 @@ impl Renderer for WgpuRenderer {
fn update(&mut self, world: &mut World, resources: &mut Resources) { fn update(&mut self, world: &mut World, resources: &mut Resources) {
Self::handle_window_created_events( Self::handle_window_created_events(
resources, resources,
&self.device, &self.global_context.device,
&mut self.wgpu_resources, &mut self.global_context.render_resources.wgpu_resources,
&mut self.window_created_event_reader, &mut self.window_created_event_reader,
); );
Self::handle_window_resized_events( Self::handle_window_resized_events(
resources, resources,
&self.device, &self.global_context.device,
&mut self.wgpu_resources, &mut self.global_context.render_resources.wgpu_resources,
&mut self.window_resized_event_reader, &mut self.window_resized_event_reader,
); );
if !self.intialized { if !self.intialized {
let mut render_context = WgpuRenderContext::new(self.device.clone(), &self.wgpu_resources); Self::initialize_resource_providers(world, resources, &mut self.global_context);
Self::initialize_resource_providers(world, resources, &mut render_context); let buffer = self.global_context.finish_encoder();
let (buffer, wgpu_resources) = render_context.finish();
self.wgpu_resources.consume(wgpu_resources);
if let Some(buffer) = buffer { if let Some(buffer) = buffer {
self.queue.submit(&[buffer]); self.queue.submit(&[buffer]);
} }
@ -411,12 +428,13 @@ impl Renderer for WgpuRenderer {
world, world,
resources, resources,
&mut self.queue, &mut self.queue,
self.device.clone(), self.global_context.device.clone(),
&mut self.wgpu_resources, &mut self.global_context.render_resources.wgpu_resources,
); );
self.encoder = Some( self.encoder = Some(
self.device self.global_context
.device
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }), .create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
); );
update_shader_assignments(world, resources, self); update_shader_assignments(world, resources, self);
@ -438,7 +456,7 @@ impl Renderer for WgpuRenderer {
let global_render_resource_assignments = let global_render_resource_assignments =
resources.get::<RenderResourceAssignments>().unwrap(); resources.get::<RenderResourceAssignments>().unwrap();
Self::create_render_pass( Self::create_render_pass(
&self.wgpu_resources, &self.global_context.render_resources.wgpu_resources,
pass_descriptor, pass_descriptor,
&global_render_resource_assignments, &global_render_resource_assignments,
&mut encoder, &mut encoder,
@ -461,7 +479,10 @@ impl Renderer for WgpuRenderer {
let mut wgpu_render_pass = WgpuRenderPass { let mut wgpu_render_pass = WgpuRenderPass {
render_pass: &mut render_pass, render_pass: &mut render_pass,
pipeline_descriptor, pipeline_descriptor,
wgpu_resources: &self.wgpu_resources, wgpu_resources: &self
.global_context
.render_resources
.wgpu_resources,
renderer: &self, renderer: &self,
bound_bind_groups: HashMap::default(), bound_bind_groups: HashMap::default(),
}; };
@ -487,24 +508,40 @@ impl Renderer for WgpuRenderer {
} }
fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource { fn create_buffer_with_data(&mut self, buffer_info: BufferInfo, data: &[u8]) -> RenderResource {
self.wgpu_resources self.global_context
.create_buffer_with_data(&self.device, buffer_info, data) .render_resources
.wgpu_resources
.create_buffer_with_data(&self.global_context.device, buffer_info, data)
} }
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource { fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
self.wgpu_resources.create_buffer(&self.device, buffer_info) self.global_context
.render_resources
.wgpu_resources
.create_buffer(&self.global_context.device, buffer_info)
} }
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> { fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
self.wgpu_resources.resource_info.get(&resource) self.global_context
.render_resources
.wgpu_resources
.resource_info
.get(&resource)
} }
fn get_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo> { fn get_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo> {
self.wgpu_resources.resource_info.get_mut(&resource) self.global_context
.render_resources
.wgpu_resources
.resource_info
.get_mut(&resource)
} }
fn remove_buffer(&mut self, resource: RenderResource) { fn remove_buffer(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_buffer(resource); self.global_context
.render_resources
.wgpu_resources
.remove_buffer(resource);
} }
fn create_buffer_mapped( fn create_buffer_mapped(
@ -513,7 +550,10 @@ impl Renderer for WgpuRenderer {
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer), setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
) -> RenderResource { ) -> RenderResource {
let buffer = WgpuResources::begin_create_buffer_mapped(&buffer_info, self, setup_data); let buffer = WgpuResources::begin_create_buffer_mapped(&buffer_info, self, setup_data);
self.wgpu_resources.assign_buffer(buffer, buffer_info) self.global_context
.render_resources
.wgpu_resources
.assign_buffer(buffer, buffer_info)
} }
fn copy_buffer_to_buffer( fn copy_buffer_to_buffer(
@ -524,19 +564,24 @@ impl Renderer for WgpuRenderer {
destination_offset: u64, destination_offset: u64,
size: u64, size: u64,
) { ) {
self.wgpu_resources.copy_buffer_to_buffer( self.global_context
self.encoder.as_mut().unwrap(), .render_resources
source_buffer, .wgpu_resources
source_offset, .copy_buffer_to_buffer(
destination_buffer, self.encoder.as_mut().unwrap(),
destination_offset, source_buffer,
size, source_offset,
); destination_buffer,
destination_offset,
size,
);
} }
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource { fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
self.wgpu_resources self.global_context
.create_sampler(&self.device, sampler_descriptor) .render_resources
.wgpu_resources
.create_sampler(&self.global_context.device, sampler_descriptor)
} }
fn create_texture( fn create_texture(
@ -545,32 +590,51 @@ impl Renderer for WgpuRenderer {
bytes: Option<&[u8]>, bytes: Option<&[u8]>,
) -> RenderResource { ) -> RenderResource {
if let Some(bytes) = bytes { if let Some(bytes) = bytes {
self.wgpu_resources.create_texture_with_data( self.global_context
&self.device, .render_resources
self.encoder.as_mut().unwrap(), .wgpu_resources
texture_descriptor, .create_texture_with_data(
bytes, &self.global_context.device,
) self.encoder.as_mut().unwrap(),
texture_descriptor,
bytes,
)
} else { } else {
self.wgpu_resources self.global_context
.create_texture(&self.device, texture_descriptor) .render_resources
.wgpu_resources
.create_texture(&self.global_context.device, texture_descriptor)
} }
} }
fn remove_texture(&mut self, resource: RenderResource) { fn remove_texture(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_texture(resource); self.global_context
.render_resources
.wgpu_resources
.remove_texture(resource);
} }
fn remove_sampler(&mut self, resource: RenderResource) { fn remove_sampler(&mut self, resource: RenderResource) {
self.wgpu_resources.remove_sampler(resource); self.global_context
.render_resources
.wgpu_resources
.remove_sampler(resource);
} }
fn get_render_resources(&self) -> &RenderResources { fn get_render_resources(&self) -> &AssetResources {
&self.wgpu_resources.render_resources &self
.global_context
.render_resources
.wgpu_resources
.asset_resources
} }
fn get_render_resources_mut(&mut self) -> &mut RenderResources { fn get_render_resources_mut(&mut self) -> &mut AssetResources {
&mut self.wgpu_resources.render_resources &mut self
.global_context
.render_resources
.wgpu_resources
.asset_resources
} }
fn setup_bind_groups( fn setup_bind_groups(
@ -584,14 +648,19 @@ impl Renderer for WgpuRenderer {
render_resource_assignments.get_or_update_render_resource_set_id(bind_group) render_resource_assignments.get_or_update_render_resource_set_id(bind_group)
{ {
if let None = self if let None = self
.global_context
.render_resources
.wgpu_resources .wgpu_resources
.get_bind_group(bind_group.id, render_resource_set_id) .get_bind_group(bind_group.id, render_resource_set_id)
{ {
self.wgpu_resources.create_bind_group( self.global_context
&self.device, .render_resources
bind_group, .wgpu_resources
render_resource_assignments, .create_bind_group(
); &self.global_context.device,
bind_group,
render_resource_assignments,
);
} else { } else {
log::trace!( log::trace!(
"reusing RenderResourceSet {:?} for bind group {}", "reusing RenderResourceSet {:?} for bind group {}",
@ -615,7 +684,13 @@ impl Renderer for WgpuRenderer {
let layout = pipeline_descriptor.get_layout().unwrap(); let layout = pipeline_descriptor.get_layout().unwrap();
for bind_group in layout.bind_groups.iter() { for bind_group in layout.bind_groups.iter() {
if let None = self.wgpu_resources.bind_group_layouts.get(&bind_group.id) { if let None = self
.global_context
.render_resources
.wgpu_resources
.bind_group_layouts
.get(&bind_group.id)
{
let bind_group_layout_binding = bind_group let bind_group_layout_binding = bind_group
.bindings .bindings
.iter() .iter()
@ -625,14 +700,16 @@ impl Renderer for WgpuRenderer {
ty: (&binding.bind_type).wgpu_into(), ty: (&binding.bind_type).wgpu_into(),
}) })
.collect::<Vec<wgpu::BindGroupLayoutEntry>>(); .collect::<Vec<wgpu::BindGroupLayoutEntry>>();
let wgpu_bind_group_layout = let wgpu_bind_group_layout = self.global_context.device.create_bind_group_layout(
self.device &wgpu::BindGroupLayoutDescriptor {
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { bindings: bind_group_layout_binding.as_slice(),
bindings: bind_group_layout_binding.as_slice(), label: None,
label: None, },
}); );
self.wgpu_resources self.global_context
.render_resources
.wgpu_resources
.bind_group_layouts .bind_group_layouts
.insert(bind_group.id, wgpu_bind_group_layout); .insert(bind_group.id, wgpu_bind_group_layout);
} }
@ -643,18 +720,21 @@ impl Renderer for WgpuRenderer {
.bind_groups .bind_groups
.iter() .iter()
.map(|bind_group| { .map(|bind_group| {
self.wgpu_resources self.global_context
.render_resources
.wgpu_resources
.bind_group_layouts .bind_group_layouts
.get(&bind_group.id) .get(&bind_group.id)
.unwrap() .unwrap()
}) })
.collect::<Vec<&wgpu::BindGroupLayout>>(); .collect::<Vec<&wgpu::BindGroupLayout>>();
let pipeline_layout = self let pipeline_layout =
.device self.global_context
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { .device
bind_group_layouts: bind_group_layouts.as_slice(), .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
}); bind_group_layouts: bind_group_layouts.as_slice(),
});
let owned_vertex_buffer_descriptors = layout let owned_vertex_buffer_descriptors = layout
.vertex_buffer_descriptors .vertex_buffer_descriptors
@ -669,28 +749,44 @@ impl Renderer for WgpuRenderer {
.collect::<Vec<wgpu::ColorStateDescriptor>>(); .collect::<Vec<wgpu::ColorStateDescriptor>>();
if let None = self if let None = self
.global_context
.render_resources
.wgpu_resources .wgpu_resources
.shader_modules .shader_modules
.get(&pipeline_descriptor.shader_stages.vertex) .get(&pipeline_descriptor.shader_stages.vertex)
{ {
self.wgpu_resources.create_shader_module( self.global_context
&self.device, .render_resources
pipeline_descriptor.shader_stages.vertex, .wgpu_resources
shader_storage, .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 Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) { if let None = self
self.wgpu_resources.create_shader_module( .global_context
&self.device, .render_resources
fragment_handle, .wgpu_resources
shader_storage, .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 let vertex_shader_module = self
.global_context
.render_resources
.wgpu_resources .wgpu_resources
.shader_modules .shader_modules
.get(&pipeline_descriptor.shader_stages.vertex) .get(&pipeline_descriptor.shader_stages.vertex)
@ -698,7 +794,9 @@ impl Renderer for WgpuRenderer {
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment { let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
Some(fragment_handle) => Some( Some(fragment_handle) => Some(
self.wgpu_resources self.global_context
.render_resources
.wgpu_resources
.shader_modules .shader_modules
.get(&fragment_handle) .get(&fragment_handle)
.unwrap(), .unwrap(),
@ -742,6 +840,7 @@ impl Renderer for WgpuRenderer {
}; };
let render_pipeline = self let render_pipeline = self
.global_context
.device .device
.create_render_pipeline(&mut render_pipeline_descriptor); .create_render_pipeline(&mut render_pipeline_descriptor);
self.render_pipelines self.render_pipelines

View File

@ -1,14 +1,17 @@
use super::WgpuRenderer; use super::WgpuRenderer;
use crate::{renderer_2::WgpuRenderContext, wgpu_type_converter::WgpuInto}; use crate::{
renderer_2::{WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext},
wgpu_type_converter::WgpuInto,
};
use bevy_asset::{AssetStorage, Handle}; use bevy_asset::{AssetStorage, Handle};
use bevy_render::{ use bevy_render::{
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, BindType}, pipeline::{BindGroupDescriptor, BindGroupDescriptorId, BindType},
render_resource::{ render_resource::{
BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId, AssetResources, BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId,
RenderResources, ResourceInfo, ResourceInfo,
}, },
renderer::Renderer, renderer::Renderer,
renderer_2::RenderContext, renderer_2::RenderResourceContext,
shader::Shader, shader::Shader,
texture::{SamplerDescriptor, TextureDescriptor}, texture::{SamplerDescriptor, TextureDescriptor},
}; };
@ -23,7 +26,7 @@ pub struct WgpuBindGroupInfo {
#[derive(Default)] #[derive(Default)]
pub struct WgpuResources { pub struct WgpuResources {
// TODO: remove this from WgpuResources. it doesn't need to be here // TODO: remove this from WgpuResources. it doesn't need to be here
pub render_resources: RenderResources, pub asset_resources: AssetResources,
pub window_surfaces: HashMap<WindowId, wgpu::Surface>, pub window_surfaces: HashMap<WindowId, wgpu::Surface>,
pub window_swap_chains: HashMap<WindowId, wgpu::SwapChain>, pub window_swap_chains: HashMap<WindowId, wgpu::SwapChain>,
pub buffers: HashMap<RenderResource, wgpu::Buffer>, pub buffers: HashMap<RenderResource, wgpu::Buffer>,
@ -38,8 +41,7 @@ pub struct WgpuResources {
impl WgpuResources { impl WgpuResources {
pub fn consume(&mut self, wgpu_resources: WgpuResources) { pub fn consume(&mut self, wgpu_resources: WgpuResources) {
// TODO: this is brittle. consider a single change-stream-based approach instead? // TODO: this is brittle. consider a single change-stream-based approach instead?
self.render_resources self.asset_resources.consume(wgpu_resources.asset_resources);
.consume(wgpu_resources.render_resources);
self.window_surfaces.extend(wgpu_resources.window_surfaces); self.window_surfaces.extend(wgpu_resources.window_surfaces);
self.window_swap_chains self.window_swap_chains
.extend(wgpu_resources.window_swap_chains); .extend(wgpu_resources.window_swap_chains);
@ -234,7 +236,7 @@ impl WgpuResources {
renderer: &mut WgpuRenderer, renderer: &mut WgpuRenderer,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer), setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
) -> wgpu::Buffer { ) -> wgpu::Buffer {
let device = renderer.device.clone(); let device = renderer.global_context.device.clone();
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor { let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
size: buffer_info.size as u64, size: buffer_info.size as u64,
usage: buffer_info.buffer_usage.wgpu_into(), usage: buffer_info.buffer_usage.wgpu_into(),
@ -247,16 +249,31 @@ impl WgpuResources {
// TODO: clean this up // TODO: clean this up
pub fn begin_create_buffer_mapped_render_context( pub fn begin_create_buffer_mapped_render_context(
buffer_info: &BufferInfo, buffer_info: &BufferInfo,
render_context: &mut WgpuRenderContext, render_resources: &mut WgpuRenderResourceContext,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext), setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
) -> wgpu::Buffer { ) -> wgpu::Buffer {
let device = render_context.device.clone(); let device = render_resources.device.clone();
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor { let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
size: buffer_info.size as u64, size: buffer_info.size as u64,
usage: buffer_info.buffer_usage.wgpu_into(), usage: buffer_info.buffer_usage.wgpu_into(),
label: None, label: None,
}); });
setup_data(&mut mapped.data, render_context); setup_data(&mut mapped.data, render_resources);
mapped.finish()
}
pub fn begin_create_buffer_mapped_transactional_render_context(
buffer_info: &BufferInfo,
render_resources: &mut WgpuTransactionalRenderResourceContext,
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
) -> wgpu::Buffer {
let device = render_resources.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, render_resources);
mapped.finish() mapped.finish()
} }
@ -356,11 +373,11 @@ impl WgpuResources {
self.resource_info.remove(&resource); self.resource_info.remove(&resource);
} }
pub fn get_render_resources(&self) -> &RenderResources { pub fn get_render_resources(&self) -> &AssetResources {
&self.render_resources &self.asset_resources
} }
pub fn get_render_resources_mut(&mut self) -> &mut RenderResources { pub fn get_render_resources_mut(&mut self) -> &mut AssetResources {
&mut self.render_resources &mut self.asset_resources
} }
} }

View File

@ -1,11 +1,15 @@
use bevy::prelude::*; use bevy::prelude::*;
fn main() { fn main() {
App::build().add_default_plugins().setup(setup).run(); App::build()
.add_default_plugins()
.setup(setup)
.run();
} }
/// set up a simple scene /// set up a simple scene
fn setup(world: &mut World, resources: &mut Resources) { fn setup(world: &mut World, resources: &mut Resources) {
env_logger::init();
// create a cube and a plane mesh // create a cube and a plane mesh
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap(); let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube)); let cube_handle = mesh_storage.add(Mesh::load(MeshType::Cube));
@ -40,6 +44,13 @@ fn setup(world: &mut World, resources: &mut Resources) {
translation: Translation::new(0.0, 0.0, 1.0), translation: Translation::new(0.0, 0.0, 1.0),
..Default::default() ..Default::default()
}) })
// cube
.add_entity(MeshEntity {
mesh: cube_handle,
material: cube_material_handle,
translation: Translation::new(2.0, 0.0, 1.0),
..Default::default()
})
// light // light
.add_entity(LightEntity { .add_entity(LightEntity {
translation: Translation::new(4.0, -4.0, 5.0), translation: Translation::new(4.0, -4.0, 5.0),