RenderContext, RenderResourceContext and wgpu implementations
This commit is contained in:
parent
08abef1c75
commit
394b7ce940
@ -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);
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>,
|
||||||
|
|||||||
@ -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::*;
|
||||||
@ -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,
|
||||||
|
|||||||
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_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::*;
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
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},
|
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
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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),
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user