mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 20:53:53 +00:00
RenderContext, RenderResourceContext and wgpu implementations
This commit is contained in:
parent
08abef1c75
commit
394b7ce940
18 changed files with 850 additions and 359 deletions
|
@ -16,15 +16,15 @@ impl RenderResource {
|
|||
// TODO: consider scoping breaking these mappings up by type: Texture, Sampler, etc
|
||||
// the overlap could cause accidents.
|
||||
#[derive(Default)]
|
||||
pub struct RenderResources {
|
||||
pub struct AssetResources {
|
||||
pub texture_to_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_indices_resource: HashMap<Handle<Mesh>, RenderResource>,
|
||||
}
|
||||
|
||||
impl RenderResources {
|
||||
pub fn consume(&mut self, render_resources: RenderResources) {
|
||||
impl AssetResources {
|
||||
pub fn consume(&mut self, render_resources: AssetResources) {
|
||||
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
||||
self.texture_to_resource.extend(render_resources.texture_to_resource);
|
||||
self.texture_to_sampler_resource.extend(render_resources.texture_to_sampler_resource);
|
||||
|
|
|
@ -48,10 +48,10 @@ impl Camera2dResourceProvider {
|
|||
let camera_matrix: [[f32; 4]; 4] = camera.view_matrix.to_cols_array_2d();
|
||||
|
||||
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 {
|
||||
size: matrix_size,
|
||||
buffer_usage: BufferUsage::COPY_SRC,
|
||||
|
@ -81,7 +81,7 @@ impl ResourceProvider for Camera2dResourceProvider {
|
|||
_world: &mut World,
|
||||
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]>(),
|
||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||
..Default::default()
|
||||
|
|
|
@ -45,10 +45,10 @@ impl CameraResourceProvider {
|
|||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||
|
||||
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 {
|
||||
size: matrix_size,
|
||||
buffer_usage: BufferUsage::COPY_SRC,
|
||||
|
@ -78,7 +78,7 @@ impl ResourceProvider for CameraResourceProvider {
|
|||
_world: &mut World,
|
||||
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]>(),
|
||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||
..Default::default()
|
||||
|
|
|
@ -34,11 +34,12 @@ impl FrameTextureResourceProvider {
|
|||
|
||||
let mut render_resource_assignments =
|
||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||
let render_resources = render_context.resources_mut();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,16 +46,17 @@ impl LightResourceProvider {
|
|||
let size = std::mem::size_of::<LightRaw>();
|
||||
let total_size = size * light_count;
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
size: total_size,
|
||||
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 {
|
||||
size: light_count_size,
|
||||
buffer_usage: BufferUsage::COPY_SRC,
|
||||
|
@ -111,7 +112,7 @@ impl ResourceProvider for LightResourceProvider {
|
|||
let light_uniform_size =
|
||||
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,
|
||||
buffer_usage: BufferUsage::UNIFORM | BufferUsage::COPY_SRC | BufferUsage::COPY_DST,
|
||||
..Default::default()
|
||||
|
|
|
@ -44,24 +44,25 @@ impl MeshResourceProvider {
|
|||
handle: Handle<Mesh>,
|
||||
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)
|
||||
{
|
||||
(
|
||||
vertex_buffer,
|
||||
render_context
|
||||
render_resources
|
||||
.get_mesh_indices_resource(handle),
|
||||
)
|
||||
} else {
|
||||
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 {
|
||||
buffer_usage: BufferUsage::VERTEX,
|
||||
..Default::default()
|
||||
},
|
||||
mesh_asset.vertices.as_bytes(),
|
||||
);
|
||||
let index_buffer = render_context.create_buffer_with_data(
|
||||
let index_buffer = render_resources.create_buffer_with_data(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::INDEX,
|
||||
..Default::default()
|
||||
|
@ -69,9 +70,9 @@ impl MeshResourceProvider {
|
|||
mesh_asset.indices.as_bytes(),
|
||||
);
|
||||
|
||||
let render_resources = render_context.local_render_resources_mut();
|
||||
render_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
||||
render_resources.set_mesh_indices_resource(handle, index_buffer);
|
||||
let asset_resources = render_resources.asset_resources_mut();
|
||||
asset_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
||||
asset_resources.set_mesh_indices_resource(handle, index_buffer);
|
||||
(vertex_buffer, Some(index_buffer))
|
||||
};
|
||||
|
||||
|
@ -90,7 +91,7 @@ impl ResourceProvider for MeshResourceProvider {
|
|||
vertex_buffer_descriptors.set(Vertex::get_vertex_buffer_descriptor().cloned().unwrap());
|
||||
}
|
||||
|
||||
fn update(&mut self, _render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) {
|
||||
fn update(&mut self, _render_context: &mut dyn RenderContext, _world: &mut World, _resources: &Resources) {
|
||||
}
|
||||
|
||||
fn finish_update(
|
||||
|
@ -99,7 +100,7 @@ impl ResourceProvider for MeshResourceProvider {
|
|||
_world: &mut World,
|
||||
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();
|
||||
|
||||
// this scope is necessary because the Fetch<AssetBatchers> pointer behaves weirdly
|
||||
|
|
|
@ -2,11 +2,12 @@ use crate::{
|
|||
pipeline::VertexBufferDescriptors,
|
||||
render_resource::{
|
||||
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
||||
RenderResourceAssignments, ResourceInfo, ResourceProvider, RenderResourceAssignmentsId,
|
||||
RenderResourceAssignments, RenderResourceAssignmentsId, ResourceInfo, ResourceProvider,
|
||||
},
|
||||
renderer_2::{RenderContext, RenderResourceContext},
|
||||
shader::{AsUniforms, FieldBindType},
|
||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||
Renderable, renderer_2::RenderContext,
|
||||
Renderable,
|
||||
};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use legion::{filter::*, prelude::*};
|
||||
|
@ -51,6 +52,7 @@ struct QueuedBufferWrite {
|
|||
offset: usize,
|
||||
}
|
||||
|
||||
// TODO: make these queries only update changed T components
|
||||
type UniformQuery<T> = Query<
|
||||
(Read<T>, Write<Renderable>),
|
||||
EntityFilterTuple<
|
||||
|
@ -262,11 +264,10 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn setup_uniform_resources(
|
||||
fn setup_uniform_buffer_resources(
|
||||
&mut self,
|
||||
uniforms: &T,
|
||||
render_context: &mut dyn RenderContext,
|
||||
resources: &Resources,
|
||||
render_resources: &mut dyn RenderResourceContext,
|
||||
render_resource_assignments: &mut RenderResourceAssignments,
|
||||
staging_buffer: &mut [u8],
|
||||
) {
|
||||
|
@ -282,10 +283,10 @@ where
|
|||
array_info: Some(ref array_info),
|
||||
is_dynamic: true,
|
||||
..
|
||||
})) = render_context.get_resource_info(buffer)
|
||||
})) = render_resources.get_resource_info(buffer)
|
||||
{
|
||||
let index =
|
||||
uniform_buffer_status.get_or_assign_index(render_resource_assignments.id);
|
||||
let index = uniform_buffer_status
|
||||
.get_or_assign_index(render_resource_assignments.id);
|
||||
render_resource_assignments.set_indexed(
|
||||
&field_info.uniform_name,
|
||||
buffer,
|
||||
|
@ -301,7 +302,7 @@ where
|
|||
{
|
||||
Some(render_resource) => render_resource,
|
||||
None => {
|
||||
let resource = render_context.create_buffer(BufferInfo {
|
||||
let resource = render_resources.create_buffer(BufferInfo {
|
||||
size,
|
||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||
..Default::default()
|
||||
|
@ -351,16 +352,33 @@ where
|
|||
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) => {
|
||||
let texture_handle = uniforms
|
||||
.get_uniform_texture(&field_info.texture_name)
|
||||
.unwrap();
|
||||
let (texture_resource, sampler_resource) = match render_context
|
||||
.resources()
|
||||
.get_texture_resource(texture_handle)
|
||||
{
|
||||
Some(texture_resource) => (
|
||||
texture_resource,
|
||||
render_context
|
||||
.resources()
|
||||
.get_texture_sampler_resource(texture_handle)
|
||||
.unwrap(),
|
||||
),
|
||||
|
@ -369,15 +387,17 @@ where
|
|||
let texture = storage.get(&texture_handle).unwrap();
|
||||
|
||||
let texture_descriptor: TextureDescriptor = texture.into();
|
||||
let texture_resource =
|
||||
render_context.create_texture_with_data(&texture_descriptor, &texture.data);
|
||||
let texture_resource = render_context
|
||||
.create_texture_with_data(&texture_descriptor, &texture.data);
|
||||
|
||||
let render_resources = render_context.resources_mut();
|
||||
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();
|
||||
render_resources.set_texture_resource(texture_handle, texture_resource);
|
||||
render_resources
|
||||
let asset_resources = render_resources.asset_resources_mut();
|
||||
asset_resources.set_texture_resource(texture_handle, texture_resource);
|
||||
asset_resources
|
||||
.set_texture_sampler_resource(texture_handle, 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.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,
|
||||
world: &mut World,
|
||||
resources: &Resources,
|
||||
render_context: &mut dyn RenderContext,
|
||||
render_resources: &mut dyn RenderResourceContext,
|
||||
staging_buffer: &mut [u8],
|
||||
) {
|
||||
let query_finish = self.query_finish.take().unwrap();
|
||||
|
@ -410,12 +431,41 @@ where
|
|||
std::any::type_name::<T>()
|
||||
);
|
||||
} 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,
|
||||
render_context,
|
||||
resources,
|
||||
&mut renderable.render_resource_assignments,
|
||||
staging_buffer,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -423,11 +473,11 @@ where
|
|||
self.query_finish = Some(query_finish);
|
||||
}
|
||||
|
||||
fn setup_handles_resources(
|
||||
fn setup_handles_buffer_resources(
|
||||
&mut self,
|
||||
world: &mut World,
|
||||
resources: &Resources,
|
||||
render_context: &mut dyn RenderContext,
|
||||
render_resources: &mut dyn RenderResourceContext,
|
||||
staging_buffer: &mut [u8],
|
||||
) {
|
||||
let assets = resources.get::<AssetStorage<T>>();
|
||||
|
@ -441,12 +491,40 @@ where
|
|||
let uniforms = assets
|
||||
.get(&handle)
|
||||
.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,
|
||||
render_context,
|
||||
resources,
|
||||
&mut renderable.render_resource_assignments,
|
||||
staging_buffer,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -476,12 +554,17 @@ where
|
|||
.unwrap();
|
||||
|
||||
if let Some(uniforms) = asset_storage.get(&handle) {
|
||||
self.setup_uniform_resources(
|
||||
uniforms,
|
||||
self.setup_uniform_buffer_resources(
|
||||
&uniforms,
|
||||
render_context.resources_mut(),
|
||||
&mut batch.render_resource_assignments,
|
||||
staging_buffer,
|
||||
);
|
||||
self.setup_uniform_texture_resources(
|
||||
&uniforms,
|
||||
render_context,
|
||||
resources,
|
||||
&mut batch.render_resource_assignments,
|
||||
staging_buffer,
|
||||
);
|
||||
|
||||
Self::update_shader_defs(&uniforms, &mut batch.render_resource_assignments);
|
||||
|
@ -516,7 +599,7 @@ where
|
|||
if let Some(ResourceInfo::Buffer(BufferInfo {
|
||||
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 {
|
||||
// over capacity. lets resize
|
||||
|
@ -544,7 +627,7 @@ where
|
|||
|
||||
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 {
|
||||
item_capacity: new_capacity,
|
||||
item_size,
|
||||
|
@ -634,7 +717,12 @@ where
|
|||
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.update_uniforms_info(world);
|
||||
self.update_uniform_handles_info(world, resources);
|
||||
|
@ -650,27 +738,56 @@ where
|
|||
self.setup_buffer_arrays(render_context);
|
||||
|
||||
let staging_buffer_size = self.update_staging_buffer_offsets();
|
||||
self.setup_uniforms_texture_resources(
|
||||
world,
|
||||
resources,
|
||||
render_context,
|
||||
);
|
||||
self.setup_handles_texture_resources(
|
||||
world,
|
||||
resources,
|
||||
render_context,
|
||||
);
|
||||
// self.setup_batched_texture_resources(world, resources, renderer, staging_buffer);
|
||||
if staging_buffer_size == 0 {
|
||||
let mut staging_buffer: [u8; 0] = [];
|
||||
self.setup_uniforms_resources(world, resources, render_context, &mut staging_buffer);
|
||||
self.setup_handles_resources(world, resources, render_context, &mut staging_buffer);
|
||||
// self.setup_batched_resources(world, resources, renderer, &mut staging_buffer);
|
||||
self.setup_uniforms_buffer_resources(
|
||||
world,
|
||||
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 {
|
||||
let staging_buffer = render_context.create_buffer_mapped(
|
||||
let staging_buffer = render_context.resources_mut().create_buffer_mapped(
|
||||
BufferInfo {
|
||||
buffer_usage: BufferUsage::COPY_SRC,
|
||||
size: staging_buffer_size,
|
||||
..Default::default()
|
||||
},
|
||||
&mut |staging_buffer, renderer| {
|
||||
self.setup_uniforms_resources(world, resources, renderer, staging_buffer);
|
||||
self.setup_handles_resources(world, resources, renderer, staging_buffer);
|
||||
// self.setup_batched_resources(world, resources, renderer, staging_buffer);
|
||||
&mut |staging_buffer, render_resources| {
|
||||
self.setup_uniforms_buffer_resources(
|
||||
world,
|
||||
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);
|
||||
render_context.remove_buffer(staging_buffer);
|
||||
render_context.resources_mut().remove_buffer(staging_buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
pipeline::PipelineDescriptor,
|
||||
render_resource::{
|
||||
BufferInfo, RenderResource, RenderResourceAssignments, RenderResources, ResourceInfo,
|
||||
BufferInfo, RenderResource, RenderResourceAssignments, AssetResources, ResourceInfo,
|
||||
},
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, TextureDescriptor},
|
||||
|
@ -38,8 +38,8 @@ pub trait Renderer {
|
|||
destination_offset: u64,
|
||||
size: u64,
|
||||
);
|
||||
fn get_render_resources(&self) -> &RenderResources;
|
||||
fn get_render_resources_mut(&mut self) -> &mut RenderResources;
|
||||
fn get_render_resources(&self) -> &AssetResources;
|
||||
fn get_render_resources_mut(&mut self) -> &mut AssetResources;
|
||||
fn setup_render_pipeline(
|
||||
&mut self,
|
||||
pipeline_handle: Handle<PipelineDescriptor>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
mod render_context;
|
||||
mod render_resource_context;
|
||||
|
||||
pub use render_context::*;
|
||||
pub use render_resource_context::*;
|
|
@ -1,35 +1,7 @@
|
|||
use crate::{
|
||||
render_resource::{
|
||||
BufferInfo, RenderResource, RenderResources, ResourceInfo,
|
||||
},
|
||||
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
|
||||
};
|
||||
use bevy_asset::Handle;
|
||||
use crate::{render_resource::RenderResource, texture::TextureDescriptor};
|
||||
use super::RenderResourceContext;
|
||||
|
||||
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(
|
||||
// &mut self,
|
||||
// pipeline_handle: Handle<PipelineDescriptor>,
|
||||
|
@ -42,6 +14,9 @@ pub trait RenderContext {
|
|||
// pipeline_descriptor: &PipelineDescriptor,
|
||||
// );
|
||||
|
||||
fn resources(&self) -> &dyn RenderResourceContext;
|
||||
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext;
|
||||
|
||||
fn create_texture_with_data(
|
||||
&mut self,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
|
|
37
bevy_render/src/renderer_2/render_resource_context.rs
Normal file
37
bevy_render/src/renderer_2/render_resource_context.rs
Normal 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>;
|
||||
}
|
|
@ -1,3 +1,7 @@
|
|||
mod wgpu_render_context;
|
||||
mod wgpu_render_resource_context;
|
||||
mod wgpu_transactional_render_resource_context;
|
||||
|
||||
pub use wgpu_render_context::*;
|
||||
pub use wgpu_render_resource_context::*;
|
||||
pub use wgpu_transactional_render_resource_context::*;
|
|
@ -1,12 +1,10 @@
|
|||
use crate::WgpuResources;
|
||||
|
||||
use super::WgpuRenderResourceContextTrait;
|
||||
use bevy_render::{
|
||||
render_resource::{BufferInfo, RenderResource, RenderResources, ResourceInfo},
|
||||
renderer_2::RenderContext,
|
||||
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
|
||||
render_resource::RenderResource,
|
||||
renderer_2::{RenderContext, RenderResourceContext},
|
||||
texture::TextureDescriptor,
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use bevy_asset::Handle;
|
||||
|
||||
#[derive(Default)]
|
||||
struct LazyCommandEncoder {
|
||||
|
@ -31,149 +29,71 @@ impl LazyCommandEncoder {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct WgpuRenderContext<'a> {
|
||||
pub struct WgpuRenderContext<T>
|
||||
where
|
||||
T: RenderResourceContext,
|
||||
{
|
||||
pub device: Arc<wgpu::Device>,
|
||||
local_wgpu_resources: WgpuResources,
|
||||
command_encoder: LazyCommandEncoder,
|
||||
global_wgpu_resources: &'a WgpuResources,
|
||||
removed_resources: Vec<RenderResource>,
|
||||
pub render_resources: T,
|
||||
}
|
||||
|
||||
impl<'a> WgpuRenderContext<'a> {
|
||||
pub fn new(device: Arc<wgpu::Device>, global_wgpu_resources: &'a WgpuResources) -> Self {
|
||||
impl<T> WgpuRenderContext<T>
|
||||
where
|
||||
T: RenderResourceContext,
|
||||
{
|
||||
pub fn new(device: Arc<wgpu::Device>, resources: T) -> Self {
|
||||
WgpuRenderContext {
|
||||
device,
|
||||
global_wgpu_resources: global_wgpu_resources,
|
||||
render_resources: resources,
|
||||
command_encoder: LazyCommandEncoder::default(),
|
||||
local_wgpu_resources: WgpuResources::default(),
|
||||
removed_resources: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn finish(mut self) -> (Option<wgpu::CommandBuffer>, WgpuResources) {
|
||||
(self.command_encoder.take().map(|encoder| encoder.finish()), self.local_wgpu_resources)
|
||||
/// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
|
||||
/// 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> {
|
||||
let buffer = local_resources.buffers.get(&render_resource);
|
||||
if buffer.is_some() {
|
||||
return buffer;
|
||||
}
|
||||
|
||||
global_resources.buffers.get(&render_resource)
|
||||
/// Consume this context, finalize the current CommandEncoder (if it exists), and take the current WgpuResources.
|
||||
/// This is intended to be called from a worker thread right before synchronizing with the main thread.
|
||||
pub fn finish_encoder(&mut self) -> Option<wgpu::CommandBuffer> {
|
||||
self.command_encoder.take().map(|encoder| encoder.finish())
|
||||
}
|
||||
|
||||
// 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> {
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||
self.local_wgpu_resources
|
||||
.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)
|
||||
}
|
||||
|
||||
impl<T> RenderContext for WgpuRenderContext<T>
|
||||
where
|
||||
T: RenderResourceContext + WgpuRenderResourceContextTrait,
|
||||
{
|
||||
fn create_texture_with_data(
|
||||
&mut self,
|
||||
texture_descriptor: &TextureDescriptor,
|
||||
bytes: &[u8],
|
||||
) -> RenderResource {
|
||||
self.local_wgpu_resources.create_texture_with_data(
|
||||
&self.device,
|
||||
self.render_resources.create_texture_with_data(
|
||||
self.command_encoder.get_or_create(&self.device),
|
||||
texture_descriptor,
|
||||
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(
|
||||
&mut self,
|
||||
source_buffer: RenderResource,
|
||||
|
@ -183,12 +103,23 @@ impl<'a> RenderContext for WgpuRenderContext<'a> {
|
|||
size: u64,
|
||||
) {
|
||||
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 destination_buffer = Self::get_buffer(destination_buffer, &self.local_wgpu_resources, &self.global_wgpu_resources).unwrap();
|
||||
command_encoder.copy_buffer_to_buffer(source_buffer, source_offset, destination_buffer, destination_offset, size);
|
||||
let source = self.render_resources.get_buffer(source_buffer).unwrap();
|
||||
let destination = self
|
||||
.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 {
|
||||
self.local_wgpu_resources
|
||||
.create_buffer_with_data(&self.device, buffer_info, data)
|
||||
fn resources(&self) -> &dyn RenderResourceContext {
|
||||
&self.render_resources
|
||||
}
|
||||
fn resources_mut(&mut self) -> &mut dyn RenderResourceContext {
|
||||
&mut self.render_resources
|
||||
}
|
||||
}
|
||||
|
|
133
bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs
Normal file
133
bevy_wgpu/src/renderer_2/wgpu_render_resource_context.rs
Normal 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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ use super::{
|
|||
wgpu_type_converter::{OwnedWgpuVertexBufferDescriptor, WgpuInto},
|
||||
WgpuRenderPass, WgpuResources,
|
||||
};
|
||||
use crate::renderer_2::WgpuRenderContext;
|
||||
use crate::renderer_2::{WgpuRenderContext, WgpuRenderResourceContext, WgpuTransactionalRenderResourceContext};
|
||||
use bevy_app::{EventReader, Events};
|
||||
use bevy_asset::{AssetStorage, Handle};
|
||||
use bevy_render::{
|
||||
|
@ -13,7 +13,7 @@ use bevy_render::{
|
|||
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
||||
render_graph::RenderGraph,
|
||||
render_resource::{
|
||||
resource_name, BufferInfo, RenderResource, RenderResourceAssignments, RenderResources,
|
||||
resource_name, AssetResources, BufferInfo, RenderResource, RenderResourceAssignments,
|
||||
ResourceInfo,
|
||||
},
|
||||
renderer::Renderer,
|
||||
|
@ -29,11 +29,10 @@ use std::{
|
|||
};
|
||||
|
||||
pub struct WgpuRenderer {
|
||||
pub device: Arc<wgpu::Device>,
|
||||
pub global_context: WgpuRenderContext<WgpuRenderResourceContext>,
|
||||
pub queue: wgpu::Queue,
|
||||
pub encoder: Option<wgpu::CommandEncoder>,
|
||||
pub render_pipelines: HashMap<Handle<PipelineDescriptor>, wgpu::RenderPipeline>,
|
||||
pub wgpu_resources: WgpuResources,
|
||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
||||
pub window_created_event_reader: EventReader<WindowCreated>,
|
||||
pub intialized: bool,
|
||||
|
@ -62,15 +61,17 @@ impl WgpuRenderer {
|
|||
limits: wgpu::Limits::default(),
|
||||
})
|
||||
.await;
|
||||
|
||||
let device = Arc::new(device);
|
||||
WgpuRenderer {
|
||||
device: Arc::new(device),
|
||||
global_context: WgpuRenderContext::new(
|
||||
device.clone(),
|
||||
WgpuRenderResourceContext::new(device),
|
||||
),
|
||||
queue,
|
||||
encoder: None,
|
||||
window_resized_event_reader,
|
||||
window_created_event_reader,
|
||||
intialized: false,
|
||||
wgpu_resources: WgpuResources::default(),
|
||||
render_pipelines: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +215,7 @@ impl WgpuRenderer {
|
|||
pub fn initialize_resource_providers(
|
||||
world: &mut World,
|
||||
resources: &mut Resources,
|
||||
render_context: &mut WgpuRenderContext,
|
||||
render_context: &mut WgpuRenderContext<WgpuRenderResourceContext>,
|
||||
) {
|
||||
let mut render_graph = resources.get_mut::<RenderGraph>().unwrap();
|
||||
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 mut results = Vec::new();
|
||||
// crossbeam_utils::thread::scope(|s| {
|
||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||
let device = device.clone();
|
||||
// let sender = sender.clone();
|
||||
// s.spawn(|_| {
|
||||
let mut render_context = WgpuRenderContext::new(device, global_wgpu_resources);
|
||||
for resource_provider in resource_provider_chunk.iter_mut() {
|
||||
resource_provider.update(&mut render_context, world, resources);
|
||||
}
|
||||
results.push(render_context.finish());
|
||||
// sender.send(render_context.finish()).unwrap();
|
||||
// });
|
||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||
let device = device.clone();
|
||||
let resource_device = device.clone();
|
||||
// let sender = sender.clone();
|
||||
// s.spawn(|_| {
|
||||
// TODO: replace WgpuResources with Global+Local resources
|
||||
let mut render_context =
|
||||
WgpuRenderContext::new(device, WgpuTransactionalRenderResourceContext::new(resource_device, global_wgpu_resources));
|
||||
for resource_provider in resource_provider_chunk.iter_mut() {
|
||||
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();
|
||||
for (command_buffer, wgpu_resources) in results {
|
||||
// for i in 0..thread_count {
|
||||
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
|
||||
let mut local_resources = Vec::new();
|
||||
for (command_buffer, render_resources) in results {
|
||||
// for i in 0..thread_count {
|
||||
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
|
||||
if let Some(command_buffer) = command_buffer {
|
||||
command_buffers.push(command_buffer);
|
||||
}
|
||||
|
||||
global_wgpu_resources.consume(wgpu_resources);
|
||||
local_resources.push(render_resources.local_resources);
|
||||
|
||||
// println!("got {}", i);
|
||||
}
|
||||
|
||||
for local_resource in local_resources {
|
||||
global_wgpu_resources.consume(local_resource);
|
||||
}
|
||||
|
||||
let mut results = Vec::new();
|
||||
// crossbeam_utils::thread::scope(|s| {
|
||||
for resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||
let device = device.clone();
|
||||
// let sender = sender.clone();
|
||||
// s.spawn(|_| {
|
||||
let mut render_context = WgpuRenderContext::new(device, global_wgpu_resources);
|
||||
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 resource_provider_chunk in render_graph.resource_providers.chunks_mut(chunk_size) {
|
||||
// TODO: try to unify this Device usage
|
||||
let device = device.clone();
|
||||
let resource_device = device.clone();
|
||||
// let sender = sender.clone();
|
||||
// s.spawn(|_| {
|
||||
// TODO: replace WgpuResources with Global+Local resources
|
||||
let mut render_context =
|
||||
WgpuRenderContext::new(device, WgpuTransactionalRenderResourceContext::new(resource_device, global_wgpu_resources));
|
||||
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 {
|
||||
// for i in 0..thread_count {
|
||||
let mut local_resources = Vec::new();
|
||||
for (command_buffer, render_resources) in results {
|
||||
// for i in 0..thread_count {
|
||||
// let (command_buffer, wgpu_resources) = receiver.recv().unwrap();
|
||||
if let Some(command_buffer) = command_buffer {
|
||||
command_buffers.push(command_buffer);
|
||||
}
|
||||
|
||||
global_wgpu_resources.consume(wgpu_resources);
|
||||
local_resources.push(render_resources.local_resources);
|
||||
// println!("got {}", i);
|
||||
}
|
||||
for local_resource in local_resources {
|
||||
global_wgpu_resources.consume(local_resource);
|
||||
}
|
||||
|
||||
queue.submit(&command_buffers);
|
||||
}
|
||||
|
@ -366,6 +383,8 @@ impl WgpuRenderer {
|
|||
let primary_swap_chain =
|
||||
primary_window_id.map(|primary_window_id| primary_window_id.to_string());
|
||||
let swap_chain_outputs = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.window_swap_chains
|
||||
.iter_mut()
|
||||
|
@ -386,21 +405,19 @@ impl Renderer for WgpuRenderer {
|
|||
fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||
Self::handle_window_created_events(
|
||||
resources,
|
||||
&self.device,
|
||||
&mut self.wgpu_resources,
|
||||
&self.global_context.device,
|
||||
&mut self.global_context.render_resources.wgpu_resources,
|
||||
&mut self.window_created_event_reader,
|
||||
);
|
||||
Self::handle_window_resized_events(
|
||||
resources,
|
||||
&self.device,
|
||||
&mut self.wgpu_resources,
|
||||
&self.global_context.device,
|
||||
&mut self.global_context.render_resources.wgpu_resources,
|
||||
&mut self.window_resized_event_reader,
|
||||
);
|
||||
if !self.intialized {
|
||||
let mut render_context = WgpuRenderContext::new(self.device.clone(), &self.wgpu_resources);
|
||||
Self::initialize_resource_providers(world, resources, &mut render_context);
|
||||
let (buffer, wgpu_resources) = render_context.finish();
|
||||
self.wgpu_resources.consume(wgpu_resources);
|
||||
Self::initialize_resource_providers(world, resources, &mut self.global_context);
|
||||
let buffer = self.global_context.finish_encoder();
|
||||
if let Some(buffer) = buffer {
|
||||
self.queue.submit(&[buffer]);
|
||||
}
|
||||
|
@ -411,12 +428,13 @@ impl Renderer for WgpuRenderer {
|
|||
world,
|
||||
resources,
|
||||
&mut self.queue,
|
||||
self.device.clone(),
|
||||
&mut self.wgpu_resources,
|
||||
self.global_context.device.clone(),
|
||||
&mut self.global_context.render_resources.wgpu_resources,
|
||||
);
|
||||
|
||||
self.encoder = Some(
|
||||
self.device
|
||||
self.global_context
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
||||
);
|
||||
update_shader_assignments(world, resources, self);
|
||||
|
@ -438,7 +456,7 @@ impl Renderer for WgpuRenderer {
|
|||
let global_render_resource_assignments =
|
||||
resources.get::<RenderResourceAssignments>().unwrap();
|
||||
Self::create_render_pass(
|
||||
&self.wgpu_resources,
|
||||
&self.global_context.render_resources.wgpu_resources,
|
||||
pass_descriptor,
|
||||
&global_render_resource_assignments,
|
||||
&mut encoder,
|
||||
|
@ -461,7 +479,10 @@ impl Renderer for WgpuRenderer {
|
|||
let mut wgpu_render_pass = WgpuRenderPass {
|
||||
render_pass: &mut render_pass,
|
||||
pipeline_descriptor,
|
||||
wgpu_resources: &self.wgpu_resources,
|
||||
wgpu_resources: &self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources,
|
||||
renderer: &self,
|
||||
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 {
|
||||
self.wgpu_resources
|
||||
.create_buffer_with_data(&self.device, buffer_info, data)
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_buffer_with_data(&self.global_context.device, buffer_info, data)
|
||||
}
|
||||
|
||||
fn create_buffer(&mut self, buffer_info: BufferInfo) -> RenderResource {
|
||||
self.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> {
|
||||
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> {
|
||||
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) {
|
||||
self.wgpu_resources.remove_buffer(resource);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.remove_buffer(resource);
|
||||
}
|
||||
|
||||
fn create_buffer_mapped(
|
||||
|
@ -513,7 +550,10 @@ impl Renderer for WgpuRenderer {
|
|||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
|
||||
) -> RenderResource {
|
||||
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(
|
||||
|
@ -524,19 +564,24 @@ impl Renderer for WgpuRenderer {
|
|||
destination_offset: u64,
|
||||
size: u64,
|
||||
) {
|
||||
self.wgpu_resources.copy_buffer_to_buffer(
|
||||
self.encoder.as_mut().unwrap(),
|
||||
source_buffer,
|
||||
source_offset,
|
||||
destination_buffer,
|
||||
destination_offset,
|
||||
size,
|
||||
);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.copy_buffer_to_buffer(
|
||||
self.encoder.as_mut().unwrap(),
|
||||
source_buffer,
|
||||
source_offset,
|
||||
destination_buffer,
|
||||
destination_offset,
|
||||
size,
|
||||
);
|
||||
}
|
||||
|
||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||
self.wgpu_resources
|
||||
.create_sampler(&self.device, sampler_descriptor)
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_sampler(&self.global_context.device, sampler_descriptor)
|
||||
}
|
||||
|
||||
fn create_texture(
|
||||
|
@ -545,32 +590,51 @@ impl Renderer for WgpuRenderer {
|
|||
bytes: Option<&[u8]>,
|
||||
) -> RenderResource {
|
||||
if let Some(bytes) = bytes {
|
||||
self.wgpu_resources.create_texture_with_data(
|
||||
&self.device,
|
||||
self.encoder.as_mut().unwrap(),
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_texture_with_data(
|
||||
&self.global_context.device,
|
||||
self.encoder.as_mut().unwrap(),
|
||||
texture_descriptor,
|
||||
bytes,
|
||||
)
|
||||
} else {
|
||||
self.wgpu_resources
|
||||
.create_texture(&self.device, texture_descriptor)
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_texture(&self.global_context.device, texture_descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
self.wgpu_resources.remove_sampler(resource);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.remove_sampler(resource);
|
||||
}
|
||||
|
||||
fn get_render_resources(&self) -> &RenderResources {
|
||||
&self.wgpu_resources.render_resources
|
||||
fn get_render_resources(&self) -> &AssetResources {
|
||||
&self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.asset_resources
|
||||
}
|
||||
|
||||
fn get_render_resources_mut(&mut self) -> &mut RenderResources {
|
||||
&mut self.wgpu_resources.render_resources
|
||||
fn get_render_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.asset_resources
|
||||
}
|
||||
|
||||
fn setup_bind_groups(
|
||||
|
@ -584,14 +648,19 @@ impl Renderer for WgpuRenderer {
|
|||
render_resource_assignments.get_or_update_render_resource_set_id(bind_group)
|
||||
{
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.get_bind_group(bind_group.id, render_resource_set_id)
|
||||
{
|
||||
self.wgpu_resources.create_bind_group(
|
||||
&self.device,
|
||||
bind_group,
|
||||
render_resource_assignments,
|
||||
);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_bind_group(
|
||||
&self.global_context.device,
|
||||
bind_group,
|
||||
render_resource_assignments,
|
||||
);
|
||||
} else {
|
||||
log::trace!(
|
||||
"reusing RenderResourceSet {:?} for bind group {}",
|
||||
|
@ -615,7 +684,13 @@ impl Renderer for WgpuRenderer {
|
|||
|
||||
let layout = pipeline_descriptor.get_layout().unwrap();
|
||||
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
|
||||
.bindings
|
||||
.iter()
|
||||
|
@ -625,14 +700,16 @@ impl Renderer for WgpuRenderer {
|
|||
ty: (&binding.bind_type).wgpu_into(),
|
||||
})
|
||||
.collect::<Vec<wgpu::BindGroupLayoutEntry>>();
|
||||
let wgpu_bind_group_layout =
|
||||
self.device
|
||||
.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: bind_group_layout_binding.as_slice(),
|
||||
label: None,
|
||||
});
|
||||
let wgpu_bind_group_layout = self.global_context.device.create_bind_group_layout(
|
||||
&wgpu::BindGroupLayoutDescriptor {
|
||||
bindings: bind_group_layout_binding.as_slice(),
|
||||
label: None,
|
||||
},
|
||||
);
|
||||
|
||||
self.wgpu_resources
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.bind_group_layouts
|
||||
.insert(bind_group.id, wgpu_bind_group_layout);
|
||||
}
|
||||
|
@ -643,18 +720,21 @@ impl Renderer for WgpuRenderer {
|
|||
.bind_groups
|
||||
.iter()
|
||||
.map(|bind_group| {
|
||||
self.wgpu_resources
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.bind_group_layouts
|
||||
.get(&bind_group.id)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<&wgpu::BindGroupLayout>>();
|
||||
|
||||
let pipeline_layout = self
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||
});
|
||||
let pipeline_layout =
|
||||
self.global_context
|
||||
.device
|
||||
.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
|
||||
bind_group_layouts: bind_group_layouts.as_slice(),
|
||||
});
|
||||
|
||||
let owned_vertex_buffer_descriptors = layout
|
||||
.vertex_buffer_descriptors
|
||||
|
@ -669,28 +749,44 @@ impl Renderer for WgpuRenderer {
|
|||
.collect::<Vec<wgpu::ColorStateDescriptor>>();
|
||||
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||
{
|
||||
self.wgpu_resources.create_shader_module(
|
||||
&self.device,
|
||||
pipeline_descriptor.shader_stages.vertex,
|
||||
shader_storage,
|
||||
);
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_shader_module(
|
||||
&self.global_context.device,
|
||||
pipeline_descriptor.shader_stages.vertex,
|
||||
shader_storage,
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(fragment_handle) = pipeline_descriptor.shader_stages.fragment {
|
||||
if let None = self.wgpu_resources.shader_modules.get(&fragment_handle) {
|
||||
self.wgpu_resources.create_shader_module(
|
||||
&self.device,
|
||||
fragment_handle,
|
||||
shader_storage,
|
||||
);
|
||||
if let None = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&fragment_handle)
|
||||
{
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.create_shader_module(
|
||||
&self.global_context.device,
|
||||
fragment_handle,
|
||||
shader_storage,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let vertex_shader_module = self
|
||||
.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&pipeline_descriptor.shader_stages.vertex)
|
||||
|
@ -698,7 +794,9 @@ impl Renderer for WgpuRenderer {
|
|||
|
||||
let fragment_shader_module = match pipeline_descriptor.shader_stages.fragment {
|
||||
Some(fragment_handle) => Some(
|
||||
self.wgpu_resources
|
||||
self.global_context
|
||||
.render_resources
|
||||
.wgpu_resources
|
||||
.shader_modules
|
||||
.get(&fragment_handle)
|
||||
.unwrap(),
|
||||
|
@ -742,6 +840,7 @@ impl Renderer for WgpuRenderer {
|
|||
};
|
||||
|
||||
let render_pipeline = self
|
||||
.global_context
|
||||
.device
|
||||
.create_render_pipeline(&mut render_pipeline_descriptor);
|
||||
self.render_pipelines
|
||||
|
|
|
@ -1,14 +1,17 @@
|
|||
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_render::{
|
||||
pipeline::{BindGroupDescriptor, BindGroupDescriptorId, BindType},
|
||||
render_resource::{
|
||||
BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId,
|
||||
RenderResources, ResourceInfo,
|
||||
AssetResources, BufferInfo, RenderResource, RenderResourceAssignments, RenderResourceSetId,
|
||||
ResourceInfo,
|
||||
},
|
||||
renderer::Renderer,
|
||||
renderer_2::RenderContext,
|
||||
renderer_2::RenderResourceContext,
|
||||
shader::Shader,
|
||||
texture::{SamplerDescriptor, TextureDescriptor},
|
||||
};
|
||||
|
@ -23,7 +26,7 @@ pub struct WgpuBindGroupInfo {
|
|||
#[derive(Default)]
|
||||
pub struct WgpuResources {
|
||||
// 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_swap_chains: HashMap<WindowId, wgpu::SwapChain>,
|
||||
pub buffers: HashMap<RenderResource, wgpu::Buffer>,
|
||||
|
@ -38,8 +41,7 @@ pub struct WgpuResources {
|
|||
impl WgpuResources {
|
||||
pub fn consume(&mut self, wgpu_resources: WgpuResources) {
|
||||
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
||||
self.render_resources
|
||||
.consume(wgpu_resources.render_resources);
|
||||
self.asset_resources.consume(wgpu_resources.asset_resources);
|
||||
self.window_surfaces.extend(wgpu_resources.window_surfaces);
|
||||
self.window_swap_chains
|
||||
.extend(wgpu_resources.window_swap_chains);
|
||||
|
@ -234,7 +236,7 @@ impl WgpuResources {
|
|||
renderer: &mut WgpuRenderer,
|
||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn Renderer),
|
||||
) -> wgpu::Buffer {
|
||||
let device = renderer.device.clone();
|
||||
let device = renderer.global_context.device.clone();
|
||||
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||
size: buffer_info.size as u64,
|
||||
usage: buffer_info.buffer_usage.wgpu_into(),
|
||||
|
@ -247,16 +249,31 @@ impl WgpuResources {
|
|||
// TODO: clean this up
|
||||
pub fn begin_create_buffer_mapped_render_context(
|
||||
buffer_info: &BufferInfo,
|
||||
render_context: &mut WgpuRenderContext,
|
||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext),
|
||||
render_resources: &mut WgpuRenderResourceContext,
|
||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderResourceContext),
|
||||
) -> wgpu::Buffer {
|
||||
let device = render_context.device.clone();
|
||||
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_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()
|
||||
}
|
||||
|
||||
|
@ -356,11 +373,11 @@ impl WgpuResources {
|
|||
self.resource_info.remove(&resource);
|
||||
}
|
||||
|
||||
pub fn get_render_resources(&self) -> &RenderResources {
|
||||
&self.render_resources
|
||||
pub fn get_render_resources(&self) -> &AssetResources {
|
||||
&self.asset_resources
|
||||
}
|
||||
|
||||
pub fn get_render_resources_mut(&mut self) -> &mut RenderResources {
|
||||
&mut self.render_resources
|
||||
pub fn get_render_resources_mut(&mut self) -> &mut AssetResources {
|
||||
&mut self.asset_resources
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
use bevy::prelude::*;
|
||||
|
||||
fn main() {
|
||||
App::build().add_default_plugins().setup(setup).run();
|
||||
App::build()
|
||||
.add_default_plugins()
|
||||
.setup(setup)
|
||||
.run();
|
||||
}
|
||||
|
||||
/// set up a simple scene
|
||||
fn setup(world: &mut World, resources: &mut Resources) {
|
||||
env_logger::init();
|
||||
// create a cube and a plane mesh
|
||||
let mut mesh_storage = resources.get_mut::<AssetStorage<Mesh>>().unwrap();
|
||||
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),
|
||||
..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
|
||||
.add_entity(LightEntity {
|
||||
translation: Translation::new(4.0, -4.0, 5.0),
|
||||
|
|
Loading…
Reference in a new issue