use RenderContext in ResourceProviders. make RenderContext contain a read-only view of global resources. Merge RenderContext changes back into global resources.
This commit is contained in:
parent
a7605b2d7a
commit
de2fb1fca2
@ -44,7 +44,7 @@ impl DrawTarget for UiDrawTarget {
|
|||||||
..
|
..
|
||||||
})) = renderer.get_resource_info(ui_instances_buffer)
|
})) = renderer.get_resource_info(ui_instances_buffer)
|
||||||
{
|
{
|
||||||
Some(array_info.item_count)
|
Some(array_info.item_capacity)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,14 @@ pub struct RenderResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RenderResources {
|
impl RenderResources {
|
||||||
|
pub fn consume(&mut self, render_resources: RenderResources) {
|
||||||
|
// TODO: this is brittle. consider a single change-stream-based approach instead?
|
||||||
|
self.texture_to_resource.extend(render_resources.texture_to_resource);
|
||||||
|
self.texture_to_sampler_resource.extend(render_resources.texture_to_sampler_resource);
|
||||||
|
self.mesh_to_vertices_resource.extend(render_resources.mesh_to_vertices_resource);
|
||||||
|
self.mesh_to_indices_resource.extend(render_resources.mesh_to_indices_resource);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
pub fn set_texture_resource(&mut self, texture: Handle<Texture>, resource: RenderResource) {
|
||||||
self.texture_to_resource.insert(texture, resource);
|
self.texture_to_resource.insert(texture, resource);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +1,9 @@
|
|||||||
use super::RenderResourceAssignmentsId;
|
|
||||||
use crate::render_resource::BufferUsage;
|
use crate::render_resource::BufferUsage;
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct BufferArrayInfo {
|
pub struct BufferArrayInfo {
|
||||||
pub item_count: usize,
|
|
||||||
pub item_size: usize,
|
pub item_size: usize,
|
||||||
pub item_capacity: usize,
|
pub item_capacity: usize,
|
||||||
pub indices: HashMap<RenderResourceAssignmentsId, usize>,
|
|
||||||
pub current_index: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BufferArrayInfo {
|
|
||||||
pub fn get_index(&self, id: RenderResourceAssignmentsId) -> Option<usize> {
|
|
||||||
self.indices.get(&id).map(|offset| *offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_or_assign_index(&mut self, id: RenderResourceAssignmentsId) -> usize {
|
|
||||||
if let Some(offset) = self.indices.get(&id) {
|
|
||||||
*offset
|
|
||||||
} else {
|
|
||||||
if self.current_index == self.item_capacity {
|
|
||||||
panic!("no empty slots available in array");
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = self.current_index;
|
|
||||||
self.indices.insert(id, index);
|
|
||||||
self.current_index += 1;
|
|
||||||
index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
use crate::renderer::Renderer;
|
use crate::{renderer_2::RenderContext};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
|
||||||
pub trait ResourceProvider {
|
pub trait ResourceProvider {
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
_renderer: &mut dyn Renderer,
|
_renderer: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
_resources: &Resources,
|
_resources: &Resources,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
fn update(&mut self, _renderer: &mut dyn Renderer, _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(
|
||||||
&mut self,
|
&mut self,
|
||||||
_renderer: &mut dyn Renderer,
|
_render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
_resources: &Resources,
|
_resources: &Resources,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@ -7,7 +7,7 @@ use crate::{
|
|||||||
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
||||||
ResourceProvider,
|
ResourceProvider,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
renderer_2::RenderContext,
|
||||||
};
|
};
|
||||||
|
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
@ -32,11 +32,11 @@ impl Camera2dResourceProvider {
|
|||||||
impl ResourceProvider for Camera2dResourceProvider {
|
impl ResourceProvider for Camera2dResourceProvider {
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let buffer = renderer.create_buffer(BufferInfo {
|
let buffer = render_context.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()
|
||||||
@ -48,7 +48,12 @@ impl ResourceProvider for Camera2dResourceProvider {
|
|||||||
self.camera_buffer = Some(buffer);
|
self.camera_buffer = Some(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
render_context: &mut dyn RenderContext,
|
||||||
|
world: &mut World,
|
||||||
|
resources: &Resources,
|
||||||
|
) {
|
||||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
||||||
let primary_window_resized_event = window_resized_events
|
let primary_window_resized_event = window_resized_events
|
||||||
.iter(&mut self.window_resized_event_reader)
|
.iter(&mut self.window_resized_event_reader)
|
||||||
@ -67,10 +72,10 @@ impl ResourceProvider for 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 {
|
||||||
renderer.remove_buffer(old_tmp_buffer);
|
render_context.remove_buffer(old_tmp_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tmp_buffer = Some(renderer.create_buffer_mapped(
|
self.tmp_buffer = Some(render_context.create_buffer_mapped(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
size: matrix_size,
|
size: matrix_size,
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
@ -81,7 +86,7 @@ impl ResourceProvider for Camera2dResourceProvider {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(
|
render_context.copy_buffer_to_buffer(
|
||||||
self.tmp_buffer.unwrap(),
|
self.tmp_buffer.unwrap(),
|
||||||
0,
|
0,
|
||||||
self.camera_buffer.unwrap(),
|
self.camera_buffer.unwrap(),
|
||||||
|
|||||||
@ -5,8 +5,7 @@ use crate::{
|
|||||||
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
||||||
ResourceProvider,
|
ResourceProvider,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
ActiveCamera, Camera, renderer_2::RenderContext,
|
||||||
ActiveCamera, Camera,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_app::{EventReader, Events};
|
use bevy_app::{EventReader, Events};
|
||||||
@ -33,11 +32,11 @@ impl CameraResourceProvider {
|
|||||||
impl ResourceProvider for CameraResourceProvider {
|
impl ResourceProvider for CameraResourceProvider {
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let buffer = renderer.create_buffer(BufferInfo {
|
let buffer = render_context.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()
|
||||||
@ -49,7 +48,7 @@ impl ResourceProvider for CameraResourceProvider {
|
|||||||
self.camera_buffer = Some(buffer);
|
self.camera_buffer = Some(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
fn update(&mut self, render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) {
|
||||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
||||||
let primary_window_resized_event = window_resized_events
|
let primary_window_resized_event = window_resized_events
|
||||||
.iter(&mut self.window_resized_event_reader)
|
.iter(&mut self.window_resized_event_reader)
|
||||||
@ -69,10 +68,10 @@ impl ResourceProvider for 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 {
|
||||||
renderer.remove_buffer(old_tmp_buffer);
|
render_context.remove_buffer(old_tmp_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tmp_buffer = Some(renderer.create_buffer_mapped(
|
self.tmp_buffer = Some(render_context.create_buffer_mapped(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
size: matrix_size,
|
size: matrix_size,
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
@ -83,7 +82,7 @@ impl ResourceProvider for CameraResourceProvider {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(
|
render_context.copy_buffer_to_buffer(
|
||||||
self.tmp_buffer.unwrap(),
|
self.tmp_buffer.unwrap(),
|
||||||
0,
|
0,
|
||||||
self.camera_buffer.unwrap(),
|
self.camera_buffer.unwrap(),
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
render_resource::{RenderResourceAssignments, ResourceProvider},
|
render_resource::{RenderResourceAssignments, ResourceProvider},
|
||||||
renderer::Renderer,
|
texture::TextureDescriptor, renderer_2::RenderContext,
|
||||||
texture::TextureDescriptor,
|
|
||||||
};
|
};
|
||||||
use bevy_window::Windows;
|
use bevy_window::Windows;
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
@ -23,7 +22,7 @@ impl FrameTextureResourceProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, renderer: &mut dyn Renderer, resources: &Resources) {
|
pub fn update(&mut self, render_context: &mut dyn RenderContext, resources: &Resources) {
|
||||||
let windows = resources.get::<Windows>().unwrap();
|
let windows = resources.get::<Windows>().unwrap();
|
||||||
let window = windows.get_primary().unwrap();
|
let window = windows.get_primary().unwrap();
|
||||||
|
|
||||||
@ -36,17 +35,17 @@ impl FrameTextureResourceProvider {
|
|||||||
let mut render_resource_assignments =
|
let mut render_resource_assignments =
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
||||||
if let Some(old_resource) = render_resource_assignments.get(&self.name) {
|
if let Some(old_resource) = render_resource_assignments.get(&self.name) {
|
||||||
renderer.remove_texture(old_resource);
|
render_context.remove_texture(old_resource);
|
||||||
}
|
}
|
||||||
|
|
||||||
let texture_resource = renderer.create_texture(&self.descriptor, None);
|
let texture_resource = render_context.create_texture(&self.descriptor);
|
||||||
render_resource_assignments.set(&self.name, texture_resource);
|
render_resource_assignments.set(&self.name, texture_resource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ResourceProvider for FrameTextureResourceProvider {
|
impl ResourceProvider for FrameTextureResourceProvider {
|
||||||
fn update(&mut self, renderer: &mut dyn Renderer, _world: &mut World, resources: &Resources) {
|
fn update(&mut self, render_context: &mut dyn RenderContext, _world: &mut World, resources: &Resources) {
|
||||||
self.update(renderer, resources)
|
self.update(render_context, resources)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,8 +3,7 @@ use crate::{
|
|||||||
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
||||||
ResourceProvider,
|
ResourceProvider,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
Light, LightRaw, renderer_2::RenderContext,
|
||||||
Light, LightRaw,
|
|
||||||
};
|
};
|
||||||
use bevy_transform::prelude::{LocalToWorld, Translation};
|
use bevy_transform::prelude::{LocalToWorld, Translation};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
@ -39,14 +38,14 @@ impl LightResourceProvider {
|
|||||||
impl ResourceProvider for LightResourceProvider {
|
impl ResourceProvider for LightResourceProvider {
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
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 = renderer.create_buffer(BufferInfo {
|
let buffer = render_context.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()
|
||||||
@ -57,7 +56,7 @@ impl ResourceProvider for LightResourceProvider {
|
|||||||
self.light_buffer = Some(buffer);
|
self.light_buffer = Some(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, renderer: &mut dyn Renderer, world: &mut World, _resources: &Resources) {
|
fn update(&mut self, render_context: &mut dyn RenderContext, world: &mut World, _resources: &Resources) {
|
||||||
if self.lights_are_dirty {
|
if self.lights_are_dirty {
|
||||||
let light_query = <(Read<Light>, Read<LocalToWorld>, Read<Translation>)>::query();
|
let light_query = <(Read<Light>, Read<LocalToWorld>, Read<Translation>)>::query();
|
||||||
let light_count = light_query.iter(world).count();
|
let light_count = light_query.iter(world).count();
|
||||||
@ -72,14 +71,14 @@ impl ResourceProvider for LightResourceProvider {
|
|||||||
let light_count_size = std::mem::size_of::<LightCount>();
|
let light_count_size = std::mem::size_of::<LightCount>();
|
||||||
|
|
||||||
if let Some(old_tmp_light_buffer) = self.tmp_light_buffer {
|
if let Some(old_tmp_light_buffer) = self.tmp_light_buffer {
|
||||||
renderer.remove_buffer(old_tmp_light_buffer);
|
render_context.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 {
|
||||||
renderer.remove_buffer(old_tmp_count_buffer);
|
render_context.remove_buffer(old_tmp_count_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tmp_light_buffer = Some(renderer.create_buffer_mapped(
|
self.tmp_light_buffer = Some(render_context.create_buffer_mapped(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
size: total_size,
|
size: total_size,
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
@ -95,7 +94,7 @@ impl ResourceProvider for LightResourceProvider {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
self.tmp_count_buffer = Some(renderer.create_buffer_mapped(
|
self.tmp_count_buffer = Some(render_context.create_buffer_mapped(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
size: light_count_size,
|
size: light_count_size,
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
@ -106,7 +105,7 @@ impl ResourceProvider for LightResourceProvider {
|
|||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(
|
render_context.copy_buffer_to_buffer(
|
||||||
self.tmp_count_buffer.unwrap(),
|
self.tmp_count_buffer.unwrap(),
|
||||||
0,
|
0,
|
||||||
self.light_buffer.unwrap(),
|
self.light_buffer.unwrap(),
|
||||||
@ -114,7 +113,7 @@ impl ResourceProvider for LightResourceProvider {
|
|||||||
light_count_size as u64,
|
light_count_size as u64,
|
||||||
);
|
);
|
||||||
|
|
||||||
renderer.copy_buffer_to_buffer(
|
render_context.copy_buffer_to_buffer(
|
||||||
self.tmp_light_buffer.unwrap(),
|
self.tmp_light_buffer.unwrap(),
|
||||||
0,
|
0,
|
||||||
self.light_buffer.unwrap(),
|
self.light_buffer.unwrap(),
|
||||||
|
|||||||
@ -4,9 +4,8 @@ use crate::{
|
|||||||
render_resource::{
|
render_resource::{
|
||||||
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
AssetBatchers, BufferInfo, BufferUsage, RenderResourceAssignments, ResourceProvider,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
|
||||||
shader::AsUniforms,
|
shader::AsUniforms,
|
||||||
Renderable, Vertex,
|
Renderable, Vertex, renderer_2::RenderContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use legion::{filter::*, prelude::*};
|
use legion::{filter::*, prelude::*};
|
||||||
@ -40,31 +39,29 @@ impl MeshResourceProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn setup_mesh_resources(
|
fn setup_mesh_resources(
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
mesh_storage: &mut AssetStorage<Mesh>,
|
mesh_storage: &mut AssetStorage<Mesh>,
|
||||||
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) = renderer
|
let (vertex_buffer, index_buffer) = if let Some(vertex_buffer) = render_context
|
||||||
.get_render_resources()
|
|
||||||
.get_mesh_vertices_resource(handle)
|
.get_mesh_vertices_resource(handle)
|
||||||
{
|
{
|
||||||
(
|
(
|
||||||
vertex_buffer,
|
vertex_buffer,
|
||||||
renderer
|
render_context
|
||||||
.get_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 = renderer.create_buffer_with_data(
|
let vertex_buffer = render_context.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 = renderer.create_buffer_with_data(
|
let index_buffer = render_context.create_buffer_with_data(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
buffer_usage: BufferUsage::INDEX,
|
buffer_usage: BufferUsage::INDEX,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -72,7 +69,7 @@ impl MeshResourceProvider {
|
|||||||
mesh_asset.indices.as_bytes(),
|
mesh_asset.indices.as_bytes(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let render_resources = renderer.get_render_resources_mut();
|
let render_resources = render_context.local_render_resources_mut();
|
||||||
render_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
render_resources.set_mesh_vertices_resource(handle, vertex_buffer);
|
||||||
render_resources.set_mesh_indices_resource(handle, index_buffer);
|
render_resources.set_mesh_indices_resource(handle, index_buffer);
|
||||||
(vertex_buffer, Some(index_buffer))
|
(vertex_buffer, Some(index_buffer))
|
||||||
@ -85,7 +82,7 @@ impl MeshResourceProvider {
|
|||||||
impl ResourceProvider for MeshResourceProvider {
|
impl ResourceProvider for MeshResourceProvider {
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
_renderer: &mut dyn Renderer,
|
_render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
@ -93,7 +90,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, _renderer: &mut dyn Renderer, world: &mut World, resources: &Resources) {
|
fn update(&mut self, _render_context: &mut dyn RenderContext, world: &mut World, resources: &Resources) {
|
||||||
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
|
let mut asset_batchers = resources.get_mut::<AssetBatchers>().unwrap();
|
||||||
for (entity, (mesh_handle, _renderable)) in self.mesh_query.iter_entities_mut(world) {
|
for (entity, (mesh_handle, _renderable)) in self.mesh_query.iter_entities_mut(world) {
|
||||||
asset_batchers.set_entity_handle(entity, *mesh_handle);
|
asset_batchers.set_entity_handle(entity, *mesh_handle);
|
||||||
@ -102,7 +99,7 @@ impl ResourceProvider for MeshResourceProvider {
|
|||||||
|
|
||||||
fn finish_update(
|
fn finish_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
@ -116,7 +113,7 @@ impl ResourceProvider for MeshResourceProvider {
|
|||||||
let handle = batch.get_handle::<Mesh>().unwrap();
|
let handle = batch.get_handle::<Mesh>().unwrap();
|
||||||
log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id);
|
log::trace!("setup mesh for {:?}", batch.render_resource_assignments.id);
|
||||||
Self::setup_mesh_resources(
|
Self::setup_mesh_resources(
|
||||||
renderer,
|
render_context,
|
||||||
&mut mesh_storage,
|
&mut mesh_storage,
|
||||||
handle,
|
handle,
|
||||||
&mut batch.render_resource_assignments,
|
&mut batch.render_resource_assignments,
|
||||||
|
|||||||
@ -2,16 +2,15 @@ use crate::{
|
|||||||
pipeline::VertexBufferDescriptors,
|
pipeline::VertexBufferDescriptors,
|
||||||
render_resource::{
|
render_resource::{
|
||||||
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
AssetBatchers, BufferArrayInfo, BufferInfo, BufferUsage, RenderResource,
|
||||||
RenderResourceAssignments, ResourceInfo, ResourceProvider,
|
RenderResourceAssignments, ResourceInfo, ResourceProvider, RenderResourceAssignmentsId,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
|
||||||
shader::{AsUniforms, FieldBindType},
|
shader::{AsUniforms, FieldBindType},
|
||||||
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
texture::{SamplerDescriptor, Texture, TextureDescriptor},
|
||||||
Renderable,
|
Renderable, renderer_2::RenderContext,
|
||||||
};
|
};
|
||||||
use bevy_asset::{AssetStorage, Handle};
|
use bevy_asset::{AssetStorage, Handle};
|
||||||
use legion::{filter::*, prelude::*};
|
use legion::{filter::*, prelude::*};
|
||||||
use std::marker::PhantomData;
|
use std::{collections::HashMap, marker::PhantomData};
|
||||||
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
|
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -22,6 +21,28 @@ struct BufferArrayStatus {
|
|||||||
staging_buffer_offset: usize,
|
staging_buffer_offset: usize,
|
||||||
queued_buffer_writes: Vec<QueuedBufferWrite>,
|
queued_buffer_writes: Vec<QueuedBufferWrite>,
|
||||||
buffer: Option<RenderResource>,
|
buffer: Option<RenderResource>,
|
||||||
|
|
||||||
|
current_item_count: usize,
|
||||||
|
current_item_capacity: usize,
|
||||||
|
indices: HashMap<RenderResourceAssignmentsId, usize>,
|
||||||
|
current_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BufferArrayStatus {
|
||||||
|
pub fn get_or_assign_index(&mut self, id: RenderResourceAssignmentsId) -> usize {
|
||||||
|
if let Some(offset) = self.indices.get(&id) {
|
||||||
|
*offset
|
||||||
|
} else {
|
||||||
|
if self.current_index == self.current_item_capacity {
|
||||||
|
panic!("no empty slots available in array");
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = self.current_index;
|
||||||
|
self.indices.insert(id, index);
|
||||||
|
self.current_index += 1;
|
||||||
|
index
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -173,6 +194,10 @@ where
|
|||||||
item_size: f(),
|
item_size: f(),
|
||||||
staging_buffer_offset: 0,
|
staging_buffer_offset: 0,
|
||||||
buffer: None,
|
buffer: None,
|
||||||
|
current_index: 0,
|
||||||
|
current_item_capacity: 0,
|
||||||
|
current_item_count: 0,
|
||||||
|
indices: HashMap::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -211,6 +236,10 @@ where
|
|||||||
item_size: size,
|
item_size: size,
|
||||||
staging_buffer_offset: 0,
|
staging_buffer_offset: 0,
|
||||||
buffer: None,
|
buffer: None,
|
||||||
|
current_index: 0,
|
||||||
|
current_item_count: 0,
|
||||||
|
current_item_capacity: 0,
|
||||||
|
indices: HashMap::new(),
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -236,7 +265,7 @@ where
|
|||||||
fn setup_uniform_resources(
|
fn setup_uniform_resources(
|
||||||
&mut self,
|
&mut self,
|
||||||
uniforms: &T,
|
uniforms: &T,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_assignments: &mut RenderResourceAssignments,
|
||||||
staging_buffer: &mut [u8],
|
staging_buffer: &mut [u8],
|
||||||
@ -250,13 +279,13 @@ where
|
|||||||
let (target_buffer, target_offset) = if self.use_dynamic_uniforms {
|
let (target_buffer, target_offset) = if self.use_dynamic_uniforms {
|
||||||
let buffer = uniform_buffer_status.buffer.unwrap();
|
let buffer = uniform_buffer_status.buffer.unwrap();
|
||||||
if let Some(ResourceInfo::Buffer(BufferInfo {
|
if let Some(ResourceInfo::Buffer(BufferInfo {
|
||||||
array_info: Some(ref mut array_info),
|
array_info: Some(ref array_info),
|
||||||
is_dynamic: true,
|
is_dynamic: true,
|
||||||
..
|
..
|
||||||
})) = renderer.get_resource_info_mut(buffer)
|
})) = render_context.get_resource_info(buffer)
|
||||||
{
|
{
|
||||||
let index =
|
let index =
|
||||||
array_info.get_or_assign_index(render_resource_assignments.id);
|
uniform_buffer_status.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,
|
||||||
@ -272,7 +301,7 @@ where
|
|||||||
{
|
{
|
||||||
Some(render_resource) => render_resource,
|
Some(render_resource) => render_resource,
|
||||||
None => {
|
None => {
|
||||||
let resource = renderer.create_buffer(BufferInfo {
|
let resource = render_context.create_buffer(BufferInfo {
|
||||||
size,
|
size,
|
||||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -326,14 +355,12 @@ where
|
|||||||
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 renderer
|
let (texture_resource, sampler_resource) = match render_context
|
||||||
.get_render_resources()
|
|
||||||
.get_texture_resource(texture_handle)
|
.get_texture_resource(texture_handle)
|
||||||
{
|
{
|
||||||
Some(texture_resource) => (
|
Some(texture_resource) => (
|
||||||
texture_resource,
|
texture_resource,
|
||||||
renderer
|
render_context
|
||||||
.get_render_resources()
|
|
||||||
.get_texture_sampler_resource(texture_handle)
|
.get_texture_sampler_resource(texture_handle)
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
),
|
),
|
||||||
@ -343,12 +370,12 @@ where
|
|||||||
|
|
||||||
let texture_descriptor: TextureDescriptor = texture.into();
|
let texture_descriptor: TextureDescriptor = texture.into();
|
||||||
let texture_resource =
|
let texture_resource =
|
||||||
renderer.create_texture(&texture_descriptor, Some(&texture.data));
|
render_context.create_texture_with_data(&texture_descriptor, &texture.data);
|
||||||
|
|
||||||
let sampler_descriptor: SamplerDescriptor = texture.into();
|
let sampler_descriptor: SamplerDescriptor = texture.into();
|
||||||
let sampler_resource = renderer.create_sampler(&sampler_descriptor);
|
let sampler_resource = render_context.create_sampler(&sampler_descriptor);
|
||||||
|
|
||||||
let render_resources = renderer.get_render_resources_mut();
|
let render_resources = render_context.local_render_resources_mut();
|
||||||
render_resources.set_texture_resource(texture_handle, texture_resource);
|
render_resources.set_texture_resource(texture_handle, texture_resource);
|
||||||
render_resources
|
render_resources
|
||||||
.set_texture_sampler_resource(texture_handle, sampler_resource);
|
.set_texture_sampler_resource(texture_handle, sampler_resource);
|
||||||
@ -368,7 +395,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
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();
|
||||||
@ -385,7 +412,7 @@ where
|
|||||||
} else {
|
} else {
|
||||||
self.setup_uniform_resources(
|
self.setup_uniform_resources(
|
||||||
&uniforms,
|
&uniforms,
|
||||||
renderer,
|
render_context,
|
||||||
resources,
|
resources,
|
||||||
&mut renderable.render_resource_assignments,
|
&mut renderable.render_resource_assignments,
|
||||||
staging_buffer,
|
staging_buffer,
|
||||||
@ -400,7 +427,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
staging_buffer: &mut [u8],
|
staging_buffer: &mut [u8],
|
||||||
) {
|
) {
|
||||||
let assets = resources.get::<AssetStorage<T>>();
|
let assets = resources.get::<AssetStorage<T>>();
|
||||||
@ -416,7 +443,7 @@ where
|
|||||||
.expect("Handle points to a non-existent resource");
|
.expect("Handle points to a non-existent resource");
|
||||||
self.setup_uniform_resources(
|
self.setup_uniform_resources(
|
||||||
&uniforms,
|
&uniforms,
|
||||||
renderer,
|
render_context,
|
||||||
resources,
|
resources,
|
||||||
&mut renderable.render_resource_assignments,
|
&mut renderable.render_resource_assignments,
|
||||||
staging_buffer,
|
staging_buffer,
|
||||||
@ -432,7 +459,7 @@ where
|
|||||||
&mut self,
|
&mut self,
|
||||||
_world: &mut World,
|
_world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
staging_buffer: &mut [u8],
|
staging_buffer: &mut [u8],
|
||||||
) {
|
) {
|
||||||
// update batch resources. this needs to run in "finish_update" because batches aren't finalized across
|
// update batch resources. this needs to run in "finish_update" because batches aren't finalized across
|
||||||
@ -451,7 +478,7 @@ where
|
|||||||
if let Some(uniforms) = asset_storage.get(&handle) {
|
if let Some(uniforms) = asset_storage.get(&handle) {
|
||||||
self.setup_uniform_resources(
|
self.setup_uniform_resources(
|
||||||
uniforms,
|
uniforms,
|
||||||
renderer,
|
render_context,
|
||||||
resources,
|
resources,
|
||||||
&mut batch.render_resource_assignments,
|
&mut batch.render_resource_assignments,
|
||||||
staging_buffer,
|
staging_buffer,
|
||||||
@ -463,11 +490,11 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_buffer_arrays(&mut self, renderer: &mut dyn Renderer) {
|
fn setup_buffer_arrays(&mut self, render_context: &mut dyn RenderContext) {
|
||||||
for buffer_array_status in self.uniform_buffer_status.iter_mut() {
|
for buffer_array_status in self.uniform_buffer_status.iter_mut() {
|
||||||
if let Some((_name, buffer_array_status)) = buffer_array_status {
|
if let Some((_name, buffer_array_status)) = buffer_array_status {
|
||||||
if self.use_dynamic_uniforms {
|
if self.use_dynamic_uniforms {
|
||||||
Self::setup_buffer_array(buffer_array_status, renderer, true);
|
Self::setup_buffer_array(buffer_array_status, render_context, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_array_status.queued_buffer_writes =
|
buffer_array_status.queued_buffer_writes =
|
||||||
@ -476,20 +503,20 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref mut buffer_array_status) = self.instance_buffer_status {
|
if let Some(ref mut buffer_array_status) = self.instance_buffer_status {
|
||||||
Self::setup_buffer_array(buffer_array_status, renderer, false);
|
Self::setup_buffer_array(buffer_array_status, render_context, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_buffer_array(
|
fn setup_buffer_array(
|
||||||
buffer_array_status: &mut BufferArrayStatus,
|
buffer_array_status: &mut BufferArrayStatus,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
align: bool,
|
align: bool,
|
||||||
) {
|
) {
|
||||||
let new_capacity = if let Some(buffer) = buffer_array_status.buffer {
|
let new_capacity = if let Some(buffer) = buffer_array_status.buffer {
|
||||||
if let Some(ResourceInfo::Buffer(BufferInfo {
|
if let Some(ResourceInfo::Buffer(BufferInfo {
|
||||||
array_info: Some(array_info),
|
array_info: Some(array_info),
|
||||||
..
|
..
|
||||||
})) = renderer.get_resource_info_mut(buffer)
|
})) = render_context.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
|
||||||
@ -517,10 +544,9 @@ where
|
|||||||
|
|
||||||
let total_size = item_size * new_capacity;
|
let total_size = item_size * new_capacity;
|
||||||
|
|
||||||
let buffer = renderer.create_buffer(BufferInfo {
|
let buffer = render_context.create_buffer(BufferInfo {
|
||||||
array_info: Some(BufferArrayInfo {
|
array_info: Some(BufferArrayInfo {
|
||||||
item_capacity: new_capacity,
|
item_capacity: new_capacity,
|
||||||
item_count: buffer_array_status.new_item_count,
|
|
||||||
item_size,
|
item_size,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}),
|
}),
|
||||||
@ -529,6 +555,8 @@ where
|
|||||||
is_dynamic: true,
|
is_dynamic: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
buffer_array_status.current_item_capacity = new_capacity;
|
||||||
|
|
||||||
log::trace!(
|
log::trace!(
|
||||||
"creating buffer for uniform {}. size: {} item_capacity: {} item_size: {}",
|
"creating buffer for uniform {}. size: {} item_capacity: {} item_size: {}",
|
||||||
std::any::type_name::<T>(),
|
std::any::type_name::<T>(),
|
||||||
@ -567,7 +595,7 @@ where
|
|||||||
|
|
||||||
fn copy_staging_buffer_to_final_buffers(
|
fn copy_staging_buffer_to_final_buffers(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
staging_buffer: RenderResource,
|
staging_buffer: RenderResource,
|
||||||
) {
|
) {
|
||||||
for uniform_buffer_status in self.uniform_buffer_status.iter_mut() {
|
for uniform_buffer_status in self.uniform_buffer_status.iter_mut() {
|
||||||
@ -578,7 +606,7 @@ where
|
|||||||
.drain(..)
|
.drain(..)
|
||||||
.enumerate()
|
.enumerate()
|
||||||
{
|
{
|
||||||
renderer.copy_buffer_to_buffer(
|
render_context.copy_buffer_to_buffer(
|
||||||
staging_buffer,
|
staging_buffer,
|
||||||
(start + (i * buffer_array_status.item_size)) as u64,
|
(start + (i * buffer_array_status.item_size)) as u64,
|
||||||
queued_buffer_write.buffer,
|
queued_buffer_write.buffer,
|
||||||
@ -597,16 +625,16 @@ where
|
|||||||
{
|
{
|
||||||
fn initialize(
|
fn initialize(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
let mut vertex_buffer_descriptors = resources.get_mut::<VertexBufferDescriptors>().unwrap();
|
||||||
self.initialize_vertex_buffer_descriptor(&mut vertex_buffer_descriptors);
|
self.initialize_vertex_buffer_descriptor(&mut vertex_buffer_descriptors);
|
||||||
self.update(renderer, world, resources);
|
self.update(render_context, world, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, _renderer: &mut dyn Renderer, 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);
|
||||||
@ -614,21 +642,21 @@ where
|
|||||||
|
|
||||||
fn finish_update(
|
fn finish_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut dyn Renderer,
|
render_context: &mut dyn RenderContext,
|
||||||
world: &mut World,
|
world: &mut World,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
) {
|
) {
|
||||||
// TODO: when setting batch shader_defs, add INSTANCING
|
// TODO: when setting batch shader_defs, add INSTANCING
|
||||||
self.setup_buffer_arrays(renderer);
|
self.setup_buffer_arrays(render_context);
|
||||||
|
|
||||||
let staging_buffer_size = self.update_staging_buffer_offsets();
|
let staging_buffer_size = self.update_staging_buffer_offsets();
|
||||||
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, renderer, &mut staging_buffer);
|
self.setup_uniforms_resources(world, resources, render_context, &mut staging_buffer);
|
||||||
self.setup_handles_resources(world, resources, renderer, &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_batched_resources(world, resources, renderer, &mut staging_buffer);
|
||||||
} else {
|
} else {
|
||||||
let staging_buffer = renderer.create_buffer_mapped(
|
let staging_buffer = render_context.create_buffer_mapped(
|
||||||
BufferInfo {
|
BufferInfo {
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
size: staging_buffer_size,
|
size: staging_buffer_size,
|
||||||
@ -641,8 +669,8 @@ where
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
self.copy_staging_buffer_to_final_buffers(renderer, staging_buffer);
|
self.copy_staging_buffer_to_final_buffers(render_context, staging_buffer);
|
||||||
renderer.remove_buffer(staging_buffer);
|
render_context.remove_buffer(staging_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,8 +2,9 @@ use crate::{
|
|||||||
render_resource::{
|
render_resource::{
|
||||||
BufferInfo, RenderResource, RenderResources, ResourceInfo,
|
BufferInfo, RenderResource, RenderResources, ResourceInfo,
|
||||||
},
|
},
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
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_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource;
|
||||||
@ -22,9 +23,13 @@ pub trait RenderContext {
|
|||||||
fn remove_texture(&mut self, resource: RenderResource);
|
fn remove_texture(&mut self, resource: RenderResource);
|
||||||
fn remove_sampler(&mut self, resource: RenderResource);
|
fn remove_sampler(&mut self, resource: RenderResource);
|
||||||
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo>;
|
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo>;
|
||||||
fn get_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo>;
|
fn get_local_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo>;
|
||||||
fn render_resources(&self) -> &RenderResources;
|
fn local_render_resources(&self) -> &RenderResources;
|
||||||
fn render_resources_mut(&mut self) -> &mut 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>,
|
||||||
@ -40,7 +45,7 @@ pub trait RenderContext {
|
|||||||
fn create_texture_with_data(
|
fn create_texture_with_data(
|
||||||
&mut self,
|
&mut self,
|
||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
bytes: Option<&[u8]>,
|
bytes: &[u8],
|
||||||
) -> RenderResource;
|
) -> RenderResource;
|
||||||
fn copy_buffer_to_buffer(
|
fn copy_buffer_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|||||||
@ -3,9 +3,10 @@ use crate::WgpuResources;
|
|||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
render_resource::{BufferInfo, RenderResource, RenderResources, ResourceInfo},
|
render_resource::{BufferInfo, RenderResource, RenderResources, ResourceInfo},
|
||||||
renderer_2::RenderContext,
|
renderer_2::RenderContext,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor, Texture}, mesh::Mesh,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use bevy_asset::Handle;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct LazyCommandEncoder {
|
struct LazyCommandEncoder {
|
||||||
@ -30,37 +31,50 @@ impl LazyCommandEncoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WgpuRenderContext {
|
pub struct WgpuRenderContext<'a> {
|
||||||
pub device: Arc<wgpu::Device>,
|
pub device: Arc<wgpu::Device>,
|
||||||
|
local_wgpu_resources: WgpuResources,
|
||||||
command_encoder: LazyCommandEncoder,
|
command_encoder: LazyCommandEncoder,
|
||||||
wgpu_resources: WgpuResources,
|
global_wgpu_resources: &'a WgpuResources,
|
||||||
|
removed_resources: Vec<RenderResource>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuRenderContext {
|
impl<'a> WgpuRenderContext<'a> {
|
||||||
pub fn new(device: Arc<wgpu::Device>) -> Self {
|
pub fn new(device: Arc<wgpu::Device>, global_wgpu_resources: &'a WgpuResources) -> Self {
|
||||||
WgpuRenderContext {
|
WgpuRenderContext {
|
||||||
device,
|
device,
|
||||||
|
global_wgpu_resources: global_wgpu_resources,
|
||||||
command_encoder: LazyCommandEncoder::default(),
|
command_encoder: LazyCommandEncoder::default(),
|
||||||
wgpu_resources: WgpuResources::default(),
|
local_wgpu_resources: WgpuResources::default(),
|
||||||
|
removed_resources: Vec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn finish(&mut self) -> Option<wgpu::CommandBuffer> {
|
pub fn finish(mut self) -> (Option<wgpu::CommandBuffer>, WgpuResources) {
|
||||||
self.command_encoder.take().map(|encoder| encoder.finish())
|
(self.command_encoder.take().map(|encoder| encoder.finish()), self.local_wgpu_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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderContext for WgpuRenderContext {
|
impl<'a> RenderContext for WgpuRenderContext<'a> {
|
||||||
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
fn create_sampler(&mut self, sampler_descriptor: &SamplerDescriptor) -> RenderResource {
|
||||||
self.wgpu_resources
|
self.local_wgpu_resources
|
||||||
.create_sampler(&self.device, sampler_descriptor)
|
.create_sampler(&self.device, sampler_descriptor)
|
||||||
}
|
}
|
||||||
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
|
fn create_texture(&mut self, texture_descriptor: &TextureDescriptor) -> RenderResource {
|
||||||
self.wgpu_resources
|
self.local_wgpu_resources
|
||||||
.create_texture(&self.device, texture_descriptor)
|
.create_texture(&self.device, texture_descriptor)
|
||||||
}
|
}
|
||||||
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.local_wgpu_resources.create_buffer(&self.device, buffer_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: clean this up
|
// TODO: clean this up
|
||||||
@ -74,14 +88,15 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
self,
|
self,
|
||||||
setup_data,
|
setup_data,
|
||||||
);
|
);
|
||||||
self.wgpu_resources.assign_buffer(buffer, buffer_info)
|
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: Option<&[u8]>,
|
bytes: &[u8],
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
self.wgpu_resources.create_texture_with_data(
|
self.local_wgpu_resources.create_texture_with_data(
|
||||||
&self.device,
|
&self.device,
|
||||||
self.command_encoder.get_or_create(&self.device),
|
self.command_encoder.get_or_create(&self.device),
|
||||||
texture_descriptor,
|
texture_descriptor,
|
||||||
@ -89,25 +104,75 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn remove_buffer(&mut self, resource: RenderResource) {
|
fn remove_buffer(&mut self, resource: RenderResource) {
|
||||||
self.wgpu_resources.remove_buffer(resource);
|
self.local_wgpu_resources.remove_buffer(resource);
|
||||||
|
self.removed_resources.push(resource);
|
||||||
}
|
}
|
||||||
fn remove_texture(&mut self, resource: RenderResource) {
|
fn remove_texture(&mut self, resource: RenderResource) {
|
||||||
self.wgpu_resources.remove_texture(resource);
|
self.local_wgpu_resources.remove_texture(resource);
|
||||||
|
self.removed_resources.push(resource);
|
||||||
}
|
}
|
||||||
fn remove_sampler(&mut self, resource: RenderResource) {
|
fn remove_sampler(&mut self, resource: RenderResource) {
|
||||||
self.wgpu_resources.remove_sampler(resource);
|
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> {
|
fn get_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||||
self.wgpu_resources.resource_info.get(&resource)
|
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_resource_info_mut(&mut self, resource: RenderResource) -> Option<&mut ResourceInfo> {
|
|
||||||
self.wgpu_resources.resource_info.get_mut(&resource)
|
|
||||||
|
fn get_local_resource_info(&self, resource: RenderResource) -> Option<&ResourceInfo> {
|
||||||
|
self.local_wgpu_resources.resource_info.get(&resource)
|
||||||
}
|
}
|
||||||
fn render_resources(&self) -> &RenderResources {
|
|
||||||
&self.wgpu_resources.render_resources
|
fn local_render_resources(&self) -> &RenderResources {
|
||||||
|
&self.local_wgpu_resources.render_resources
|
||||||
}
|
}
|
||||||
fn render_resources_mut(&mut self) -> &mut RenderResources {
|
fn local_render_resources_mut(&mut self) -> &mut RenderResources {
|
||||||
&mut self.wgpu_resources.render_resources
|
&mut self.local_wgpu_resources.render_resources
|
||||||
}
|
}
|
||||||
fn copy_buffer_to_buffer(
|
fn copy_buffer_to_buffer(
|
||||||
&mut self,
|
&mut self,
|
||||||
@ -117,17 +182,13 @@ impl RenderContext for WgpuRenderContext {
|
|||||||
destination_offset: u64,
|
destination_offset: u64,
|
||||||
size: u64,
|
size: u64,
|
||||||
) {
|
) {
|
||||||
self.wgpu_resources.copy_buffer_to_buffer(
|
let command_encoder = self.command_encoder.get_or_create(&self.device);
|
||||||
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();
|
||||||
source_buffer,
|
let destination_buffer = Self::get_buffer(destination_buffer, &self.local_wgpu_resources, &self.global_wgpu_resources).unwrap();
|
||||||
source_offset,
|
command_encoder.copy_buffer_to_buffer(source_buffer, source_offset, destination_buffer, destination_offset, size);
|
||||||
destination_buffer,
|
|
||||||
destination_offset,
|
|
||||||
size,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
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.local_wgpu_resources
|
||||||
.create_buffer_with_data(&self.device, buffer_info, data)
|
.create_buffer_with_data(&self.device, buffer_info, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,14 +13,14 @@ 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, BufferUsage, RenderResource, RenderResourceAssignments,
|
resource_name, BufferInfo, RenderResource, RenderResourceAssignments,
|
||||||
RenderResources, ResourceInfo,
|
RenderResources, ResourceInfo,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor},
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
};
|
};
|
||||||
use bevy_window::{Window, WindowCreated, WindowResized, Windows};
|
use bevy_window::{WindowCreated, WindowResized, Windows};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
@ -75,15 +75,6 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize(&mut self, world: &mut World, resources: &mut Resources) {
|
|
||||||
if self.intialized {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.initialize_resource_providers(world, resources);
|
|
||||||
self.intialized = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_render_pass<'a, 'b>(
|
pub fn create_render_pass<'a, 'b>(
|
||||||
wgpu_resources: &'a WgpuResources,
|
wgpu_resources: &'a WgpuResources,
|
||||||
pass_descriptor: &PassDescriptor,
|
pass_descriptor: &PassDescriptor,
|
||||||
@ -220,30 +211,29 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn initialize_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn initialize_resource_providers(
|
||||||
self.encoder = Some(
|
world: &mut World,
|
||||||
self.device
|
resources: &mut Resources,
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
render_context: &mut WgpuRenderContext,
|
||||||
);
|
) {
|
||||||
|
|
||||||
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() {
|
||||||
resource_provider.initialize(self, world, resources);
|
resource_provider.initialize(render_context, world, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
// consume current encoder
|
|
||||||
let command_buffer = self.encoder.take().unwrap().finish();
|
|
||||||
self.queue.submit(&[command_buffer]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_resource_providers(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn update_resource_providers(
|
||||||
|
world: &mut World,
|
||||||
|
resources: &mut Resources,
|
||||||
|
render_context: &mut WgpuRenderContext,
|
||||||
|
) {
|
||||||
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() {
|
||||||
resource_provider.update(self, world, resources);
|
resource_provider.update(render_context, world, resources);
|
||||||
}
|
}
|
||||||
|
|
||||||
for resource_provider in render_graph.resource_providers.iter_mut() {
|
for resource_provider in render_graph.resource_providers.iter_mut() {
|
||||||
resource_provider.finish_update(self, world, resources);
|
resource_provider.finish_update(render_context, world, resources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,14 +247,19 @@ impl WgpuRenderer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_window_resized_events(&mut self, resources: &mut Resources) {
|
pub fn handle_window_resized_events(
|
||||||
|
resources: &mut Resources,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
wgpu_resources: &mut WgpuResources,
|
||||||
|
window_resized_event_reader: &mut EventReader<WindowResized>,
|
||||||
|
) {
|
||||||
let windows = resources.get::<Windows>().unwrap();
|
let windows = resources.get::<Windows>().unwrap();
|
||||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
||||||
let mut handled_windows = HashSet::new();
|
let mut handled_windows = HashSet::new();
|
||||||
// iterate in reverse order so we can handle the latest window resize event first for each window.
|
// iterate in reverse order so we can handle the latest window resize event first for each window.
|
||||||
// we skip earlier events for the same window because it results in redundant work
|
// we skip earlier events for the same window because it results in redundant work
|
||||||
for window_resized_event in window_resized_events
|
for window_resized_event in window_resized_events
|
||||||
.iter(&mut self.window_resized_event_reader)
|
.iter(window_resized_event_reader)
|
||||||
.rev()
|
.rev()
|
||||||
{
|
{
|
||||||
if handled_windows.contains(&window_resized_event.id) {
|
if handled_windows.contains(&window_resized_event.id) {
|
||||||
@ -275,18 +270,23 @@ impl WgpuRenderer {
|
|||||||
.get(window_resized_event.id)
|
.get(window_resized_event.id)
|
||||||
.expect("Received window resized event for non-existent window");
|
.expect("Received window resized event for non-existent window");
|
||||||
|
|
||||||
self.setup_swap_chain(window);
|
// TODO: consider making this a WgpuRenderContext method
|
||||||
|
wgpu_resources
|
||||||
|
.create_window_swap_chain(device, window);
|
||||||
|
|
||||||
handled_windows.insert(window_resized_event.id);
|
handled_windows.insert(window_resized_event.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn handle_window_created_events(&mut self, resources: &mut Resources) {
|
pub fn handle_window_created_events(
|
||||||
|
resources: &mut Resources,
|
||||||
|
device: &wgpu::Device,
|
||||||
|
wgpu_resources: &mut WgpuResources,
|
||||||
|
window_created_event_reader: &mut EventReader<WindowCreated>,
|
||||||
|
) {
|
||||||
let windows = resources.get::<Windows>().unwrap();
|
let windows = resources.get::<Windows>().unwrap();
|
||||||
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
|
let window_created_events = resources.get::<Events<WindowCreated>>().unwrap();
|
||||||
for window_created_event in
|
for window_created_event in window_created_events.iter(window_created_event_reader) {
|
||||||
window_created_events.iter(&mut self.window_created_event_reader)
|
|
||||||
{
|
|
||||||
let window = windows
|
let window = windows
|
||||||
.get(window_created_event.id)
|
.get(window_created_event.id)
|
||||||
.expect("Received window created event for non-existent window");
|
.expect("Received window created event for non-existent window");
|
||||||
@ -295,30 +295,12 @@ impl WgpuRenderer {
|
|||||||
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
|
let winit_windows = resources.get::<bevy_winit::WinitWindows>().unwrap();
|
||||||
let primary_winit_window = winit_windows.get_window(window.id).unwrap();
|
let primary_winit_window = winit_windows.get_window(window.id).unwrap();
|
||||||
let surface = wgpu::Surface::create(primary_winit_window.deref());
|
let surface = wgpu::Surface::create(primary_winit_window.deref());
|
||||||
self.wgpu_resources
|
wgpu_resources.set_window_surface(window.id, surface);
|
||||||
.window_surfaces
|
wgpu_resources.create_window_swap_chain(device, window);
|
||||||
.insert(window.id, surface);
|
|
||||||
self.setup_swap_chain(window);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_swap_chain(&mut self, window: &Window) {
|
|
||||||
let surface = self
|
|
||||||
.wgpu_resources
|
|
||||||
.window_surfaces
|
|
||||||
.get(&window.id)
|
|
||||||
.expect("Received window resized event for window without a wgpu surface");
|
|
||||||
|
|
||||||
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
|
||||||
let swap_chain = self
|
|
||||||
.device
|
|
||||||
.create_swap_chain(surface, &swap_chain_descriptor);
|
|
||||||
self.wgpu_resources
|
|
||||||
.window_swap_chains
|
|
||||||
.insert(window.id, swap_chain);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_swap_chain_outputs(
|
fn get_swap_chain_outputs(
|
||||||
&mut self,
|
&mut self,
|
||||||
resources: &Resources,
|
resources: &Resources,
|
||||||
@ -349,16 +331,28 @@ impl WgpuRenderer {
|
|||||||
|
|
||||||
impl Renderer for WgpuRenderer {
|
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.initialize(world, resources);
|
Self::handle_window_created_events(
|
||||||
self.handle_window_created_events(resources);
|
resources,
|
||||||
self.handle_window_resized_events(resources);
|
&self.device,
|
||||||
|
&mut self.wgpu_resources,
|
||||||
|
&mut self.window_created_event_reader,
|
||||||
|
);
|
||||||
|
Self::handle_window_resized_events(
|
||||||
|
resources,
|
||||||
|
&self.device,
|
||||||
|
&mut self.wgpu_resources,
|
||||||
|
&mut self.window_resized_event_reader,
|
||||||
|
);
|
||||||
|
let mut render_context = WgpuRenderContext::new(self.device.clone(), &self.wgpu_resources);
|
||||||
|
if !self.intialized {
|
||||||
|
Self::initialize_resource_providers(world, resources, &mut render_context);
|
||||||
|
self.intialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: this self.encoder handoff is a bit gross, but its here to give resource providers access to buffer copies without
|
// TODO: this self.encoder handoff is a bit gross, but its here to give resource providers access to buffer copies without
|
||||||
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
|
// exposing the wgpu renderer internals to ResourceProvider traits. if this can be made cleaner that would be pretty cool.
|
||||||
self.encoder = Some(
|
|
||||||
self.device
|
|
||||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
|
||||||
);
|
|
||||||
|
|
||||||
// use bevy_render::renderer_2::RenderContext;
|
// use bevy_render::renderer_2::RenderContext;
|
||||||
// let thread_count = 5;
|
// let thread_count = 5;
|
||||||
@ -397,10 +391,21 @@ impl Renderer for WgpuRenderer {
|
|||||||
|
|
||||||
// self.queue.submit(&command_buffers);
|
// self.queue.submit(&command_buffers);
|
||||||
|
|
||||||
self.update_resource_providers(world, resources);
|
Self::update_resource_providers(world, resources, &mut render_context);
|
||||||
|
|
||||||
|
let (buffer, wgpu_resources) = render_context.finish();
|
||||||
|
self.wgpu_resources
|
||||||
|
.consume(wgpu_resources);
|
||||||
|
if let Some(buffer) = buffer {
|
||||||
|
self.queue.submit(&[buffer]);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.encoder = Some(
|
||||||
|
self.device
|
||||||
|
.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }),
|
||||||
|
);
|
||||||
update_shader_assignments(world, resources, self);
|
update_shader_assignments(world, resources, self);
|
||||||
self.create_queued_textures(resources);
|
self.create_queued_textures(resources);
|
||||||
|
|
||||||
let mut encoder = self.encoder.take().unwrap();
|
let mut encoder = self.encoder.take().unwrap();
|
||||||
|
|
||||||
// setup draw targets
|
// setup draw targets
|
||||||
@ -524,12 +529,17 @@ impl Renderer for WgpuRenderer {
|
|||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
bytes: Option<&[u8]>,
|
bytes: Option<&[u8]>,
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
self.wgpu_resources.create_texture_with_data(
|
if let Some(bytes) = bytes {
|
||||||
&self.device,
|
self.wgpu_resources.create_texture_with_data(
|
||||||
self.encoder.as_mut().unwrap(),
|
&self.device,
|
||||||
texture_descriptor,
|
self.encoder.as_mut().unwrap(),
|
||||||
bytes,
|
texture_descriptor,
|
||||||
)
|
bytes,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
self.wgpu_resources
|
||||||
|
.create_texture(&self.device, texture_descriptor)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn remove_texture(&mut self, resource: RenderResource) {
|
fn remove_texture(&mut self, resource: RenderResource) {
|
||||||
|
|||||||
@ -8,10 +8,11 @@ use bevy_render::{
|
|||||||
RenderResources, ResourceInfo,
|
RenderResources, ResourceInfo,
|
||||||
},
|
},
|
||||||
renderer::Renderer,
|
renderer::Renderer,
|
||||||
|
renderer_2::RenderContext,
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
texture::{SamplerDescriptor, TextureDescriptor}, renderer_2::RenderContext,
|
texture::{SamplerDescriptor, TextureDescriptor},
|
||||||
};
|
};
|
||||||
use bevy_window::WindowId;
|
use bevy_window::{Window, WindowId};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
@ -21,6 +22,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
|
||||||
pub render_resources: RenderResources,
|
pub render_resources: RenderResources,
|
||||||
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>,
|
||||||
@ -34,6 +36,41 @@ pub struct WgpuResources {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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.window_surfaces.extend(wgpu_resources.window_surfaces);
|
||||||
|
self.window_swap_chains
|
||||||
|
.extend(wgpu_resources.window_swap_chains);
|
||||||
|
self.buffers.extend(wgpu_resources.buffers);
|
||||||
|
self.textures.extend(wgpu_resources.textures);
|
||||||
|
self.samplers.extend(wgpu_resources.samplers);
|
||||||
|
self.resource_info.extend(wgpu_resources.resource_info);
|
||||||
|
self.shader_modules.extend(wgpu_resources.shader_modules);
|
||||||
|
self.bind_groups.extend(wgpu_resources.bind_groups);
|
||||||
|
self.bind_group_layouts
|
||||||
|
.extend(wgpu_resources.bind_group_layouts);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_window_surface(&mut self, window_id: WindowId, surface: wgpu::Surface) {
|
||||||
|
self.window_surfaces.insert(window_id, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_window_surface(&mut self, window_id: WindowId) -> Option<&wgpu::Surface> {
|
||||||
|
self.window_surfaces.get(&window_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_window_swap_chain(&mut self, device: &wgpu::Device, window: &Window) {
|
||||||
|
let swap_chain_descriptor: wgpu::SwapChainDescriptor = window.wgpu_into();
|
||||||
|
let surface = self
|
||||||
|
.window_surfaces
|
||||||
|
.get(&window.id)
|
||||||
|
.expect("No surface found for window");
|
||||||
|
let swap_chain = device.create_swap_chain(surface, &swap_chain_descriptor);
|
||||||
|
self.window_swap_chains.insert(window.id, swap_chain);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn add_resource_info(&mut self, resource: RenderResource, resource_info: ResourceInfo) {
|
pub fn add_resource_info(&mut self, resource: RenderResource, resource_info: ResourceInfo) {
|
||||||
self.resource_info.insert(resource, resource_info);
|
self.resource_info.insert(resource, resource_info);
|
||||||
}
|
}
|
||||||
@ -198,13 +235,11 @@ impl WgpuResources {
|
|||||||
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.device.clone();
|
||||||
let mut mapped = device.create_buffer_mapped(
|
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||||
&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, renderer);
|
setup_data(&mut mapped.data, renderer);
|
||||||
mapped.finish()
|
mapped.finish()
|
||||||
}
|
}
|
||||||
@ -216,13 +251,11 @@ impl WgpuResources {
|
|||||||
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext),
|
setup_data: &mut dyn FnMut(&mut [u8], &mut dyn RenderContext),
|
||||||
) -> wgpu::Buffer {
|
) -> wgpu::Buffer {
|
||||||
let device = render_context.device.clone();
|
let device = render_context.device.clone();
|
||||||
let mut mapped = device.create_buffer_mapped(
|
let mut mapped = device.create_buffer_mapped(&wgpu::BufferDescriptor {
|
||||||
&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_context);
|
||||||
mapped.finish()
|
mapped.finish()
|
||||||
}
|
}
|
||||||
@ -285,29 +318,27 @@ impl WgpuResources {
|
|||||||
device: &wgpu::Device,
|
device: &wgpu::Device,
|
||||||
encoder: &mut wgpu::CommandEncoder,
|
encoder: &mut wgpu::CommandEncoder,
|
||||||
texture_descriptor: &TextureDescriptor,
|
texture_descriptor: &TextureDescriptor,
|
||||||
bytes: Option<&[u8]>,
|
bytes: &[u8],
|
||||||
) -> RenderResource {
|
) -> RenderResource {
|
||||||
let descriptor: wgpu::TextureDescriptor = (*texture_descriptor).wgpu_into();
|
let descriptor: wgpu::TextureDescriptor = (*texture_descriptor).wgpu_into();
|
||||||
let texture = device.create_texture(&descriptor);
|
let texture = device.create_texture(&descriptor);
|
||||||
let texture_view = texture.create_default_view();
|
let texture_view = texture.create_default_view();
|
||||||
if let Some(bytes) = bytes {
|
let temp_buf = device.create_buffer_with_data(bytes, wgpu::BufferUsage::COPY_SRC);
|
||||||
let temp_buf = device.create_buffer_with_data(bytes, wgpu::BufferUsage::COPY_SRC);
|
encoder.copy_buffer_to_texture(
|
||||||
encoder.copy_buffer_to_texture(
|
wgpu::BufferCopyView {
|
||||||
wgpu::BufferCopyView {
|
buffer: &temp_buf,
|
||||||
buffer: &temp_buf,
|
offset: 0,
|
||||||
offset: 0,
|
bytes_per_row: 4 * descriptor.size.width,
|
||||||
bytes_per_row: 4 * descriptor.size.width,
|
rows_per_image: 0, // NOTE: Example sets this to 0, but should it be height?
|
||||||
rows_per_image: 0, // NOTE: Example sets this to 0, but should it be height?
|
},
|
||||||
},
|
wgpu::TextureCopyView {
|
||||||
wgpu::TextureCopyView {
|
texture: &texture,
|
||||||
texture: &texture,
|
mip_level: 0,
|
||||||
mip_level: 0,
|
array_layer: 0,
|
||||||
array_layer: 0,
|
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
||||||
origin: wgpu::Origin3d { x: 0, y: 0, z: 0 },
|
},
|
||||||
},
|
descriptor.size,
|
||||||
descriptor.size,
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
let resource = RenderResource::new();
|
let resource = RenderResource::new();
|
||||||
self.add_resource_info(resource, ResourceInfo::Texture);
|
self.add_resource_info(resource, ResourceInfo::Texture);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user