AssetRenderResourceNodes now consume asset change events. Remove EntitiesWaitingForAssets in favor of DrawState.
This commit is contained in:
parent
2e48269923
commit
fc4160ea41
@ -71,6 +71,7 @@ impl<T> Assets<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
pub fn get_mut(&mut self, handle: &Handle<T>) -> Option<&mut T> {
|
||||||
|
self.events.send(AssetEvent::Modified { handle: *handle });
|
||||||
self.assets.get_mut(&handle)
|
self.assets.get_mut(&handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use bevy_render::{
|
|||||||
base_render_graph,
|
base_render_graph,
|
||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_graph::{
|
render_graph::{
|
||||||
nodes::{AssetUniformNode, UniformNode},
|
nodes::{AssetRenderResourcesNode, RenderResourcesNode},
|
||||||
RenderGraph,
|
RenderGraph,
|
||||||
},
|
},
|
||||||
shader::Shader,
|
shader::Shader,
|
||||||
@ -28,10 +28,10 @@ pub trait ForwardPbrRenderGraphBuilder {
|
|||||||
|
|
||||||
impl ForwardPbrRenderGraphBuilder for RenderGraph {
|
impl ForwardPbrRenderGraphBuilder for RenderGraph {
|
||||||
fn add_pbr_graph(&mut self, resources: &Resources) -> &mut Self {
|
fn add_pbr_graph(&mut self, resources: &Resources) -> &mut Self {
|
||||||
self.add_system_node(node::TRANSFORM, UniformNode::<Transform>::new(true));
|
self.add_system_node(node::TRANSFORM, RenderResourcesNode::<Transform>::new(true));
|
||||||
self.add_system_node(
|
self.add_system_node(
|
||||||
node::STANDARD_MATERIAL,
|
node::STANDARD_MATERIAL,
|
||||||
AssetUniformNode::<StandardMaterial>::new(true),
|
AssetRenderResourcesNode::<StandardMaterial>::new(true),
|
||||||
);
|
);
|
||||||
self.add_system_node(node::LIGHTS, LightsNode::new(10));
|
self.add_system_node(node::LIGHTS, LightsNode::new(10));
|
||||||
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
|
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();
|
||||||
|
|||||||
@ -39,7 +39,6 @@ use draw::{clear_draw_system, Draw, RenderPipelines};
|
|||||||
use legion::prelude::IntoSystem;
|
use legion::prelude::IntoSystem;
|
||||||
use mesh::mesh_resource_provider_system;
|
use mesh::mesh_resource_provider_system;
|
||||||
use render_graph::RenderGraph;
|
use render_graph::RenderGraph;
|
||||||
use render_resource::EntitiesWaitingForAssets;
|
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
use texture::{PngTextureLoader, TextureResourceSystemState};
|
use texture::{PngTextureLoader, TextureResourceSystemState};
|
||||||
|
|
||||||
@ -83,7 +82,6 @@ impl AppPlugin for RenderPlugin {
|
|||||||
.init_resource::<PipelineCompiler>()
|
.init_resource::<PipelineCompiler>()
|
||||||
.init_resource::<RenderResourceAssignments>()
|
.init_resource::<RenderResourceAssignments>()
|
||||||
.init_resource::<VertexBufferDescriptors>()
|
.init_resource::<VertexBufferDescriptors>()
|
||||||
.init_resource::<EntitiesWaitingForAssets>()
|
|
||||||
.init_resource::<TextureResourceSystemState>()
|
.init_resource::<TextureResourceSystemState>()
|
||||||
.add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system())
|
.add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system())
|
||||||
.init_system_to_stage(
|
.init_system_to_stage(
|
||||||
@ -94,10 +92,6 @@ impl AppPlugin for RenderPlugin {
|
|||||||
bevy_app::stage::POST_UPDATE,
|
bevy_app::stage::POST_UPDATE,
|
||||||
camera::camera_system::<PerspectiveProjection>,
|
camera::camera_system::<PerspectiveProjection>,
|
||||||
)
|
)
|
||||||
.add_system_to_stage(
|
|
||||||
bevy_app::stage::PRE_UPDATE,
|
|
||||||
EntitiesWaitingForAssets::clear_system.system(),
|
|
||||||
)
|
|
||||||
.init_system_to_stage(stage::RENDER_RESOURCE, mesh_resource_provider_system)
|
.init_system_to_stage(stage::RENDER_RESOURCE, mesh_resource_provider_system)
|
||||||
.add_system_to_stage(
|
.add_system_to_stage(
|
||||||
stage::RENDER_RESOURCE,
|
stage::RENDER_RESOURCE,
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
mod camera_node;
|
mod camera_node;
|
||||||
mod pass_node;
|
mod pass_node;
|
||||||
mod texture_copy_node;
|
mod texture_copy_node;
|
||||||
mod uniform_node;
|
mod render_resources_node;
|
||||||
mod window_swapchain_node;
|
mod window_swapchain_node;
|
||||||
mod window_texture_node;
|
mod window_texture_node;
|
||||||
|
|
||||||
pub use camera_node::*;
|
pub use camera_node::*;
|
||||||
pub use pass_node::*;
|
pub use pass_node::*;
|
||||||
pub use texture_copy_node::*;
|
pub use texture_copy_node::*;
|
||||||
pub use uniform_node::*;
|
pub use render_resources_node::*;
|
||||||
pub use window_swapchain_node::*;
|
pub use window_swapchain_node::*;
|
||||||
pub use window_texture_node::*;
|
pub use window_texture_node::*;
|
||||||
|
|||||||
@ -1,10 +1,14 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
draw::{Draw, RenderCommand},
|
draw::{Draw, RenderCommand},
|
||||||
pass::{PassDescriptor, TextureAttachment},
|
pass::{PassDescriptor, TextureAttachment},
|
||||||
|
pipeline::PipelineDescriptor,
|
||||||
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
|
||||||
render_resource::{EntitiesWaitingForAssets, RenderResourceAssignments, ResourceInfo},
|
render_resource::{
|
||||||
|
RenderResourceAssignments, RenderResourceId, RenderResourceSetId, ResourceInfo,
|
||||||
|
},
|
||||||
renderer::RenderContext,
|
renderer::RenderContext,
|
||||||
};
|
};
|
||||||
|
use bevy_asset::{Assets, Handle};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
|
|
||||||
pub struct MainPassNode {
|
pub struct MainPassNode {
|
||||||
@ -63,8 +67,8 @@ impl Node for MainPassNode {
|
|||||||
input: &ResourceSlots,
|
input: &ResourceSlots,
|
||||||
_output: &mut ResourceSlots,
|
_output: &mut ResourceSlots,
|
||||||
) {
|
) {
|
||||||
let entities_waiting_for_assets = resources.get::<EntitiesWaitingForAssets>().unwrap();
|
|
||||||
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
let render_resource_assignments = resources.get::<RenderResourceAssignments>().unwrap();
|
||||||
|
let pipelines = resources.get::<Assets<PipelineDescriptor>>().unwrap();
|
||||||
|
|
||||||
for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() {
|
for (i, color_attachment) in self.descriptor.color_attachments.iter_mut().enumerate() {
|
||||||
if let Some(input_index) = self.color_attachment_input_indices[i] {
|
if let Some(input_index) = self.color_attachment_input_indices[i] {
|
||||||
@ -85,8 +89,9 @@ impl Node for MainPassNode {
|
|||||||
&self.descriptor,
|
&self.descriptor,
|
||||||
&render_resource_assignments,
|
&render_resource_assignments,
|
||||||
&mut |render_pass| {
|
&mut |render_pass| {
|
||||||
for (entity, draw) in <Read<Draw>>::query().iter_entities(&world) {
|
let mut draw_state = DrawState::default();
|
||||||
if !draw.is_visible || entities_waiting_for_assets.contains(&entity) {
|
for draw in <Read<Draw>>::query().iter(&world) {
|
||||||
|
if !draw.is_visible {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,17 +100,23 @@ impl Node for MainPassNode {
|
|||||||
RenderCommand::SetPipeline { pipeline } => {
|
RenderCommand::SetPipeline { pipeline } => {
|
||||||
// TODO: Filter pipelines
|
// TODO: Filter pipelines
|
||||||
render_pass.set_pipeline(*pipeline);
|
render_pass.set_pipeline(*pipeline);
|
||||||
|
let descriptor = pipelines.get(pipeline).unwrap();
|
||||||
|
draw_state.set_pipeline(*pipeline, descriptor);
|
||||||
}
|
}
|
||||||
RenderCommand::DrawIndexed {
|
RenderCommand::DrawIndexed {
|
||||||
base_vertex,
|
base_vertex,
|
||||||
indices,
|
indices,
|
||||||
instances,
|
instances,
|
||||||
} => {
|
} => {
|
||||||
render_pass.draw_indexed(
|
if draw_state.can_draw_indexed() {
|
||||||
indices.clone(),
|
render_pass.draw_indexed(
|
||||||
*base_vertex,
|
indices.clone(),
|
||||||
instances.clone(),
|
*base_vertex,
|
||||||
);
|
instances.clone(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
log::info!("Could not draw indexed because the pipeline layout wasn't fully set for pipeline: {:?}", draw_state.pipeline);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
RenderCommand::SetVertexBuffer {
|
RenderCommand::SetVertexBuffer {
|
||||||
buffer,
|
buffer,
|
||||||
@ -113,9 +124,11 @@ impl Node for MainPassNode {
|
|||||||
slot,
|
slot,
|
||||||
} => {
|
} => {
|
||||||
render_pass.set_vertex_buffer(*slot, *buffer, *offset);
|
render_pass.set_vertex_buffer(*slot, *buffer, *offset);
|
||||||
|
draw_state.set_vertex_buffer(*slot, *buffer);
|
||||||
}
|
}
|
||||||
RenderCommand::SetIndexBuffer { buffer, offset } => {
|
RenderCommand::SetIndexBuffer { buffer, offset } => {
|
||||||
render_pass.set_index_buffer(*buffer, *offset);
|
render_pass.set_index_buffer(*buffer, *offset);
|
||||||
|
draw_state.set_index_buffer(*buffer)
|
||||||
}
|
}
|
||||||
RenderCommand::SetBindGroup {
|
RenderCommand::SetBindGroup {
|
||||||
index,
|
index,
|
||||||
@ -131,6 +144,7 @@ impl Node for MainPassNode {
|
|||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|indices| indices.as_slice()),
|
.map(|indices| indices.as_slice()),
|
||||||
);
|
);
|
||||||
|
draw_state.set_bind_group(*index, *render_resource_set);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,3 +153,48 @@ impl Node for MainPassNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tracks the current pipeline state to ensure draw calls are valid.
|
||||||
|
#[derive(Default)]
|
||||||
|
struct DrawState {
|
||||||
|
pipeline: Option<Handle<PipelineDescriptor>>,
|
||||||
|
bind_groups: Vec<Option<RenderResourceSetId>>,
|
||||||
|
vertex_buffers: Vec<Option<RenderResourceId>>,
|
||||||
|
index_buffer: Option<RenderResourceId>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DrawState {
|
||||||
|
pub fn set_bind_group(&mut self, index: u32, render_resource_set: RenderResourceSetId) {
|
||||||
|
self.bind_groups[index as usize] = Some(render_resource_set);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_vertex_buffer(&mut self, index: u32, buffer: RenderResourceId) {
|
||||||
|
self.vertex_buffers[index as usize] = Some(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_index_buffer(&mut self, buffer: RenderResourceId) {
|
||||||
|
self.index_buffer = Some(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn can_draw_indexed(&self) -> bool {
|
||||||
|
self.bind_groups.iter().all(|b| b.is_some())
|
||||||
|
&& self.vertex_buffers.iter().all(|v| v.is_some())
|
||||||
|
&& self.index_buffer.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_pipeline(
|
||||||
|
&mut self,
|
||||||
|
handle: Handle<PipelineDescriptor>,
|
||||||
|
descriptor: &PipelineDescriptor,
|
||||||
|
) {
|
||||||
|
self.bind_groups.clear();
|
||||||
|
self.vertex_buffers.clear();
|
||||||
|
self.index_buffer = None;
|
||||||
|
|
||||||
|
self.pipeline = Some(handle);
|
||||||
|
let layout = descriptor.get_layout().unwrap();
|
||||||
|
self.bind_groups.resize(layout.bind_groups.len(), None);
|
||||||
|
self.vertex_buffers
|
||||||
|
.resize(layout.vertex_buffer_descriptors.len(), None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -2,19 +2,21 @@ use crate::{
|
|||||||
draw::{Draw, RenderPipelines},
|
draw::{Draw, RenderPipelines},
|
||||||
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
|
||||||
render_resource::{
|
render_resource::{
|
||||||
self, BufferInfo, BufferUsage, EntitiesWaitingForAssets, RenderResourceAssignment,
|
self, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
|
||||||
RenderResourceAssignments, RenderResourceAssignmentsId, RenderResourceHints,
|
RenderResourceAssignmentsId, RenderResourceHints, RenderResourceId,
|
||||||
RenderResourceId,
|
|
||||||
},
|
},
|
||||||
renderer::{RenderContext, RenderResourceContext, RenderResources},
|
renderer::{RenderContext, RenderResourceContext, RenderResources},
|
||||||
texture,
|
texture,
|
||||||
};
|
};
|
||||||
|
|
||||||
use bevy_app::EventReader;
|
use bevy_app::{EventReader, Events};
|
||||||
use bevy_asset::{AssetEvent, Assets, Handle};
|
use bevy_asset::{AssetEvent, Assets, Handle};
|
||||||
use legion::prelude::*;
|
use legion::prelude::*;
|
||||||
use render_resource::ResourceInfo;
|
use render_resource::ResourceInfo;
|
||||||
use std::{collections::HashMap, marker::PhantomData};
|
use std::{
|
||||||
|
collections::{HashMap, HashSet},
|
||||||
|
marker::PhantomData,
|
||||||
|
};
|
||||||
|
|
||||||
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
|
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -25,7 +27,7 @@ struct QueuedBufferWrite {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct BufferArrayStatus {
|
struct BufferArrayStatus {
|
||||||
new_item_count: usize,
|
changed_item_count: usize,
|
||||||
item_size: usize,
|
item_size: usize,
|
||||||
aligned_size: usize,
|
aligned_size: usize,
|
||||||
staging_buffer_offset: usize,
|
staging_buffer_offset: usize,
|
||||||
@ -78,15 +80,15 @@ impl<T> UniformBufferArrays<T>
|
|||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
fn reset_new_item_counts(&mut self) {
|
fn reset_changed_item_counts(&mut self) {
|
||||||
for buffer_status in self.uniform_arrays.iter_mut() {
|
for buffer_status in self.uniform_arrays.iter_mut() {
|
||||||
if let Some((_name, buffer_status)) = buffer_status {
|
if let Some((_name, buffer_status)) = buffer_status {
|
||||||
buffer_status.new_item_count = 0;
|
buffer_status.changed_item_count = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn increment_uniform_counts(&mut self, uniforms: &T) {
|
fn increment_changed_item_counts(&mut self, uniforms: &T) {
|
||||||
if self.uniform_arrays.len() != uniforms.render_resources_len() {
|
if self.uniform_arrays.len() != uniforms.render_resources_len() {
|
||||||
self.uniform_arrays
|
self.uniform_arrays
|
||||||
.resize_with(uniforms.render_resources_len(), || None);
|
.resize_with(uniforms.render_resources_len(), || None);
|
||||||
@ -96,12 +98,12 @@ where
|
|||||||
let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
|
let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
|
||||||
let size = render_resource.buffer_byte_len().unwrap();
|
let size = render_resource.buffer_byte_len().unwrap();
|
||||||
if let Some((ref _name, ref mut buffer_array_status)) = self.uniform_arrays[i] {
|
if let Some((ref _name, ref mut buffer_array_status)) = self.uniform_arrays[i] {
|
||||||
buffer_array_status.new_item_count += 1;
|
buffer_array_status.changed_item_count += 1;
|
||||||
} else {
|
} else {
|
||||||
self.uniform_arrays[i] = Some((
|
self.uniform_arrays[i] = Some((
|
||||||
render_resource_name.to_string(),
|
render_resource_name.to_string(),
|
||||||
BufferArrayStatus {
|
BufferArrayStatus {
|
||||||
new_item_count: 1,
|
changed_item_count: 1,
|
||||||
queued_buffer_writes: Vec::new(),
|
queued_buffer_writes: Vec::new(),
|
||||||
aligned_size: Self::get_aligned_dynamic_uniform_size(size),
|
aligned_size: Self::get_aligned_dynamic_uniform_size(size),
|
||||||
item_size: size,
|
item_size: size,
|
||||||
@ -134,7 +136,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
buffer_array_status.queued_buffer_writes =
|
buffer_array_status.queued_buffer_writes =
|
||||||
Vec::with_capacity(buffer_array_status.new_item_count);
|
Vec::with_capacity(buffer_array_status.changed_item_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,9 +146,9 @@ where
|
|||||||
render_resource_context: &dyn RenderResourceContext,
|
render_resource_context: &dyn RenderResourceContext,
|
||||||
align: bool,
|
align: bool,
|
||||||
) {
|
) {
|
||||||
if buffer_array_status.current_item_capacity < buffer_array_status.new_item_count {
|
if buffer_array_status.current_item_capacity < buffer_array_status.changed_item_count {
|
||||||
let new_capacity =
|
let new_capacity =
|
||||||
buffer_array_status.new_item_count + buffer_array_status.new_item_count / 2;
|
buffer_array_status.changed_item_count + buffer_array_status.changed_item_count / 2;
|
||||||
let mut item_size = buffer_array_status.item_size;
|
let mut item_size = buffer_array_status.item_size;
|
||||||
if align {
|
if align {
|
||||||
item_size = Self::get_aligned_dynamic_uniform_size(item_size);
|
item_size = Self::get_aligned_dynamic_uniform_size(item_size);
|
||||||
@ -177,7 +179,7 @@ where
|
|||||||
for dynamic_buffer_array_status in self.uniform_arrays.iter_mut() {
|
for dynamic_buffer_array_status in self.uniform_arrays.iter_mut() {
|
||||||
if let Some((_name, ref mut buffer_array_status)) = dynamic_buffer_array_status {
|
if let Some((_name, ref mut buffer_array_status)) = dynamic_buffer_array_status {
|
||||||
buffer_array_status.staging_buffer_offset = size;
|
buffer_array_status.staging_buffer_offset = size;
|
||||||
size += buffer_array_status.item_size * buffer_array_status.new_item_count;
|
size += buffer_array_status.item_size * buffer_array_status.changed_item_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,7 +300,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct UniformNode<T>
|
pub struct RenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -307,12 +309,12 @@ where
|
|||||||
_marker: PhantomData<T>,
|
_marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> UniformNode<T>
|
impl<T> RenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
pub fn new(dynamic_uniforms: bool) -> Self {
|
pub fn new(dynamic_uniforms: bool) -> Self {
|
||||||
UniformNode {
|
RenderResourcesNode {
|
||||||
command_queue: CommandQueue::default(),
|
command_queue: CommandQueue::default(),
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
_marker: PhantomData::default(),
|
_marker: PhantomData::default(),
|
||||||
@ -320,7 +322,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Node for UniformNode<T>
|
impl<T> Node for RenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -336,7 +338,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SystemNode for UniformNode<T>
|
impl<T> SystemNode for RenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -347,35 +349,30 @@ where
|
|||||||
// TODO: maybe run "update" here
|
// TODO: maybe run "update" here
|
||||||
(move |world: &mut SubWorld,
|
(move |world: &mut SubWorld,
|
||||||
render_resources: Res<RenderResources>,
|
render_resources: Res<RenderResources>,
|
||||||
entities_waiting_for_assets: Res<EntitiesWaitingForAssets>,
|
|
||||||
query: &mut Query<(Read<T>, Read<Draw>, Write<RenderPipelines>)>| {
|
query: &mut Query<(Read<T>, Read<Draw>, Write<RenderPipelines>)>| {
|
||||||
let render_resource_context = &*render_resources.context;
|
let render_resource_context = &*render_resources.context;
|
||||||
|
|
||||||
uniform_buffer_arrays.reset_new_item_counts();
|
uniform_buffer_arrays.reset_changed_item_counts();
|
||||||
// update uniforms info
|
// update uniforms info
|
||||||
for (uniforms, draw, _render_pipelines) in query.iter_mut(world) {
|
for (uniforms, draw, _render_pipelines) in query.iter_mut(world) {
|
||||||
if !draw.is_visible {
|
if !draw.is_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform_buffer_arrays.increment_uniform_counts(&uniforms);
|
uniform_buffer_arrays.increment_changed_item_counts(&uniforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform_buffer_arrays.setup_buffer_arrays(render_resource_context, dynamic_uniforms);
|
uniform_buffer_arrays.setup_buffer_arrays(render_resource_context, dynamic_uniforms);
|
||||||
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
|
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
|
||||||
|
|
||||||
for (entity, (uniforms, draw, mut render_pipelines)) in
|
for (uniforms, draw, mut render_pipelines) in query.iter_mut(world) {
|
||||||
query.iter_entities_mut(world)
|
|
||||||
{
|
|
||||||
if !draw.is_visible {
|
if !draw.is_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setup_uniform_texture_resources::<T>(
|
setup_uniform_texture_resources::<T>(
|
||||||
entity,
|
|
||||||
&uniforms,
|
&uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&entities_waiting_for_assets,
|
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_pipelines.render_resource_assignments,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -403,9 +400,7 @@ where
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
&mut |mut staging_buffer, _render_resources| {
|
&mut |mut staging_buffer, _render_resources| {
|
||||||
for (uniforms, draw, mut render_pipelines) in
|
for (uniforms, draw, mut render_pipelines) in query.iter_mut(world) {
|
||||||
query.iter_mut(world)
|
|
||||||
{
|
|
||||||
if !draw.is_visible {
|
if !draw.is_visible {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -431,7 +426,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct AssetUniformNode<T>
|
pub struct AssetRenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -440,12 +435,12 @@ where
|
|||||||
_marker: PhantomData<T>,
|
_marker: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> AssetUniformNode<T>
|
impl<T> AssetRenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
pub fn new(dynamic_uniforms: bool) -> Self {
|
pub fn new(dynamic_uniforms: bool) -> Self {
|
||||||
AssetUniformNode {
|
AssetRenderResourcesNode {
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
command_queue: Default::default(),
|
command_queue: Default::default(),
|
||||||
_marker: Default::default(),
|
_marker: Default::default(),
|
||||||
@ -453,7 +448,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Node for AssetUniformNode<T>
|
impl<T> Node for AssetRenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
@ -469,72 +464,79 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SystemNode for AssetUniformNode<T>
|
const EXPECT_ASSET_MESSAGE: &str = "Only assets that exist should be in the modified assets list";
|
||||||
|
|
||||||
|
impl<T> SystemNode for AssetRenderResourcesNode<T>
|
||||||
where
|
where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
{
|
{
|
||||||
fn get_system(&self) -> Box<dyn Schedulable> {
|
fn get_system(&self) -> Box<dyn Schedulable> {
|
||||||
let mut command_queue = self.command_queue.clone();
|
let mut command_queue = self.command_queue.clone();
|
||||||
let mut uniform_buffer_arrays = UniformBufferArrays::<T>::default();
|
let mut uniform_buffer_arrays = UniformBufferArrays::<T>::default();
|
||||||
|
let mut asset_event_reader = EventReader::<AssetEvent<T>>::default();
|
||||||
|
let mut asset_render_resource_assignments =
|
||||||
|
HashMap::<Handle<T>, RenderResourceAssignments>::default();
|
||||||
let dynamic_uniforms = self.dynamic_uniforms;
|
let dynamic_uniforms = self.dynamic_uniforms;
|
||||||
(move |world: &mut SubWorld,
|
(move |world: &mut SubWorld,
|
||||||
assets: Res<Assets<T>>,
|
assets: Res<Assets<T>>,
|
||||||
render_resources: Res<RenderResources>,
|
asset_events: Res<Events<AssetEvent<T>>>,
|
||||||
entities_waiting_for_assets: Res<EntitiesWaitingForAssets>,
|
render_resources: Res<RenderResources>,
|
||||||
query: &mut Query<(Read<Handle<T>>, Read<Draw>, Write<RenderPipelines>)>| {
|
query: &mut Query<(Read<Handle<T>>, Read<Draw>, Write<RenderPipelines>)>| {
|
||||||
let render_resource_context = &*render_resources.context;
|
let render_resource_context = &*render_resources.context;
|
||||||
uniform_buffer_arrays.reset_new_item_counts();
|
uniform_buffer_arrays.reset_changed_item_counts();
|
||||||
|
|
||||||
|
let mut modified_assets = HashSet::new();
|
||||||
|
for event in asset_event_reader.iter(&asset_events) {
|
||||||
|
match event {
|
||||||
|
AssetEvent::Created { handle } => {
|
||||||
|
modified_assets.insert(*handle);
|
||||||
|
}
|
||||||
|
AssetEvent::Modified { handle } => {
|
||||||
|
modified_assets.insert(*handle);
|
||||||
|
}
|
||||||
|
AssetEvent::Removed { handle } => {
|
||||||
|
// TODO: handle removals
|
||||||
|
modified_assets.remove(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// update uniform handles info
|
// update uniform handles info
|
||||||
for (entity, (handle, draw, _render_pipelines)) in query.iter_entities_mut(world) {
|
for asset_handle in modified_assets.iter() {
|
||||||
if !draw.is_visible {
|
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
||||||
return;
|
uniform_buffer_arrays.increment_changed_item_counts(&asset);
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(uniforms) = assets.get(&handle) {
|
|
||||||
// TODO: only increment count if we haven't seen this uniform handle before
|
|
||||||
uniform_buffer_arrays.increment_uniform_counts(&uniforms);
|
|
||||||
} else {
|
|
||||||
entities_waiting_for_assets.add(entity)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uniform_buffer_arrays.setup_buffer_arrays(render_resource_context, dynamic_uniforms);
|
uniform_buffer_arrays.setup_buffer_arrays(render_resource_context, dynamic_uniforms);
|
||||||
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
|
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
|
||||||
|
|
||||||
for (entity, (handle, draw, mut render_pipelines)) in
|
for asset_handle in modified_assets.iter() {
|
||||||
query.iter_entities_mut(world)
|
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
||||||
{
|
let mut render_resource_assignments = asset_render_resource_assignments
|
||||||
if !draw.is_visible {
|
.entry(*asset_handle)
|
||||||
return;
|
.or_insert_with(|| RenderResourceAssignments::default());
|
||||||
}
|
setup_uniform_texture_resources::<T>(
|
||||||
|
&asset,
|
||||||
if let Some(uniforms) = assets.get(&handle) {
|
render_resource_context,
|
||||||
setup_uniform_texture_resources::<T>(
|
&mut render_resource_assignments,
|
||||||
entity,
|
);
|
||||||
&uniforms,
|
|
||||||
render_resource_context,
|
|
||||||
&entities_waiting_for_assets,
|
|
||||||
&mut render_pipelines.render_resource_assignments,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if staging_buffer_size == 0 {
|
if staging_buffer_size == 0 {
|
||||||
let mut staging_buffer: [u8; 0] = [];
|
let mut staging_buffer: [u8; 0] = [];
|
||||||
for (handle, draw, mut render_pipelines) in query.iter_mut(world) {
|
for asset_handle in modified_assets.iter() {
|
||||||
if !draw.is_visible {
|
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
||||||
return;
|
let mut render_resource_assignments = asset_render_resource_assignments
|
||||||
}
|
.entry(*asset_handle)
|
||||||
if let Some(uniforms) = assets.get(&handle) {
|
.or_insert_with(|| RenderResourceAssignments::default());
|
||||||
// TODO: only setup buffer if we haven't seen this handle before
|
// TODO: only setup buffer if we haven't seen this handle before
|
||||||
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
||||||
&uniforms,
|
&asset,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_resource_assignments,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let staging_buffer = render_resource_context.create_buffer_mapped(
|
let staging_buffer = render_resource_context.create_buffer_mapped(
|
||||||
@ -544,20 +546,19 @@ where
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
&mut |mut staging_buffer, _render_resources| {
|
&mut |mut staging_buffer, _render_resources| {
|
||||||
for (handle, draw, mut render_pipelines) in query.iter_mut(world) {
|
for asset_handle in modified_assets.iter() {
|
||||||
if !draw.is_visible {
|
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
|
||||||
return;
|
let mut render_resource_assignments = asset_render_resource_assignments
|
||||||
}
|
.entry(*asset_handle)
|
||||||
if let Some(uniforms) = assets.get(&handle) {
|
.or_insert_with(|| RenderResourceAssignments::default());
|
||||||
// TODO: only setup buffer if we haven't seen this handle before
|
// TODO: only setup buffer if we haven't seen this handle before
|
||||||
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
uniform_buffer_arrays.setup_uniform_buffer_resources(
|
||||||
&uniforms,
|
&asset,
|
||||||
dynamic_uniforms,
|
dynamic_uniforms,
|
||||||
render_resource_context,
|
render_resource_context,
|
||||||
&mut render_pipelines.render_resource_assignments,
|
&mut render_resource_assignments,
|
||||||
&mut staging_buffer,
|
&mut staging_buffer,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -566,16 +567,20 @@ where
|
|||||||
.copy_staging_buffer_to_final_buffers(&mut command_queue, staging_buffer);
|
.copy_staging_buffer_to_final_buffers(&mut command_queue, staging_buffer);
|
||||||
command_queue.free_buffer(staging_buffer);
|
command_queue.free_buffer(staging_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (asset_handle, _draw, mut render_pipelines) in query.iter_mut(world) {
|
||||||
|
if let Some(asset_assignments) = asset_render_resource_assignments.get(&asset_handle) {
|
||||||
|
render_pipelines.render_resource_assignments.extend(asset_assignments);
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.system()
|
.system()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_uniform_texture_resources<T>(
|
fn setup_uniform_texture_resources<T>(
|
||||||
entity: Entity,
|
|
||||||
uniforms: &T,
|
uniforms: &T,
|
||||||
render_resource_context: &dyn RenderResourceContext,
|
render_resource_context: &dyn RenderResourceContext,
|
||||||
entities_waiting_for_assets: &EntitiesWaitingForAssets,
|
|
||||||
render_resource_assignments: &mut RenderResourceAssignments,
|
render_resource_assignments: &mut RenderResourceAssignments,
|
||||||
) where
|
) where
|
||||||
T: render_resource::RenderResources,
|
T: render_resource::RenderResources,
|
||||||
@ -600,11 +605,7 @@ fn setup_uniform_texture_resources<T>(
|
|||||||
RenderResourceAssignment::Sampler(sampler_resource),
|
RenderResourceAssignment::Sampler(sampler_resource),
|
||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
} else {
|
|
||||||
entities_waiting_for_assets.add(entity);
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
entities_waiting_for_assets.add(entity);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,31 +0,0 @@
|
|||||||
use legion::prelude::{Entity, Res};
|
|
||||||
use std::{collections::HashSet, sync::RwLock};
|
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct EntitiesWaitingForAssets {
|
|
||||||
pub entities: RwLock<HashSet<Entity>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EntitiesWaitingForAssets {
|
|
||||||
pub fn add(&self, entity: Entity) {
|
|
||||||
self.entities
|
|
||||||
.write()
|
|
||||||
.expect("RwLock poisoned")
|
|
||||||
.insert(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn contains(&self, entity: &Entity) -> bool {
|
|
||||||
self.entities
|
|
||||||
.read()
|
|
||||||
.expect("RwLock poisoned")
|
|
||||||
.contains(entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear(&self) {
|
|
||||||
self.entities.write().expect("RwLock poisoned").clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn clear_system(entities_waiting_for_assets: Res<EntitiesWaitingForAssets>) {
|
|
||||||
entities_waiting_for_assets.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,5 +1,4 @@
|
|||||||
mod buffer;
|
mod buffer;
|
||||||
mod entities_waiting_for_assets;
|
|
||||||
mod render_resource;
|
mod render_resource;
|
||||||
mod render_resource_set;
|
mod render_resource_set;
|
||||||
mod render_resource_assignments;
|
mod render_resource_assignments;
|
||||||
@ -7,7 +6,6 @@ mod resource_info;
|
|||||||
mod systems;
|
mod systems;
|
||||||
|
|
||||||
pub use buffer::*;
|
pub use buffer::*;
|
||||||
pub use entities_waiting_for_assets::*;
|
|
||||||
pub use render_resource::*;
|
pub use render_resource::*;
|
||||||
pub use render_resource_set::*;
|
pub use render_resource_set::*;
|
||||||
pub use render_resource_assignments::*;
|
pub use render_resource_assignments::*;
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use super::{RenderResourceId, RenderResourceSet, RenderResourceSetId};
|
|||||||
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
|
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
hash::{Hash, Hasher},
|
hash::Hash,
|
||||||
ops::Range,
|
ops::Range,
|
||||||
};
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@ -60,6 +60,7 @@ impl RenderResourceAssignments {
|
|||||||
fn try_set_dirty(&mut self, name: &str, assignment: &RenderResourceAssignment) {
|
fn try_set_dirty(&mut self, name: &str, assignment: &RenderResourceAssignment) {
|
||||||
if let Some(current_assignment) = self.render_resources.get(name) {
|
if let Some(current_assignment) = self.render_resources.get(name) {
|
||||||
if current_assignment != assignment {
|
if current_assignment != assignment {
|
||||||
|
// TODO: this is crude. we shouldn't need to invalidate all render resource sets
|
||||||
for id in self.render_resource_sets.keys() {
|
for id in self.render_resource_sets.keys() {
|
||||||
self.dirty_render_resource_sets.insert(*id);
|
self.dirty_render_resource_sets.insert(*id);
|
||||||
}
|
}
|
||||||
@ -67,6 +68,18 @@ impl RenderResourceAssignments {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn extend(&mut self, render_resource_assignments: &RenderResourceAssignments) {
|
||||||
|
for (name, assignment) in render_resource_assignments.render_resources.iter() {
|
||||||
|
self.set(name, assignment.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (name, (vertex_buffer, index_buffer)) in
|
||||||
|
render_resource_assignments.vertex_buffers.iter()
|
||||||
|
{
|
||||||
|
self.set_vertex_buffer(name, *vertex_buffer, index_buffer.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_vertex_buffer(
|
pub fn get_vertex_buffer(
|
||||||
&self,
|
&self,
|
||||||
name: &str,
|
name: &str,
|
||||||
|
|||||||
@ -16,10 +16,10 @@ pub struct IndexedRenderResourceAssignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: consider renaming this to BindGroup for parity with renderer terminology
|
// TODO: consider renaming this to BindGroup for parity with renderer terminology
|
||||||
#[derive(Eq, PartialEq, Debug)]
|
#[derive(Clone, Eq, PartialEq, Debug)]
|
||||||
pub struct RenderResourceSet {
|
pub struct RenderResourceSet {
|
||||||
pub id: RenderResourceSetId,
|
pub id: RenderResourceSetId,
|
||||||
pub indexed_assignments: Vec<IndexedRenderResourceAssignment>,
|
pub indexed_assignments: Arc<Vec<IndexedRenderResourceAssignment>>,
|
||||||
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ impl RenderResourceSetBuilder {
|
|||||||
self.indexed_assignments.sort_by_key(|i| i.index);
|
self.indexed_assignments.sort_by_key(|i| i.index);
|
||||||
RenderResourceSet {
|
RenderResourceSet {
|
||||||
id: RenderResourceSetId(self.hasher.finish()),
|
id: RenderResourceSetId(self.hasher.finish()),
|
||||||
indexed_assignments: self.indexed_assignments,
|
indexed_assignments: Arc::new(self.indexed_assignments),
|
||||||
dynamic_uniform_indices: if self.dynamic_uniform_indices.is_empty() {
|
dynamic_uniform_indices: if self.dynamic_uniform_indices.is_empty() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use bevy_render::{
|
|||||||
base_render_graph,
|
base_render_graph,
|
||||||
pipeline::{state_descriptors::*, PipelineDescriptor},
|
pipeline::{state_descriptors::*, PipelineDescriptor},
|
||||||
render_graph::{
|
render_graph::{
|
||||||
nodes::{AssetUniformNode, UniformNode},
|
nodes::{AssetRenderResourcesNode, RenderResourcesNode},
|
||||||
RenderGraph,
|
RenderGraph,
|
||||||
},
|
},
|
||||||
shader::{Shader, ShaderStage, ShaderStages},
|
shader::{Shader, ShaderStage, ShaderStages},
|
||||||
@ -123,23 +123,23 @@ impl SpriteRenderGraphBuilder for RenderGraph {
|
|||||||
fn add_sprite_graph(&mut self, resources: &Resources) -> &mut Self {
|
fn add_sprite_graph(&mut self, resources: &Resources) -> &mut Self {
|
||||||
self.add_system_node(
|
self.add_system_node(
|
||||||
node::COLOR_MATERIAL,
|
node::COLOR_MATERIAL,
|
||||||
AssetUniformNode::<ColorMaterial>::new(false),
|
AssetRenderResourcesNode::<ColorMaterial>::new(false),
|
||||||
);
|
);
|
||||||
self.add_node_edge(node::COLOR_MATERIAL, base_render_graph::node::MAIN_PASS)
|
self.add_node_edge(node::COLOR_MATERIAL, base_render_graph::node::MAIN_PASS)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.add_system_node(node::QUAD, UniformNode::<Quad>::new(false));
|
self.add_system_node(node::QUAD, RenderResourcesNode::<Quad>::new(false));
|
||||||
self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS)
|
self.add_node_edge(node::QUAD, base_render_graph::node::MAIN_PASS)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
self.add_system_node(
|
self.add_system_node(
|
||||||
node::SPRITE_SHEET,
|
node::SPRITE_SHEET,
|
||||||
AssetUniformNode::<TextureAtlas>::new(false),
|
AssetRenderResourcesNode::<TextureAtlas>::new(false),
|
||||||
);
|
);
|
||||||
|
|
||||||
self.add_system_node(
|
self.add_system_node(
|
||||||
node::SPRITE_SHEET_SPRITE,
|
node::SPRITE_SHEET_SPRITE,
|
||||||
UniformNode::<TextureAtlasSprite>::new(true),
|
RenderResourcesNode::<TextureAtlasSprite>::new(true),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
|
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();
|
||||||
|
|||||||
@ -53,7 +53,7 @@ fn setup(
|
|||||||
fragment: Some(shaders.add(Shader::from_glsl(ShaderStage::Fragment, FRAGMENT_SHADER))),
|
fragment: Some(shaders.add(Shader::from_glsl(ShaderStage::Fragment, FRAGMENT_SHADER))),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
render_graph.add_system_node("my_material", AssetUniformNode::<MyMaterial>::new(true));
|
render_graph.add_system_node("my_material", AssetRenderResourcesNode::<MyMaterial>::new(true));
|
||||||
pipeline_handle
|
pipeline_handle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -63,7 +63,7 @@ fn setup(
|
|||||||
vertex: shaders.add(Shader::from_glsl(ShaderStage::Vertex, VERTEX_SHADER)),
|
vertex: shaders.add(Shader::from_glsl(ShaderStage::Vertex, VERTEX_SHADER)),
|
||||||
fragment: Some(shaders.add(Shader::from_glsl(ShaderStage::Fragment, FRAGMENT_SHADER))),
|
fragment: Some(shaders.add(Shader::from_glsl(ShaderStage::Fragment, FRAGMENT_SHADER))),
|
||||||
}));
|
}));
|
||||||
render_graph.add_system_node("my_material", AssetUniformNode::<MyMaterial>::new(true));
|
render_graph.add_system_node("my_material", AssetRenderResourcesNode::<MyMaterial>::new(true));
|
||||||
pipeline_handle
|
pipeline_handle
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -19,7 +19,7 @@ pub use crate::{
|
|||||||
pipeline::PipelineDescriptor,
|
pipeline::PipelineDescriptor,
|
||||||
render_graph::{
|
render_graph::{
|
||||||
nodes::{
|
nodes::{
|
||||||
AssetUniformNode, CameraNode, MainPassNode, UniformNode, WindowSwapChainNode,
|
AssetRenderResourcesNode, CameraNode, MainPassNode, RenderResourcesNode, WindowSwapChainNode,
|
||||||
WindowTextureNode,
|
WindowTextureNode,
|
||||||
},
|
},
|
||||||
RenderGraph,
|
RenderGraph,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user