AssetRenderResourceNodes now consume asset change events. Remove EntitiesWaitingForAssets in favor of DrawState.

This commit is contained in:
Carter Anderson 2020-06-10 18:54:17 -07:00
parent 2e48269923
commit fc4160ea41
14 changed files with 202 additions and 167 deletions

View file

@ -71,6 +71,7 @@ impl<T> Assets<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)
}

View file

@ -4,7 +4,7 @@ use bevy_render::{
base_render_graph,
pipeline::PipelineDescriptor,
render_graph::{
nodes::{AssetUniformNode, UniformNode},
nodes::{AssetRenderResourcesNode, RenderResourcesNode},
RenderGraph,
},
shader::Shader,
@ -28,10 +28,10 @@ pub trait ForwardPbrRenderGraphBuilder {
impl ForwardPbrRenderGraphBuilder for RenderGraph {
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(
node::STANDARD_MATERIAL,
AssetUniformNode::<StandardMaterial>::new(true),
AssetRenderResourcesNode::<StandardMaterial>::new(true),
);
self.add_system_node(node::LIGHTS, LightsNode::new(10));
let mut shaders = resources.get_mut::<Assets<Shader>>().unwrap();

View file

@ -39,7 +39,6 @@ use draw::{clear_draw_system, Draw, RenderPipelines};
use legion::prelude::IntoSystem;
use mesh::mesh_resource_provider_system;
use render_graph::RenderGraph;
use render_resource::EntitiesWaitingForAssets;
use std::ops::Range;
use texture::{PngTextureLoader, TextureResourceSystemState};
@ -83,7 +82,6 @@ impl AppPlugin for RenderPlugin {
.init_resource::<PipelineCompiler>()
.init_resource::<RenderResourceAssignments>()
.init_resource::<VertexBufferDescriptors>()
.init_resource::<EntitiesWaitingForAssets>()
.init_resource::<TextureResourceSystemState>()
.add_system_to_stage(bevy_app::stage::PRE_UPDATE, clear_draw_system.system())
.init_system_to_stage(
@ -94,10 +92,6 @@ impl AppPlugin for RenderPlugin {
bevy_app::stage::POST_UPDATE,
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)
.add_system_to_stage(
stage::RENDER_RESOURCE,

View file

@ -1,13 +1,13 @@
mod camera_node;
mod pass_node;
mod texture_copy_node;
mod uniform_node;
mod render_resources_node;
mod window_swapchain_node;
mod window_texture_node;
pub use camera_node::*;
pub use pass_node::*;
pub use texture_copy_node::*;
pub use uniform_node::*;
pub use render_resources_node::*;
pub use window_swapchain_node::*;
pub use window_texture_node::*;

View file

@ -1,10 +1,14 @@
use crate::{
draw::{Draw, RenderCommand},
pass::{PassDescriptor, TextureAttachment},
pipeline::PipelineDescriptor,
render_graph::{Node, ResourceSlotInfo, ResourceSlots},
render_resource::{EntitiesWaitingForAssets, RenderResourceAssignments, ResourceInfo},
render_resource::{
RenderResourceAssignments, RenderResourceId, RenderResourceSetId, ResourceInfo,
},
renderer::RenderContext,
};
use bevy_asset::{Assets, Handle};
use legion::prelude::*;
pub struct MainPassNode {
@ -63,8 +67,8 @@ impl Node for MainPassNode {
input: &ResourceSlots,
_output: &mut ResourceSlots,
) {
let entities_waiting_for_assets = resources.get::<EntitiesWaitingForAssets>().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() {
if let Some(input_index) = self.color_attachment_input_indices[i] {
@ -85,8 +89,9 @@ impl Node for MainPassNode {
&self.descriptor,
&render_resource_assignments,
&mut |render_pass| {
for (entity, draw) in <Read<Draw>>::query().iter_entities(&world) {
if !draw.is_visible || entities_waiting_for_assets.contains(&entity) {
let mut draw_state = DrawState::default();
for draw in <Read<Draw>>::query().iter(&world) {
if !draw.is_visible {
continue;
}
@ -95,17 +100,23 @@ impl Node for MainPassNode {
RenderCommand::SetPipeline { pipeline } => {
// TODO: Filter pipelines
render_pass.set_pipeline(*pipeline);
let descriptor = pipelines.get(pipeline).unwrap();
draw_state.set_pipeline(*pipeline, descriptor);
}
RenderCommand::DrawIndexed {
base_vertex,
indices,
instances,
} => {
render_pass.draw_indexed(
indices.clone(),
*base_vertex,
instances.clone(),
);
if draw_state.can_draw_indexed() {
render_pass.draw_indexed(
indices.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 {
buffer,
@ -113,9 +124,11 @@ impl Node for MainPassNode {
slot,
} => {
render_pass.set_vertex_buffer(*slot, *buffer, *offset);
draw_state.set_vertex_buffer(*slot, *buffer);
}
RenderCommand::SetIndexBuffer { buffer, offset } => {
render_pass.set_index_buffer(*buffer, *offset);
draw_state.set_index_buffer(*buffer)
}
RenderCommand::SetBindGroup {
index,
@ -131,6 +144,7 @@ impl Node for MainPassNode {
.as_ref()
.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);
}
}

View file

@ -2,19 +2,21 @@ use crate::{
draw::{Draw, RenderPipelines},
render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
render_resource::{
self, BufferInfo, BufferUsage, EntitiesWaitingForAssets, RenderResourceAssignment,
RenderResourceAssignments, RenderResourceAssignmentsId, RenderResourceHints,
RenderResourceId,
self, BufferInfo, BufferUsage, RenderResourceAssignment, RenderResourceAssignments,
RenderResourceAssignmentsId, RenderResourceHints, RenderResourceId,
},
renderer::{RenderContext, RenderResourceContext, RenderResources},
texture,
};
use bevy_app::EventReader;
use bevy_app::{EventReader, Events};
use bevy_asset::{AssetEvent, Assets, Handle};
use legion::prelude::*;
use render_resource::ResourceInfo;
use std::{collections::HashMap, marker::PhantomData};
use std::{
collections::{HashMap, HashSet},
marker::PhantomData,
};
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
#[derive(Debug)]
@ -25,7 +27,7 @@ struct QueuedBufferWrite {
#[derive(Debug)]
struct BufferArrayStatus {
new_item_count: usize,
changed_item_count: usize,
item_size: usize,
aligned_size: usize,
staging_buffer_offset: usize,
@ -78,15 +80,15 @@ impl<T> UniformBufferArrays<T>
where
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() {
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() {
self.uniform_arrays
.resize_with(uniforms.render_resources_len(), || None);
@ -96,12 +98,12 @@ where
let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
let size = render_resource.buffer_byte_len().unwrap();
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 {
self.uniform_arrays[i] = Some((
render_resource_name.to_string(),
BufferArrayStatus {
new_item_count: 1,
changed_item_count: 1,
queued_buffer_writes: Vec::new(),
aligned_size: Self::get_aligned_dynamic_uniform_size(size),
item_size: size,
@ -134,7 +136,7 @@ where
}
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,
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 =
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;
if align {
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() {
if let Some((_name, ref mut buffer_array_status)) = dynamic_buffer_array_status {
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)]
pub struct UniformNode<T>
pub struct RenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
@ -307,12 +309,12 @@ where
_marker: PhantomData<T>,
}
impl<T> UniformNode<T>
impl<T> RenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
pub fn new(dynamic_uniforms: bool) -> Self {
UniformNode {
RenderResourcesNode {
command_queue: CommandQueue::default(),
dynamic_uniforms,
_marker: PhantomData::default(),
@ -320,7 +322,7 @@ where
}
}
impl<T> Node for UniformNode<T>
impl<T> Node for RenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
@ -336,7 +338,7 @@ where
}
}
impl<T> SystemNode for UniformNode<T>
impl<T> SystemNode for RenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
@ -347,35 +349,30 @@ where
// TODO: maybe run "update" here
(move |world: &mut SubWorld,
render_resources: Res<RenderResources>,
entities_waiting_for_assets: Res<EntitiesWaitingForAssets>,
query: &mut Query<(Read<T>, Read<Draw>, Write<RenderPipelines>)>| {
let render_resource_context = &*render_resources.context;
uniform_buffer_arrays.reset_new_item_counts();
uniform_buffer_arrays.reset_changed_item_counts();
// update uniforms info
for (uniforms, draw, _render_pipelines) in query.iter_mut(world) {
if !draw.is_visible {
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);
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
for (entity, (uniforms, draw, mut render_pipelines)) in
query.iter_entities_mut(world)
{
for (uniforms, draw, mut render_pipelines) in query.iter_mut(world) {
if !draw.is_visible {
return;
}
setup_uniform_texture_resources::<T>(
entity,
&uniforms,
render_resource_context,
&entities_waiting_for_assets,
&mut render_pipelines.render_resource_assignments,
)
}
@ -403,9 +400,7 @@ where
..Default::default()
},
&mut |mut staging_buffer, _render_resources| {
for (uniforms, draw, mut render_pipelines) in
query.iter_mut(world)
{
for (uniforms, draw, mut render_pipelines) in query.iter_mut(world) {
if !draw.is_visible {
return;
}
@ -431,7 +426,7 @@ where
}
#[derive(Default)]
pub struct AssetUniformNode<T>
pub struct AssetRenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
@ -440,12 +435,12 @@ where
_marker: PhantomData<T>,
}
impl<T> AssetUniformNode<T>
impl<T> AssetRenderResourcesNode<T>
where
T: render_resource::RenderResources,
{
pub fn new(dynamic_uniforms: bool) -> Self {
AssetUniformNode {
AssetRenderResourcesNode {
dynamic_uniforms,
command_queue: Default::default(),
_marker: Default::default(),
@ -453,7 +448,7 @@ where
}
}
impl<T> Node for AssetUniformNode<T>
impl<T> Node for AssetRenderResourcesNode<T>
where
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
T: render_resource::RenderResources,
{
fn get_system(&self) -> Box<dyn Schedulable> {
let mut command_queue = self.command_queue.clone();
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;
(move |world: &mut SubWorld,
assets: Res<Assets<T>>,
render_resources: Res<RenderResources>,
entities_waiting_for_assets: Res<EntitiesWaitingForAssets>,
query: &mut Query<(Read<Handle<T>>, Read<Draw>, Write<RenderPipelines>)>| {
assets: Res<Assets<T>>,
asset_events: Res<Events<AssetEvent<T>>>,
render_resources: Res<RenderResources>,
query: &mut Query<(Read<Handle<T>>, Read<Draw>, Write<RenderPipelines>)>| {
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
for (entity, (handle, draw, _render_pipelines)) in query.iter_entities_mut(world) {
if !draw.is_visible {
return;
}
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)
}
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
uniform_buffer_arrays.increment_changed_item_counts(&asset);
}
uniform_buffer_arrays.setup_buffer_arrays(render_resource_context, dynamic_uniforms);
let staging_buffer_size = uniform_buffer_arrays.update_staging_buffer_offsets();
for (entity, (handle, draw, mut render_pipelines)) in
query.iter_entities_mut(world)
{
if !draw.is_visible {
return;
}
if let Some(uniforms) = assets.get(&handle) {
setup_uniform_texture_resources::<T>(
entity,
&uniforms,
render_resource_context,
&entities_waiting_for_assets,
&mut render_pipelines.render_resource_assignments,
)
}
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
setup_uniform_texture_resources::<T>(
&asset,
render_resource_context,
&mut render_resource_assignments,
);
}
if staging_buffer_size == 0 {
let mut staging_buffer: [u8; 0] = [];
for (handle, draw, mut render_pipelines) in query.iter_mut(world) {
if !draw.is_visible {
return;
}
if let Some(uniforms) = assets.get(&handle) {
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&uniforms,
dynamic_uniforms,
render_resource_context,
&mut render_pipelines.render_resource_assignments,
&mut staging_buffer,
);
}
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&asset,
dynamic_uniforms,
render_resource_context,
&mut render_resource_assignments,
&mut staging_buffer,
);
}
} else {
let staging_buffer = render_resource_context.create_buffer_mapped(
@ -544,20 +546,19 @@ where
..Default::default()
},
&mut |mut staging_buffer, _render_resources| {
for (handle, draw, mut render_pipelines) in query.iter_mut(world) {
if !draw.is_visible {
return;
}
if let Some(uniforms) = assets.get(&handle) {
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&uniforms,
dynamic_uniforms,
render_resource_context,
&mut render_pipelines.render_resource_assignments,
&mut staging_buffer,
);
}
for asset_handle in modified_assets.iter() {
let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
let mut render_resource_assignments = asset_render_resource_assignments
.entry(*asset_handle)
.or_insert_with(|| RenderResourceAssignments::default());
// TODO: only setup buffer if we haven't seen this handle before
uniform_buffer_arrays.setup_uniform_buffer_resources(
&asset,
dynamic_uniforms,
render_resource_context,
&mut render_resource_assignments,
&mut staging_buffer,
);
}
},
);
@ -566,16 +567,20 @@ where
.copy_staging_buffer_to_final_buffers(&mut command_queue, 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()
}
}
fn setup_uniform_texture_resources<T>(
entity: Entity,
uniforms: &T,
render_resource_context: &dyn RenderResourceContext,
entities_waiting_for_assets: &EntitiesWaitingForAssets,
render_resource_assignments: &mut RenderResourceAssignments,
) where
T: render_resource::RenderResources,
@ -600,11 +605,7 @@ fn setup_uniform_texture_resources<T>(
RenderResourceAssignment::Sampler(sampler_resource),
);
continue;
} else {
entities_waiting_for_assets.add(entity);
}
} else {
entities_waiting_for_assets.add(entity);
}
}
}

View file

@ -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();
}
}

View file

@ -1,5 +1,4 @@
mod buffer;
mod entities_waiting_for_assets;
mod render_resource;
mod render_resource_set;
mod render_resource_assignments;
@ -7,7 +6,6 @@ mod resource_info;
mod systems;
pub use buffer::*;
pub use entities_waiting_for_assets::*;
pub use render_resource::*;
pub use render_resource_set::*;
pub use render_resource_assignments::*;

View file

@ -2,7 +2,7 @@ use super::{RenderResourceId, RenderResourceSet, RenderResourceSetId};
use crate::pipeline::{BindGroupDescriptor, BindGroupDescriptorId, PipelineSpecialization};
use std::{
collections::{HashMap, HashSet},
hash::{Hash, Hasher},
hash::Hash,
ops::Range,
};
use uuid::Uuid;
@ -60,6 +60,7 @@ impl RenderResourceAssignments {
fn try_set_dirty(&mut self, name: &str, assignment: &RenderResourceAssignment) {
if let Some(current_assignment) = self.render_resources.get(name) {
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() {
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(
&self,
name: &str,

View file

@ -16,10 +16,10 @@ pub struct IndexedRenderResourceAssignment {
}
// TODO: consider renaming this to BindGroup for parity with renderer terminology
#[derive(Eq, PartialEq, Debug)]
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct RenderResourceSet {
pub id: RenderResourceSetId,
pub indexed_assignments: Vec<IndexedRenderResourceAssignment>,
pub indexed_assignments: Arc<Vec<IndexedRenderResourceAssignment>>,
pub dynamic_uniform_indices: Option<Arc<Vec<u32>>>,
}
@ -99,7 +99,7 @@ impl RenderResourceSetBuilder {
self.indexed_assignments.sort_by_key(|i| i.index);
RenderResourceSet {
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() {
None
} else {

View file

@ -4,7 +4,7 @@ use bevy_render::{
base_render_graph,
pipeline::{state_descriptors::*, PipelineDescriptor},
render_graph::{
nodes::{AssetUniformNode, UniformNode},
nodes::{AssetRenderResourcesNode, RenderResourcesNode},
RenderGraph,
},
shader::{Shader, ShaderStage, ShaderStages},
@ -123,23 +123,23 @@ impl SpriteRenderGraphBuilder for RenderGraph {
fn add_sprite_graph(&mut self, resources: &Resources) -> &mut Self {
self.add_system_node(
node::COLOR_MATERIAL,
AssetUniformNode::<ColorMaterial>::new(false),
AssetRenderResourcesNode::<ColorMaterial>::new(false),
);
self.add_node_edge(node::COLOR_MATERIAL, base_render_graph::node::MAIN_PASS)
.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)
.unwrap();
self.add_system_node(
node::SPRITE_SHEET,
AssetUniformNode::<TextureAtlas>::new(false),
AssetRenderResourcesNode::<TextureAtlas>::new(false),
);
self.add_system_node(
node::SPRITE_SHEET_SPRITE,
UniformNode::<TextureAtlasSprite>::new(true),
RenderResourcesNode::<TextureAtlasSprite>::new(true),
);
let mut pipelines = resources.get_mut::<Assets<PipelineDescriptor>>().unwrap();

View file

@ -53,7 +53,7 @@ fn setup(
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
};

View file

@ -63,7 +63,7 @@ fn setup(
vertex: shaders.add(Shader::from_glsl(ShaderStage::Vertex, VERTEX_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
};

View file

@ -19,7 +19,7 @@ pub use crate::{
pipeline::PipelineDescriptor,
render_graph::{
nodes::{
AssetUniformNode, CameraNode, MainPassNode, UniformNode, WindowSwapChainNode,
AssetRenderResourcesNode, CameraNode, MainPassNode, RenderResourcesNode, WindowSwapChainNode,
WindowTextureNode,
},
RenderGraph,