mirror of
https://github.com/bevyengine/bevy
synced 2025-02-18 06:58:34 +00:00
Initial RenderGraph2. Port CameraResourceProvider
This commit is contained in:
parent
3c83e34cc1
commit
210a50e781
5 changed files with 284 additions and 147 deletions
|
@ -54,7 +54,8 @@ use bevy_app::{stage, AppBuilder, AppPlugin, GetEventReader};
|
||||||
use bevy_asset::AssetStorage;
|
use bevy_asset::AssetStorage;
|
||||||
use bevy_transform::prelude::LocalToWorld;
|
use bevy_transform::prelude::LocalToWorld;
|
||||||
use bevy_window::WindowResized;
|
use bevy_window::WindowResized;
|
||||||
use render_resource::resource_providers::mesh_resource_provider_system;
|
use render_resource::resource_providers::{CameraNode, mesh_resource_provider_system};
|
||||||
|
use render_graph_2::RenderGraph2;
|
||||||
|
|
||||||
pub static RENDER_RESOURCE_STAGE: &str = "render_resource";
|
pub static RENDER_RESOURCE_STAGE: &str = "render_resource";
|
||||||
pub static RENDER_STAGE: &str = "render";
|
pub static RENDER_STAGE: &str = "render";
|
||||||
|
@ -77,9 +78,6 @@ impl RenderPlugin {
|
||||||
.add_draw_target(AssignedBatchesDrawTarget::default())
|
.add_draw_target(AssignedBatchesDrawTarget::default())
|
||||||
.add_draw_target(AssignedMeshesDrawTarget::default())
|
.add_draw_target(AssignedMeshesDrawTarget::default())
|
||||||
.add_draw_target(UiDrawTarget::default())
|
.add_draw_target(UiDrawTarget::default())
|
||||||
.add_resource_provider(CameraResourceProvider::new(
|
|
||||||
app.resources().get_event_reader::<WindowResized>(),
|
|
||||||
))
|
|
||||||
.add_resource_provider(Camera2dResourceProvider::new(
|
.add_resource_provider(Camera2dResourceProvider::new(
|
||||||
resources.get_event_reader::<WindowResized>(),
|
resources.get_event_reader::<WindowResized>(),
|
||||||
))
|
))
|
||||||
|
@ -93,21 +91,24 @@ impl RenderPlugin {
|
||||||
|
|
||||||
impl AppPlugin for RenderPlugin {
|
impl AppPlugin for RenderPlugin {
|
||||||
fn build(&self, app: &mut AppBuilder) {
|
fn build(&self, app: &mut AppBuilder) {
|
||||||
|
let mut render_graph = RenderGraph2::default();
|
||||||
|
render_graph.add_system_node(CameraNode::default(), app.resources_mut());
|
||||||
let mut asset_batchers = AssetBatchers::default();
|
let mut asset_batchers = AssetBatchers::default();
|
||||||
asset_batchers.batch_types2::<Mesh, StandardMaterial>();
|
asset_batchers.batch_types2::<Mesh, StandardMaterial>();
|
||||||
app.add_stage_after(stage::POST_UPDATE, RENDER_RESOURCE_STAGE)
|
app.add_stage_after(stage::POST_UPDATE, RENDER_RESOURCE_STAGE)
|
||||||
.add_stage_after(RENDER_RESOURCE_STAGE, RENDER_STAGE)
|
.add_stage_after(RENDER_RESOURCE_STAGE, RENDER_STAGE)
|
||||||
// resources
|
// resources
|
||||||
.add_resource(RenderGraph::default())
|
.add_resource(RenderGraph::default())
|
||||||
|
.add_resource(render_graph)
|
||||||
.add_resource(AssetStorage::<Mesh>::new())
|
.add_resource(AssetStorage::<Mesh>::new())
|
||||||
.add_resource(AssetStorage::<Texture>::new())
|
.add_resource(AssetStorage::<Texture>::new())
|
||||||
.add_resource(AssetStorage::<Shader>::new())
|
.add_resource(AssetStorage::<Shader>::new())
|
||||||
.add_resource(AssetStorage::<StandardMaterial>::new())
|
.add_resource(AssetStorage::<StandardMaterial>::new())
|
||||||
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
.add_resource(AssetStorage::<PipelineDescriptor>::new())
|
||||||
.add_resource(PipelineAssignments::new())
|
.add_resource(PipelineAssignments::new())
|
||||||
.add_resource(VertexBufferDescriptors::default())
|
|
||||||
.add_resource(PipelineCompiler::new())
|
.add_resource(PipelineCompiler::new())
|
||||||
.add_resource(RenderResourceAssignments::default())
|
.add_resource(RenderResourceAssignments::default())
|
||||||
|
.add_resource(VertexBufferDescriptors::default())
|
||||||
.add_resource(EntityRenderResourceAssignments::default())
|
.add_resource(EntityRenderResourceAssignments::default())
|
||||||
.add_resource(asset_batchers)
|
.add_resource(asset_batchers)
|
||||||
// core systems
|
// core systems
|
||||||
|
|
|
@ -1 +1,159 @@
|
||||||
|
use crate::{
|
||||||
|
render_resource::{RenderResource, ResourceInfo},
|
||||||
|
renderer_2::RenderContext,
|
||||||
|
};
|
||||||
|
use legion::prelude::{Executor, Resources, Schedulable, World};
|
||||||
|
use std::{
|
||||||
|
collections::{HashMap, VecDeque},
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
pub enum Command {
|
||||||
|
CopyBufferToBuffer {
|
||||||
|
source_buffer: RenderResource,
|
||||||
|
source_offset: u64,
|
||||||
|
destination_buffer: RenderResource,
|
||||||
|
destination_offset: u64,
|
||||||
|
size: u64,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct CommandQueue {
|
||||||
|
queue: Arc<Mutex<VecDeque<Command>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommandQueue {
|
||||||
|
fn push(&mut self, command: Command) {
|
||||||
|
self.queue.lock().unwrap().push_front(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn copy_buffer_to_buffer(
|
||||||
|
&mut self,
|
||||||
|
source_buffer: RenderResource,
|
||||||
|
source_offset: u64,
|
||||||
|
destination_buffer: RenderResource,
|
||||||
|
destination_offset: u64,
|
||||||
|
size: u64,
|
||||||
|
) {
|
||||||
|
self.push(Command::CopyBufferToBuffer {
|
||||||
|
source_buffer,
|
||||||
|
source_offset,
|
||||||
|
destination_buffer,
|
||||||
|
destination_offset,
|
||||||
|
size,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn execute(&mut self, render_context: &mut dyn RenderContext) {
|
||||||
|
for command in self.queue.lock().unwrap().drain(..) {
|
||||||
|
match command {
|
||||||
|
Command::CopyBufferToBuffer {
|
||||||
|
source_buffer,
|
||||||
|
source_offset,
|
||||||
|
destination_buffer,
|
||||||
|
destination_offset,
|
||||||
|
size,
|
||||||
|
} => render_context.copy_buffer_to_buffer(
|
||||||
|
source_buffer,
|
||||||
|
source_offset,
|
||||||
|
destination_buffer,
|
||||||
|
destination_offset,
|
||||||
|
size,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
|
||||||
|
pub struct NodeId(Uuid);
|
||||||
|
|
||||||
|
impl NodeId {
|
||||||
|
fn new() -> Self {
|
||||||
|
NodeId(Uuid::new_v4())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ResourceSlot {
|
||||||
|
name: Option<String>,
|
||||||
|
resource_type: ResourceInfo,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ResourceSlotBinding {
|
||||||
|
resource: RenderResource,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NodeDescriptor {
|
||||||
|
pub inputs: Vec<ResourceSlot>,
|
||||||
|
pub outputs: Vec<ResourceSlot>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait Node: Send + Sync + 'static {
|
||||||
|
fn descriptor(&self) -> &NodeDescriptor;
|
||||||
|
fn update(
|
||||||
|
&mut self,
|
||||||
|
world: &World,
|
||||||
|
resources: &Resources,
|
||||||
|
render_context: &mut dyn RenderContext,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait SystemNode: Node {
|
||||||
|
fn get_system(&self, resources: &mut Resources) -> Box<dyn Schedulable>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct RenderGraph2 {
|
||||||
|
nodes: HashMap<NodeId, Box<dyn Node>>,
|
||||||
|
new_systems: Vec<Box<dyn Schedulable>>,
|
||||||
|
system_executor: Option<Executor>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RenderGraph2 {
|
||||||
|
pub fn add_node<T>(&mut self, node: T) -> NodeId
|
||||||
|
where
|
||||||
|
T: Node + 'static,
|
||||||
|
{
|
||||||
|
let id = NodeId::new();
|
||||||
|
self.nodes.insert(id, Box::new(node));
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_system_node<T>(&mut self, node: T, resources: &mut Resources) -> NodeId
|
||||||
|
where
|
||||||
|
T: SystemNode + 'static,
|
||||||
|
{
|
||||||
|
let id = NodeId::new();
|
||||||
|
self.new_systems.push(node.get_system(resources));
|
||||||
|
self.nodes.insert(id, Box::new(node));
|
||||||
|
id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_schedule(&mut self) -> impl Iterator<Item = &mut Box<dyn Node>> {
|
||||||
|
self.nodes.values_mut()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn take_executor(&mut self) -> Option<Executor> {
|
||||||
|
// rebuild executor if there are new systems
|
||||||
|
if self.new_systems.len() > 0 {
|
||||||
|
let mut systems = self
|
||||||
|
.system_executor
|
||||||
|
.take()
|
||||||
|
.map(|executor| executor.into_vec())
|
||||||
|
.unwrap_or_else(|| Vec::new());
|
||||||
|
for system in self.new_systems.drain(..) {
|
||||||
|
systems.push(system);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.system_executor = Some(Executor::new(systems));
|
||||||
|
}
|
||||||
|
|
||||||
|
self.system_executor.take()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_executor(&mut self, executor: Executor) {
|
||||||
|
self.system_executor = Some(executor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,162 +1,107 @@
|
||||||
use bevy_window::WindowResized;
|
use bevy_window::WindowResized;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
render_resource::{
|
render_graph_2::{CommandQueue, Node, NodeDescriptor, SystemNode},
|
||||||
resource_name, BufferInfo, BufferUsage, RenderResource, RenderResourceAssignments,
|
render_resource::{resource_name, BufferInfo, BufferUsage, RenderResourceAssignments},
|
||||||
ResourceProvider,
|
|
||||||
},
|
|
||||||
renderer_2::{GlobalRenderResourceContext, RenderContext},
|
renderer_2::{GlobalRenderResourceContext, RenderContext},
|
||||||
ActiveCamera, Camera,
|
ActiveCamera, Camera,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_app::{EventReader, Events, GetEventReader};
|
use bevy_app::{Events, GetEventReader};
|
||||||
use bevy_transform::prelude::*;
|
use bevy_transform::prelude::*;
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use zerocopy::AsBytes;
|
use zerocopy::AsBytes;
|
||||||
|
|
||||||
pub fn camera_resource_provider_system(resources: &mut Resources) -> Box<dyn Schedulable> {
|
#[derive(Default)]
|
||||||
let mut camera_buffer = None;
|
pub struct CameraNode {
|
||||||
let mut tmp_buffer = None;
|
command_queue: CommandQueue,
|
||||||
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
|
|
||||||
SystemBuilder::new("camera_resource_provider")
|
|
||||||
.read_resource::<GlobalRenderResourceContext>()
|
|
||||||
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
|
|
||||||
.write_resource::<RenderResourceAssignments>()
|
|
||||||
.read_resource::<Events<WindowResized>>()
|
|
||||||
.with_query(<(Read<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query())
|
|
||||||
.build(
|
|
||||||
move |_,
|
|
||||||
world,
|
|
||||||
(
|
|
||||||
render_resource_context,
|
|
||||||
ref mut render_resource_assignments,
|
|
||||||
window_resized_events,
|
|
||||||
),
|
|
||||||
query| {
|
|
||||||
let render_resources = &render_resource_context.context;
|
|
||||||
if camera_buffer.is_none() {
|
|
||||||
let buffer = render_resources.create_buffer(BufferInfo {
|
|
||||||
size: std::mem::size_of::<[[f32; 4]; 4]>(),
|
|
||||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
|
||||||
..Default::default()
|
|
||||||
});
|
|
||||||
render_resource_assignments.set(resource_name::uniform::CAMERA, buffer);
|
|
||||||
camera_buffer = Some(buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
let primary_window_resized_event = window_resized_events
|
|
||||||
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
|
|
||||||
if let Some(_) = primary_window_resized_event {
|
|
||||||
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
|
|
||||||
for (camera, local_to_world, _) in query.iter(world) {
|
|
||||||
let camera_matrix: [[f32; 4]; 4] =
|
|
||||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
|
||||||
|
|
||||||
if let Some(old_tmp_buffer) = tmp_buffer {
|
|
||||||
render_resources.remove_buffer(old_tmp_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp_buffer = Some(render_resources.create_buffer_mapped(
|
|
||||||
BufferInfo {
|
|
||||||
size: matrix_size,
|
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
&mut |data, _renderer| {
|
|
||||||
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
// render_resources.copy_buffer_to_buffer(
|
|
||||||
// tmp_buffer.unwrap(),
|
|
||||||
// 0,
|
|
||||||
// camera_buffer.unwrap(),
|
|
||||||
// 0,
|
|
||||||
// matrix_size as u64,
|
|
||||||
// );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct CameraResourceProvider {
|
impl Node for CameraNode {
|
||||||
pub camera_buffer: Option<RenderResource>,
|
fn descriptor(&self) -> &NodeDescriptor {
|
||||||
pub tmp_buffer: Option<RenderResource>,
|
static DESCRIPTOR: Lazy<NodeDescriptor> = Lazy::new(|| NodeDescriptor {
|
||||||
pub window_resized_event_reader: EventReader<WindowResized>,
|
inputs: Vec::new(),
|
||||||
}
|
outputs: Vec::new(),
|
||||||
|
|
||||||
impl CameraResourceProvider {
|
|
||||||
pub fn new(window_resized_event_reader: EventReader<WindowResized>) -> Self {
|
|
||||||
CameraResourceProvider {
|
|
||||||
camera_buffer: None,
|
|
||||||
tmp_buffer: None,
|
|
||||||
window_resized_event_reader,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResourceProvider for CameraResourceProvider {
|
|
||||||
fn initialize(
|
|
||||||
&mut self,
|
|
||||||
render_context: &mut dyn RenderContext,
|
|
||||||
_world: &mut World,
|
|
||||||
resources: &Resources,
|
|
||||||
) {
|
|
||||||
let buffer = render_context.resources_mut().create_buffer(BufferInfo {
|
|
||||||
size: std::mem::size_of::<[[f32; 4]; 4]>(),
|
|
||||||
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
|
||||||
..Default::default()
|
|
||||||
});
|
});
|
||||||
|
&DESCRIPTOR
|
||||||
let mut render_resource_assignments =
|
|
||||||
resources.get_mut::<RenderResourceAssignments>().unwrap();
|
|
||||||
render_resource_assignments.set(resource_name::uniform::CAMERA, buffer);
|
|
||||||
self.camera_buffer = Some(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(
|
fn update(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
_world: &World,
|
||||||
|
_resources: &Resources,
|
||||||
render_context: &mut dyn RenderContext,
|
render_context: &mut dyn RenderContext,
|
||||||
world: &World,
|
|
||||||
resources: &Resources,
|
|
||||||
) {
|
) {
|
||||||
let window_resized_events = resources.get::<Events<WindowResized>>().unwrap();
|
self.command_queue.execute(render_context);
|
||||||
let primary_window_resized_event = window_resized_events
|
}
|
||||||
.find_latest(&mut self.window_resized_event_reader, |event| {
|
}
|
||||||
event.is_primary
|
|
||||||
});
|
impl SystemNode for CameraNode {
|
||||||
if let Some(_) = primary_window_resized_event {
|
fn get_system(&self, resources: &mut Resources) -> Box<dyn Schedulable> {
|
||||||
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
|
let mut camera_buffer = None;
|
||||||
for (camera, local_to_world, _) in
|
let mut tmp_buffer = None;
|
||||||
<(Read<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query().iter(world)
|
let mut window_resized_event_reader = resources.get_event_reader::<WindowResized>();
|
||||||
{
|
let mut command_queue = self.command_queue.clone();
|
||||||
let camera_matrix: [[f32; 4]; 4] =
|
SystemBuilder::new("camera_resource_provider")
|
||||||
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
.read_resource::<GlobalRenderResourceContext>()
|
||||||
|
// TODO: this write on RenderResourceAssignments will prevent this system from running in parallel with other systems that do the same
|
||||||
if let Some(old_tmp_buffer) = self.tmp_buffer {
|
.write_resource::<RenderResourceAssignments>()
|
||||||
render_context.resources_mut().remove_buffer(old_tmp_buffer);
|
.read_resource::<Events<WindowResized>>()
|
||||||
}
|
.with_query(<(Read<Camera>, Read<LocalToWorld>, Read<ActiveCamera>)>::query())
|
||||||
|
.build(
|
||||||
self.tmp_buffer = Some(render_context.resources_mut().create_buffer_mapped(
|
move |_,
|
||||||
BufferInfo {
|
world,
|
||||||
size: matrix_size,
|
(
|
||||||
buffer_usage: BufferUsage::COPY_SRC,
|
render_resource_context,
|
||||||
..Default::default()
|
ref mut render_resource_assignments,
|
||||||
},
|
window_resized_events,
|
||||||
&mut |data, _renderer| {
|
),
|
||||||
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
query| {
|
||||||
},
|
let render_resources = &render_resource_context.context;
|
||||||
));
|
if camera_buffer.is_none() {
|
||||||
|
let buffer = render_resources.create_buffer(BufferInfo {
|
||||||
render_context.copy_buffer_to_buffer(
|
size: std::mem::size_of::<[[f32; 4]; 4]>(),
|
||||||
self.tmp_buffer.unwrap(),
|
buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
|
||||||
0,
|
..Default::default()
|
||||||
self.camera_buffer.unwrap(),
|
});
|
||||||
0,
|
render_resource_assignments.set(resource_name::uniform::CAMERA, buffer);
|
||||||
matrix_size as u64,
|
camera_buffer = Some(buffer);
|
||||||
);
|
}
|
||||||
}
|
|
||||||
}
|
let primary_window_resized_event = window_resized_events
|
||||||
|
.find_latest(&mut window_resized_event_reader, |event| event.is_primary);
|
||||||
|
if let Some(_) = primary_window_resized_event {
|
||||||
|
let matrix_size = std::mem::size_of::<[[f32; 4]; 4]>();
|
||||||
|
for (camera, local_to_world, _) in query.iter(world) {
|
||||||
|
let camera_matrix: [[f32; 4]; 4] =
|
||||||
|
(camera.view_matrix * local_to_world.0).to_cols_array_2d();
|
||||||
|
|
||||||
|
if let Some(old_tmp_buffer) = tmp_buffer {
|
||||||
|
render_resources.remove_buffer(old_tmp_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_buffer = Some(render_resources.create_buffer_mapped(
|
||||||
|
BufferInfo {
|
||||||
|
size: matrix_size,
|
||||||
|
buffer_usage: BufferUsage::COPY_SRC,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
&mut |data, _renderer| {
|
||||||
|
data[0..matrix_size].copy_from_slice(camera_matrix.as_bytes());
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
|
command_queue.copy_buffer_to_buffer(
|
||||||
|
tmp_buffer.unwrap(),
|
||||||
|
0,
|
||||||
|
camera_buffer.unwrap(),
|
||||||
|
0,
|
||||||
|
matrix_size as u64,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ use bevy_asset::AssetStorage;
|
||||||
use bevy_render::{
|
use bevy_render::{
|
||||||
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
pipeline::{update_shader_assignments, PipelineCompiler, PipelineDescriptor},
|
||||||
render_graph::RenderGraph,
|
render_graph::RenderGraph,
|
||||||
|
render_graph_2::RenderGraph2,
|
||||||
render_resource::RenderResourceAssignments,
|
render_resource::RenderResourceAssignments,
|
||||||
renderer_2::{GlobalRenderResourceContext, RenderContext, RenderResourceContext},
|
renderer_2::{GlobalRenderResourceContext, RenderContext, RenderResourceContext},
|
||||||
};
|
};
|
||||||
|
@ -225,7 +226,39 @@ impl WgpuRenderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn run_graph(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
|
let mut executor = {
|
||||||
|
let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap();
|
||||||
|
render_graph.take_executor()
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(executor) = executor.as_mut() {
|
||||||
|
executor.execute(world, resources);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut render_graph = resources.get_mut::<RenderGraph2>().unwrap();
|
||||||
|
if let Some(executor) = executor.take() {
|
||||||
|
render_graph.set_executor(executor);
|
||||||
|
}
|
||||||
|
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
||||||
|
let render_resource_context = global_context
|
||||||
|
.context
|
||||||
|
.downcast_mut::<WgpuRenderResourceContext>()
|
||||||
|
.unwrap();
|
||||||
|
let mut render_context =
|
||||||
|
WgpuRenderContext::new(self.device.clone(), render_resource_context.clone());
|
||||||
|
for node in render_graph.get_schedule() {
|
||||||
|
node.update(world, resources, &mut render_context);
|
||||||
|
}
|
||||||
|
|
||||||
|
let command_buffer = render_context.finish();
|
||||||
|
if let Some(command_buffer) = command_buffer {
|
||||||
|
self.queue.submit(&[command_buffer]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
pub fn update(&mut self, world: &mut World, resources: &mut Resources) {
|
||||||
|
self.run_graph(world, resources);
|
||||||
let mut encoder = {
|
let mut encoder = {
|
||||||
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
let mut global_context = resources.get_mut::<GlobalRenderResourceContext>().unwrap();
|
||||||
let render_resource_context = global_context
|
let render_resource_context = global_context
|
||||||
|
|
|
@ -19,7 +19,7 @@ pub struct WgpuBindGroupInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Grabs a read lock on all wgpu resources. When paired with WgpuResourceRefs, this allows
|
/// Grabs a read lock on all wgpu resources. When paired with WgpuResourceRefs, this allows
|
||||||
/// us to pass in wgpu resources to wgpu::RenderPass<'a> with the appropriate lifetime. This is accomplished by
|
/// you to pass in wgpu resources to wgpu::RenderPass<'a> with the appropriate lifetime. This is accomplished by
|
||||||
/// grabbing a WgpuResourcesReadLock _before_ creating a wgpu::RenderPass, getting a WgpuResourcesRefs, and storing that
|
/// grabbing a WgpuResourcesReadLock _before_ creating a wgpu::RenderPass, getting a WgpuResourcesRefs, and storing that
|
||||||
/// in the pass.
|
/// in the pass.
|
||||||
///
|
///
|
||||||
|
@ -88,7 +88,7 @@ pub struct WgpuResources {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WgpuResources {
|
impl WgpuResources {
|
||||||
pub fn read<'a>(&'a self) -> WgpuResourcesReadLock<'a> {
|
pub fn read(&self) -> WgpuResourcesReadLock {
|
||||||
WgpuResourcesReadLock {
|
WgpuResourcesReadLock {
|
||||||
buffers: self.buffers.read().unwrap(),
|
buffers: self.buffers.read().unwrap(),
|
||||||
textures: self.textures.read().unwrap(),
|
textures: self.textures.read().unwrap(),
|
||||||
|
|
Loading…
Add table
Reference in a new issue