Fix despawn (#361)
* simplify RenderResourcesNode gpu array management * support removals in RenderResourcesNode
This commit is contained in:
		
							parent
							
								
									93040ef9a0
								
							
						
					
					
						commit
						89a1d360c1
					
				@ -66,7 +66,7 @@ pub fn derive_render_resources(input: TokenStream) -> TokenStream {
 | 
				
			|||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                fn iter_render_resources(&self) -> #bevy_render_path::renderer::RenderResourceIterator {
 | 
					                fn iter(&self) -> #bevy_render_path::renderer::RenderResourceIterator {
 | 
				
			||||||
                    #bevy_render_path::renderer::RenderResourceIterator::new(self)
 | 
					                    #bevy_render_path::renderer::RenderResourceIterator::new(self)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@ -167,7 +167,7 @@ pub fn derive_render_resources(input: TokenStream) -> TokenStream {
 | 
				
			|||||||
                    #render_resource_hints_ident[index].clone()
 | 
					                    #render_resource_hints_ident[index].clone()
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                fn iter_render_resources(&self) -> #bevy_render_path::renderer::RenderResourceIterator {
 | 
					                fn iter(&self) -> #bevy_render_path::renderer::RenderResourceIterator {
 | 
				
			||||||
                    #bevy_render_path::renderer::RenderResourceIterator::new(self)
 | 
					                    #bevy_render_path::renderer::RenderResourceIterator::new(self)
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,24 @@ use crate::{
 | 
				
			|||||||
    render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
 | 
					    render_graph::{CommandQueue, Node, ResourceSlots, SystemNode},
 | 
				
			||||||
    renderer::{
 | 
					    renderer::{
 | 
				
			||||||
        self, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding,
 | 
					        self, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding,
 | 
				
			||||||
        RenderResourceBindings, RenderResourceBindingsId, RenderResourceContext,
 | 
					        RenderResourceBindings, RenderResourceContext, RenderResourceHints,
 | 
				
			||||||
        RenderResourceHints,
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    texture,
 | 
					    texture,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use bevy_asset::{Assets, Handle};
 | 
					use bevy_asset::{Assets, Handle};
 | 
				
			||||||
use bevy_ecs::{Commands, IntoQuerySystem, Local, Query, Res, ResMut, Resources, System, World};
 | 
					use bevy_ecs::{
 | 
				
			||||||
 | 
					    Commands, Entity, IntoQuerySystem, Local, Query, Res, ResMut, Resources, System, World,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
use renderer::{AssetRenderResourceBindings, BufferId, RenderResourceType, RenderResources};
 | 
					use renderer::{AssetRenderResourceBindings, BufferId, RenderResourceType, RenderResources};
 | 
				
			||||||
use std::{collections::HashMap, marker::PhantomData, ops::DerefMut};
 | 
					use std::{collections::HashMap, hash::Hash, marker::PhantomData, ops::DerefMut};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub const BIND_BUFFER_ALIGNMENT: usize = 256;
 | 
					pub const BIND_BUFFER_ALIGNMENT: usize = 256;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fn get_aligned_dynamic_uniform_size(data_size: usize) -> usize {
 | 
				
			||||||
 | 
					    BIND_BUFFER_ALIGNMENT * ((data_size as f32 / BIND_BUFFER_ALIGNMENT as f32).ceil() as usize)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct QueuedBufferWrite {
 | 
					struct QueuedBufferWrite {
 | 
				
			||||||
    buffer: BufferId,
 | 
					    buffer: BufferId,
 | 
				
			||||||
@ -24,189 +30,191 @@ struct QueuedBufferWrite {
 | 
				
			|||||||
    size: usize,
 | 
					    size: usize,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Used to track items in a gpu buffer in an "array" style
 | 
				
			||||||
#[derive(Debug)]
 | 
					#[derive(Debug)]
 | 
				
			||||||
struct BufferArrayStatus {
 | 
					struct BufferArray<I> {
 | 
				
			||||||
    changed_item_count: usize,
 | 
					 | 
				
			||||||
    item_size: usize,
 | 
					    item_size: usize,
 | 
				
			||||||
    aligned_size: usize,
 | 
					    buffer_capacity: usize,
 | 
				
			||||||
    staging_buffer_offset: usize,
 | 
					    min_capacity: usize,
 | 
				
			||||||
 | 
					    len: usize,
 | 
				
			||||||
    buffer: Option<BufferId>,
 | 
					    buffer: Option<BufferId>,
 | 
				
			||||||
    queued_buffer_writes: Vec<QueuedBufferWrite>,
 | 
					    free_indices: Vec<usize>,
 | 
				
			||||||
    current_item_count: usize,
 | 
					    indices: HashMap<I, usize>,
 | 
				
			||||||
    current_item_capacity: usize,
 | 
					 | 
				
			||||||
    indices: HashMap<RenderResourceBindingsId, usize>,
 | 
					 | 
				
			||||||
    current_index: usize,
 | 
					 | 
				
			||||||
    // TODO: this is a hack to workaround RenderResources without a fixed length
 | 
					 | 
				
			||||||
    changed_size: usize,
 | 
					 | 
				
			||||||
    current_offset: usize,
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl BufferArrayStatus {
 | 
					impl<I: Hash + Eq> BufferArray<I> {
 | 
				
			||||||
    pub fn get_or_assign_index(&mut self, id: RenderResourceBindingsId) -> usize {
 | 
					    pub fn new(item_size: usize, min_capacity: usize, align: bool) -> Self {
 | 
				
			||||||
        if let Some(offset) = self.indices.get(&id) {
 | 
					        BufferArray {
 | 
				
			||||||
            *offset
 | 
					            item_size: if align {
 | 
				
			||||||
        } else {
 | 
					                get_aligned_dynamic_uniform_size(item_size)
 | 
				
			||||||
            if self.current_index == self.current_item_capacity {
 | 
					            } else {
 | 
				
			||||||
                panic!("no empty slots available in array");
 | 
					                item_size
 | 
				
			||||||
            }
 | 
					            },
 | 
				
			||||||
 | 
					            len: 0,
 | 
				
			||||||
 | 
					            buffer_capacity: 0,
 | 
				
			||||||
 | 
					            min_capacity,
 | 
				
			||||||
 | 
					            buffer: None,
 | 
				
			||||||
 | 
					            free_indices: Vec::new(),
 | 
				
			||||||
 | 
					            indices: HashMap::new(),
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            let index = self.current_index;
 | 
					    fn get_or_assign_index(&mut self, id: I) -> usize {
 | 
				
			||||||
 | 
					        if let Some(index) = self.indices.get(&id) {
 | 
				
			||||||
 | 
					            *index
 | 
				
			||||||
 | 
					        } else if let Some(index) = self.free_indices.pop() {
 | 
				
			||||||
            self.indices.insert(id, index);
 | 
					            self.indices.insert(id, index);
 | 
				
			||||||
            self.current_index += 1;
 | 
					            self.len += 1;
 | 
				
			||||||
 | 
					            index
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            let index = self.len;
 | 
				
			||||||
 | 
					            self.indices.insert(id, index);
 | 
				
			||||||
 | 
					            self.len += 1;
 | 
				
			||||||
            index
 | 
					            index
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn get_binding(&self, id: I) -> Option<RenderResourceBinding> {
 | 
				
			||||||
 | 
					        self.indices
 | 
				
			||||||
 | 
					            .get(&id)
 | 
				
			||||||
 | 
					            .map(|index| RenderResourceBinding::Buffer {
 | 
				
			||||||
 | 
					                buffer: self.buffer.unwrap(),
 | 
				
			||||||
 | 
					                dynamic_index: Some((index * self.item_size) as u32),
 | 
				
			||||||
 | 
					                range: 0..self.item_size as u64,
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn remove_binding(&mut self, id: I) {
 | 
				
			||||||
 | 
					        if let Some(index) = self.indices.remove(&id) {
 | 
				
			||||||
 | 
					            self.free_indices.push(index);
 | 
				
			||||||
 | 
					            self.len -= 1;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn resize(&mut self, render_resource_context: &dyn RenderResourceContext) {
 | 
				
			||||||
 | 
					        if self.len <= self.buffer_capacity {
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.allocate_buffer(render_resource_context);
 | 
				
			||||||
 | 
					        // TODO: allow shrinking
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pub fn allocate_buffer(&mut self, render_resource_context: &dyn RenderResourceContext) {
 | 
				
			||||||
 | 
					        if let Some(old_buffer) = self.buffer.take() {
 | 
				
			||||||
 | 
					            render_resource_context.remove_buffer(old_buffer);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let new_len = if self.buffer_capacity == 0 {
 | 
				
			||||||
 | 
					            self.min_capacity.max(self.len)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            self.min_capacity.max(self.len * 2)
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let size = new_len * self.item_size;
 | 
				
			||||||
 | 
					        let buffer = render_resource_context.create_buffer(BufferInfo {
 | 
				
			||||||
 | 
					            size,
 | 
				
			||||||
 | 
					            buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
 | 
				
			||||||
 | 
					            ..Default::default()
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.buffer = Some(buffer);
 | 
				
			||||||
 | 
					        self.buffer_capacity = new_len;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct UniformBufferArrays<T>
 | 
					struct UniformBufferArrays<I, T>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    T: renderer::RenderResources,
 | 
					    T: renderer::RenderResources,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    uniform_arrays: Vec<Option<(String, BufferArrayStatus)>>,
 | 
					    buffer_arrays: Vec<Option<BufferArray<I>>>,
 | 
				
			||||||
    staging_buffer: Option<BufferId>,
 | 
					    staging_buffer: Option<BufferId>,
 | 
				
			||||||
    staging_buffer_size: usize,
 | 
					    staging_buffer_size: usize,
 | 
				
			||||||
 | 
					    required_staging_buffer_size: usize,
 | 
				
			||||||
 | 
					    current_staging_buffer_offset: usize,
 | 
				
			||||||
 | 
					    queued_buffer_writes: Vec<QueuedBufferWrite>,
 | 
				
			||||||
    _marker: PhantomData<T>,
 | 
					    _marker: PhantomData<T>,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> Default for UniformBufferArrays<T>
 | 
					impl<I, T> Default for UniformBufferArrays<I, T>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
    T: renderer::RenderResources,
 | 
					    T: renderer::RenderResources,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            uniform_arrays: Default::default(),
 | 
					            buffer_arrays: Default::default(),
 | 
				
			||||||
            staging_buffer: Default::default(),
 | 
					            staging_buffer: Default::default(),
 | 
				
			||||||
            staging_buffer_size: 0,
 | 
					            staging_buffer_size: 0,
 | 
				
			||||||
 | 
					            current_staging_buffer_offset: 0,
 | 
				
			||||||
 | 
					            queued_buffer_writes: Vec::new(),
 | 
				
			||||||
 | 
					            required_staging_buffer_size: 0,
 | 
				
			||||||
            _marker: Default::default(),
 | 
					            _marker: Default::default(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T> UniformBufferArrays<T>
 | 
					impl<I, T> UniformBufferArrays<I, T>
 | 
				
			||||||
where
 | 
					where
 | 
				
			||||||
 | 
					    I: Hash + Eq + Copy,
 | 
				
			||||||
    T: renderer::RenderResources,
 | 
					    T: renderer::RenderResources,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    fn reset_changed_item_counts(&mut self) {
 | 
					    /// Initialize this UniformBufferArrays using information from a RenderResources value.
 | 
				
			||||||
        for buffer_status in self.uniform_arrays.iter_mut() {
 | 
					    fn initialize(&mut self, render_resources: &T) {
 | 
				
			||||||
            if let Some((_name, buffer_status)) = buffer_status {
 | 
					        if self.buffer_arrays.len() != render_resources.render_resources_len() {
 | 
				
			||||||
                buffer_status.changed_item_count = 0;
 | 
					            let mut buffer_arrays = Vec::with_capacity(render_resources.render_resources_len());
 | 
				
			||||||
                buffer_status.current_index = 0;
 | 
					            for render_resource in render_resources.iter() {
 | 
				
			||||||
                buffer_status.indices.clear();
 | 
					                if let Some(RenderResourceType::Buffer) = render_resource.resource_type() {
 | 
				
			||||||
                buffer_status.current_offset = 0;
 | 
					                    let size = render_resource.buffer_byte_len().unwrap();
 | 
				
			||||||
                buffer_status.changed_size = 0;
 | 
					                    buffer_arrays.push(Some(BufferArray::new(size, 10, true)));
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    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);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
 | 
					 | 
				
			||||||
            if let Some(RenderResourceType::Buffer) = render_resource.resource_type() {
 | 
					 | 
				
			||||||
                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.changed_item_count += 1;
 | 
					 | 
				
			||||||
                    buffer_array_status.changed_size += size;
 | 
					 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    self.uniform_arrays[i] = Some((
 | 
					                    buffer_arrays.push(None);
 | 
				
			||||||
                        render_resource_name.to_string(),
 | 
					                }
 | 
				
			||||||
                        BufferArrayStatus {
 | 
					            }
 | 
				
			||||||
                            changed_item_count: 1,
 | 
					
 | 
				
			||||||
                            queued_buffer_writes: Vec::new(),
 | 
					            self.buffer_arrays = buffer_arrays;
 | 
				
			||||||
                            aligned_size: Self::get_aligned_dynamic_uniform_size(size),
 | 
					        }
 | 
				
			||||||
                            item_size: size,
 | 
					    }
 | 
				
			||||||
                            staging_buffer_offset: 0,
 | 
					
 | 
				
			||||||
                            buffer: None,
 | 
					    /// Resets staging buffer tracking information
 | 
				
			||||||
                            current_index: 0,
 | 
					    fn begin_update(&mut self) {
 | 
				
			||||||
                            current_item_count: 0,
 | 
					        self.required_staging_buffer_size = 0;
 | 
				
			||||||
                            current_item_capacity: 0,
 | 
					        self.current_staging_buffer_offset = 0;
 | 
				
			||||||
                            indices: HashMap::new(),
 | 
					    }
 | 
				
			||||||
                            changed_size: size,
 | 
					
 | 
				
			||||||
                            current_offset: 0,
 | 
					    /// Find a spot for the given RenderResources in each uniform's BufferArray and prepare space in the staging buffer
 | 
				
			||||||
                        },
 | 
					    fn prepare_uniform_buffers(&mut self, id: I, render_resources: &T) {
 | 
				
			||||||
                    ))
 | 
					        for (i, render_resource) in render_resources.iter().enumerate() {
 | 
				
			||||||
 | 
					            if let Some(RenderResourceType::Buffer) = render_resource.resource_type() {
 | 
				
			||||||
 | 
					                let size = render_resource.buffer_byte_len().unwrap();
 | 
				
			||||||
 | 
					                if let Some(buffer_array) = &mut self.buffer_arrays[i] {
 | 
				
			||||||
 | 
					                    buffer_array.get_or_assign_index(id);
 | 
				
			||||||
 | 
					                    self.required_staging_buffer_size += size;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn get_aligned_dynamic_uniform_size(data_size: usize) -> usize {
 | 
					    /// Resize BufferArray buffers if they aren't large enough
 | 
				
			||||||
        BIND_BUFFER_ALIGNMENT * ((data_size as f32 / BIND_BUFFER_ALIGNMENT as f32).ceil() as usize)
 | 
					    fn resize_buffer_arrays(&mut self, render_resource_context: &dyn RenderResourceContext) {
 | 
				
			||||||
    }
 | 
					        for buffer_array in self.buffer_arrays.iter_mut() {
 | 
				
			||||||
 | 
					            if let Some(buffer_array) = buffer_array {
 | 
				
			||||||
    fn setup_buffer_arrays(
 | 
					                buffer_array.resize(render_resource_context);
 | 
				
			||||||
        &mut self,
 | 
					 | 
				
			||||||
        render_resource_context: &dyn RenderResourceContext,
 | 
					 | 
				
			||||||
        dynamic_uniforms: bool,
 | 
					 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
        for buffer_array_status in self.uniform_arrays.iter_mut() {
 | 
					 | 
				
			||||||
            if let Some((_name, buffer_array_status)) = buffer_array_status {
 | 
					 | 
				
			||||||
                if dynamic_uniforms {
 | 
					 | 
				
			||||||
                    Self::setup_buffer_array(buffer_array_status, render_resource_context, true);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                buffer_array_status.queued_buffer_writes =
 | 
					 | 
				
			||||||
                    Vec::with_capacity(buffer_array_status.changed_item_count);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn setup_buffer_array(
 | 
					    /// Update the staging buffer to provide enough space to copy data to target buffers.
 | 
				
			||||||
        buffer_array_status: &mut BufferArrayStatus,
 | 
					    fn resize_staging_buffer(&mut self, render_resource_context: &dyn RenderResourceContext) {
 | 
				
			||||||
        render_resource_context: &dyn RenderResourceContext,
 | 
					        // TODO: allow staging buffer to scale down
 | 
				
			||||||
        align: bool,
 | 
					        if self.required_staging_buffer_size > self.staging_buffer_size {
 | 
				
			||||||
    ) {
 | 
					 | 
				
			||||||
        if buffer_array_status.current_item_capacity < buffer_array_status.changed_item_count {
 | 
					 | 
				
			||||||
            let new_capacity =
 | 
					 | 
				
			||||||
                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);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let total_size = item_size * new_capacity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let buffer = render_resource_context.create_buffer(BufferInfo {
 | 
					 | 
				
			||||||
                size: total_size,
 | 
					 | 
				
			||||||
                buffer_usage: BufferUsage::COPY_DST | BufferUsage::UNIFORM,
 | 
					 | 
				
			||||||
                ..Default::default()
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            buffer_array_status.current_item_capacity = new_capacity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            log::trace!(
 | 
					 | 
				
			||||||
                "creating buffer for uniform {}. size: {} item_capacity: {} item_size: {}",
 | 
					 | 
				
			||||||
                std::any::type_name::<T>(),
 | 
					 | 
				
			||||||
                total_size,
 | 
					 | 
				
			||||||
                new_capacity,
 | 
					 | 
				
			||||||
                item_size
 | 
					 | 
				
			||||||
            );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            buffer_array_status.buffer = Some(buffer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    fn update_staging_buffer(&mut self, render_resource_context: &dyn RenderResourceContext) {
 | 
					 | 
				
			||||||
        let mut size = 0;
 | 
					 | 
				
			||||||
        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.changed_size;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if self.staging_buffer_size != size {
 | 
					 | 
				
			||||||
            if let Some(staging_buffer) = self.staging_buffer {
 | 
					            if let Some(staging_buffer) = self.staging_buffer {
 | 
				
			||||||
                render_resource_context.remove_buffer(staging_buffer);
 | 
					                render_resource_context.remove_buffer(staging_buffer);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if size > 0 {
 | 
					            if self.required_staging_buffer_size > 0 {
 | 
				
			||||||
                let staging_buffer = render_resource_context.create_buffer(BufferInfo {
 | 
					                let staging_buffer = render_resource_context.create_buffer(BufferInfo {
 | 
				
			||||||
                    buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE,
 | 
					                    buffer_usage: BufferUsage::COPY_SRC | BufferUsage::MAP_WRITE,
 | 
				
			||||||
                    size,
 | 
					                    size: self.required_staging_buffer_size,
 | 
				
			||||||
                    ..Default::default()
 | 
					                    ..Default::default()
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
                self.staging_buffer = Some(staging_buffer);
 | 
					                self.staging_buffer = Some(staging_buffer);
 | 
				
			||||||
@ -214,40 +222,47 @@ where
 | 
				
			|||||||
                self.staging_buffer = None;
 | 
					                self.staging_buffer = None;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.staging_buffer_size = size;
 | 
					            self.staging_buffer_size = self.required_staging_buffer_size;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn setup_uniform_buffer_resources(
 | 
					    fn remove_bindings(&mut self, id: I) {
 | 
				
			||||||
 | 
					        for buffer_array in self.buffer_arrays.iter_mut() {
 | 
				
			||||||
 | 
					            if let Some(buffer_array) = buffer_array {
 | 
				
			||||||
 | 
					                buffer_array.remove_binding(id);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn write_uniform_buffers(
 | 
				
			||||||
        &mut self,
 | 
					        &mut self,
 | 
				
			||||||
 | 
					        id: I,
 | 
				
			||||||
        uniforms: &T,
 | 
					        uniforms: &T,
 | 
				
			||||||
        dynamic_uniforms: bool,
 | 
					        dynamic_uniforms: bool,
 | 
				
			||||||
        render_resource_context: &dyn RenderResourceContext,
 | 
					        render_resource_context: &dyn RenderResourceContext,
 | 
				
			||||||
        render_resource_bindings: &mut RenderResourceBindings,
 | 
					        render_resource_bindings: &mut RenderResourceBindings,
 | 
				
			||||||
        staging_buffer: &mut [u8],
 | 
					        staging_buffer: &mut [u8],
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
 | 
					        for (i, render_resource) in uniforms.iter().enumerate() {
 | 
				
			||||||
            match render_resource.resource_type() {
 | 
					            match render_resource.resource_type() {
 | 
				
			||||||
                Some(RenderResourceType::Buffer) => {
 | 
					                Some(RenderResourceType::Buffer) => {
 | 
				
			||||||
                    let size = render_resource.buffer_byte_len().unwrap();
 | 
					                    let size = render_resource.buffer_byte_len().unwrap();
 | 
				
			||||||
                    let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
 | 
					                    let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
 | 
				
			||||||
                    let (_name, uniform_buffer_status) = self.uniform_arrays[i].as_mut().unwrap();
 | 
					                    let buffer_array = self.buffer_arrays[i].as_mut().unwrap();
 | 
				
			||||||
                    let range = 0..size as u64;
 | 
					                    let range = 0..size as u64;
 | 
				
			||||||
                    let (target_buffer, target_offset) = if dynamic_uniforms {
 | 
					                    let (target_buffer, target_offset) = if dynamic_uniforms {
 | 
				
			||||||
                        let buffer = uniform_buffer_status.buffer.unwrap();
 | 
					                        let binding = buffer_array.get_binding(id).unwrap();
 | 
				
			||||||
                        let index =
 | 
					                        let dynamic_index = if let RenderResourceBinding::Buffer {
 | 
				
			||||||
                            uniform_buffer_status.get_or_assign_index(render_resource_bindings.id);
 | 
					                            dynamic_index: Some(dynamic_index),
 | 
				
			||||||
                        render_resource_bindings.set(
 | 
					                            ..
 | 
				
			||||||
                            render_resource_name,
 | 
					                        } = binding
 | 
				
			||||||
                            RenderResourceBinding::Buffer {
 | 
					                        {
 | 
				
			||||||
                                buffer,
 | 
					                            dynamic_index
 | 
				
			||||||
                                dynamic_index: Some(
 | 
					                        } else {
 | 
				
			||||||
                                    (index * uniform_buffer_status.aligned_size) as u32,
 | 
					                            panic!("dynamic index should always be set");
 | 
				
			||||||
                                ),
 | 
					                        };
 | 
				
			||||||
                                range,
 | 
					                        render_resource_bindings.set(render_resource_name, binding);
 | 
				
			||||||
                            },
 | 
					                        (buffer_array.buffer.unwrap(), dynamic_index)
 | 
				
			||||||
                        );
 | 
					 | 
				
			||||||
                        (buffer, index * uniform_buffer_status.aligned_size)
 | 
					 | 
				
			||||||
                    } else {
 | 
					                    } else {
 | 
				
			||||||
                        let mut matching_buffer = None;
 | 
					                        let mut matching_buffer = None;
 | 
				
			||||||
                        if let Some(binding) = render_resource_bindings.get(render_resource_name) {
 | 
					                        if let Some(binding) = render_resource_bindings.get(render_resource_name) {
 | 
				
			||||||
@ -296,22 +311,18 @@ where
 | 
				
			|||||||
                        (resource, 0)
 | 
					                        (resource, 0)
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    let staging_buffer_start = uniform_buffer_status.staging_buffer_offset
 | 
					 | 
				
			||||||
                        + uniform_buffer_status.current_offset;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    render_resource.write_buffer_bytes(
 | 
					                    render_resource.write_buffer_bytes(
 | 
				
			||||||
                        &mut staging_buffer[staging_buffer_start..(staging_buffer_start + size)],
 | 
					                        &mut staging_buffer[self.current_staging_buffer_offset
 | 
				
			||||||
 | 
					                            ..(self.current_staging_buffer_offset + size)],
 | 
				
			||||||
                    );
 | 
					                    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    uniform_buffer_status
 | 
					                    self.queued_buffer_writes.push(QueuedBufferWrite {
 | 
				
			||||||
                        .queued_buffer_writes
 | 
					                        buffer: target_buffer,
 | 
				
			||||||
                        .push(QueuedBufferWrite {
 | 
					                        target_offset: target_offset as usize,
 | 
				
			||||||
                            buffer: target_buffer,
 | 
					                        source_offset: self.current_staging_buffer_offset,
 | 
				
			||||||
                            target_offset,
 | 
					                        size,
 | 
				
			||||||
                            source_offset: uniform_buffer_status.current_offset,
 | 
					                    });
 | 
				
			||||||
                            size,
 | 
					                    self.current_staging_buffer_offset += size;
 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                    uniform_buffer_status.current_offset += size;
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                Some(RenderResourceType::Texture) => { /* ignore textures */ }
 | 
					                Some(RenderResourceType::Texture) => { /* ignore textures */ }
 | 
				
			||||||
                Some(RenderResourceType::Sampler) => { /* ignore samplers */ }
 | 
					                Some(RenderResourceType::Sampler) => { /* ignore samplers */ }
 | 
				
			||||||
@ -325,19 +336,14 @@ where
 | 
				
			|||||||
        command_queue: &mut CommandQueue,
 | 
					        command_queue: &mut CommandQueue,
 | 
				
			||||||
        staging_buffer: BufferId,
 | 
					        staging_buffer: BufferId,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        for uniform_buffer_status in self.uniform_arrays.iter_mut() {
 | 
					        for queued_buffer_write in self.queued_buffer_writes.drain(..) {
 | 
				
			||||||
            if let Some((_name, buffer_array_status)) = uniform_buffer_status {
 | 
					            command_queue.copy_buffer_to_buffer(
 | 
				
			||||||
                let start = buffer_array_status.staging_buffer_offset;
 | 
					                staging_buffer,
 | 
				
			||||||
                for queued_buffer_write in buffer_array_status.queued_buffer_writes.drain(..) {
 | 
					                queued_buffer_write.source_offset as u64,
 | 
				
			||||||
                    command_queue.copy_buffer_to_buffer(
 | 
					                queued_buffer_write.buffer,
 | 
				
			||||||
                        staging_buffer,
 | 
					                queued_buffer_write.target_offset as u64,
 | 
				
			||||||
                        (start + queued_buffer_write.source_offset) as u64,
 | 
					                queued_buffer_write.size as u64,
 | 
				
			||||||
                        queued_buffer_write.buffer,
 | 
					            )
 | 
				
			||||||
                        queued_buffer_write.target_offset as u64,
 | 
					 | 
				
			||||||
                        queued_buffer_write.size as u64,
 | 
					 | 
				
			||||||
                    )
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -391,7 +397,7 @@ where
 | 
				
			|||||||
            system.id(),
 | 
					            system.id(),
 | 
				
			||||||
            RenderResourcesNodeState {
 | 
					            RenderResourcesNodeState {
 | 
				
			||||||
                command_queue: self.command_queue.clone(),
 | 
					                command_queue: self.command_queue.clone(),
 | 
				
			||||||
                uniform_buffer_arrays: UniformBufferArrays::<T>::default(),
 | 
					                uniform_buffer_arrays: UniformBufferArrays::<Entity, T>::default(),
 | 
				
			||||||
                dynamic_uniforms: self.dynamic_uniforms,
 | 
					                dynamic_uniforms: self.dynamic_uniforms,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
@ -400,13 +406,13 @@ where
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RenderResourcesNodeState<T: RenderResources> {
 | 
					struct RenderResourcesNodeState<I, T: RenderResources> {
 | 
				
			||||||
    command_queue: CommandQueue,
 | 
					    command_queue: CommandQueue,
 | 
				
			||||||
    uniform_buffer_arrays: UniformBufferArrays<T>,
 | 
					    uniform_buffer_arrays: UniformBufferArrays<I, T>,
 | 
				
			||||||
    dynamic_uniforms: bool,
 | 
					    dynamic_uniforms: bool,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: RenderResources> Default for RenderResourcesNodeState<T> {
 | 
					impl<I, T: RenderResources> Default for RenderResourcesNodeState<I, T> {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            command_queue: Default::default(),
 | 
					            command_queue: Default::default(),
 | 
				
			||||||
@ -417,35 +423,29 @@ impl<T: RenderResources> Default for RenderResourcesNodeState<T> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn render_resources_node_system<T: RenderResources>(
 | 
					fn render_resources_node_system<T: RenderResources>(
 | 
				
			||||||
    mut state: Local<RenderResourcesNodeState<T>>,
 | 
					    mut state: Local<RenderResourcesNodeState<Entity, T>>,
 | 
				
			||||||
    render_resource_context: Res<Box<dyn RenderResourceContext>>,
 | 
					    render_resource_context: Res<Box<dyn RenderResourceContext>>,
 | 
				
			||||||
    mut query: Query<(&T, &Draw, &mut RenderPipelines)>,
 | 
					    mut query: Query<(Entity, &T, &Draw, &mut RenderPipelines)>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let state = state.deref_mut();
 | 
					    let state = state.deref_mut();
 | 
				
			||||||
 | 
					    let uniform_buffer_arrays = &mut state.uniform_buffer_arrays;
 | 
				
			||||||
    let render_resource_context = &**render_resource_context;
 | 
					    let render_resource_context = &**render_resource_context;
 | 
				
			||||||
    state.uniform_buffer_arrays.reset_changed_item_counts();
 | 
					    uniform_buffer_arrays.begin_update();
 | 
				
			||||||
    // update uniforms info
 | 
					    // initialize uniform buffer arrays using the first RenderResources
 | 
				
			||||||
    for (uniforms, draw, _render_pipelines) in &mut query.iter() {
 | 
					    if let Some((_, first, _, _)) = query.iter().iter().next() {
 | 
				
			||||||
        if !draw.is_visible {
 | 
					        uniform_buffer_arrays.initialize(first);
 | 
				
			||||||
            continue;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        state
 | 
					 | 
				
			||||||
            .uniform_buffer_arrays
 | 
					 | 
				
			||||||
            .increment_changed_item_counts(&uniforms);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    state
 | 
					 | 
				
			||||||
        .uniform_buffer_arrays
 | 
					 | 
				
			||||||
        .setup_buffer_arrays(render_resource_context, state.dynamic_uniforms);
 | 
					 | 
				
			||||||
    state
 | 
					 | 
				
			||||||
        .uniform_buffer_arrays
 | 
					 | 
				
			||||||
        .update_staging_buffer(render_resource_context);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
					    for entity in query.removed::<T>() {
 | 
				
			||||||
 | 
					        uniform_buffer_arrays.remove_bindings(*entity);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (entity, uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
				
			||||||
        if !draw.is_visible {
 | 
					        if !draw.is_visible {
 | 
				
			||||||
            continue;
 | 
					            continue;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        uniform_buffer_arrays.prepare_uniform_buffers(entity, uniforms);
 | 
				
			||||||
        setup_uniform_texture_resources::<T>(
 | 
					        setup_uniform_texture_resources::<T>(
 | 
				
			||||||
            &uniforms,
 | 
					            &uniforms,
 | 
				
			||||||
            render_resource_context,
 | 
					            render_resource_context,
 | 
				
			||||||
@ -453,18 +453,22 @@ fn render_resources_node_system<T: RenderResources>(
 | 
				
			|||||||
        )
 | 
					        )
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uniform_buffer_arrays.resize_buffer_arrays(render_resource_context);
 | 
				
			||||||
 | 
					    uniform_buffer_arrays.resize_staging_buffer(render_resource_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer {
 | 
					    if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer {
 | 
				
			||||||
        render_resource_context.map_buffer(staging_buffer);
 | 
					        render_resource_context.map_buffer(staging_buffer);
 | 
				
			||||||
        render_resource_context.write_mapped_buffer(
 | 
					        render_resource_context.write_mapped_buffer(
 | 
				
			||||||
            staging_buffer,
 | 
					            staging_buffer,
 | 
				
			||||||
            0..state.uniform_buffer_arrays.staging_buffer_size as u64,
 | 
					            0..state.uniform_buffer_arrays.staging_buffer_size as u64,
 | 
				
			||||||
            &mut |mut staging_buffer, _render_resource_context| {
 | 
					            &mut |mut staging_buffer, _render_resource_context| {
 | 
				
			||||||
                for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
					                for (entity, uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
				
			||||||
                    if !draw.is_visible {
 | 
					                    if !draw.is_visible {
 | 
				
			||||||
                        continue;
 | 
					                        continue;
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    state.uniform_buffer_arrays.setup_uniform_buffer_resources(
 | 
					                    state.uniform_buffer_arrays.write_uniform_buffers(
 | 
				
			||||||
 | 
					                        entity,
 | 
				
			||||||
                        &uniforms,
 | 
					                        &uniforms,
 | 
				
			||||||
                        state.dynamic_uniforms,
 | 
					                        state.dynamic_uniforms,
 | 
				
			||||||
                        render_resource_context,
 | 
					                        render_resource_context,
 | 
				
			||||||
@ -482,12 +486,13 @@ fn render_resources_node_system<T: RenderResources>(
 | 
				
			|||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        // TODO: can we just remove this?
 | 
					        // TODO: can we just remove this?
 | 
				
			||||||
        let mut staging_buffer: [u8; 0] = [];
 | 
					        let mut staging_buffer: [u8; 0] = [];
 | 
				
			||||||
        for (uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
					        for (entity, uniforms, draw, mut render_pipelines) in &mut query.iter() {
 | 
				
			||||||
            if !draw.is_visible {
 | 
					            if !draw.is_visible {
 | 
				
			||||||
                continue;
 | 
					                continue;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            state.uniform_buffer_arrays.setup_uniform_buffer_resources(
 | 
					            state.uniform_buffer_arrays.write_uniform_buffers(
 | 
				
			||||||
 | 
					                entity,
 | 
				
			||||||
                &uniforms,
 | 
					                &uniforms,
 | 
				
			||||||
                state.dynamic_uniforms,
 | 
					                state.dynamic_uniforms,
 | 
				
			||||||
                render_resource_context,
 | 
					                render_resource_context,
 | 
				
			||||||
@ -549,7 +554,7 @@ where
 | 
				
			|||||||
            system.id(),
 | 
					            system.id(),
 | 
				
			||||||
            RenderResourcesNodeState {
 | 
					            RenderResourcesNodeState {
 | 
				
			||||||
                command_queue: self.command_queue.clone(),
 | 
					                command_queue: self.command_queue.clone(),
 | 
				
			||||||
                uniform_buffer_arrays: UniformBufferArrays::<T>::default(),
 | 
					                uniform_buffer_arrays: UniformBufferArrays::<Handle<T>, T>::default(),
 | 
				
			||||||
                dynamic_uniforms: self.dynamic_uniforms,
 | 
					                dynamic_uniforms: self.dynamic_uniforms,
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
@ -559,64 +564,38 @@ where
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn asset_render_resources_node_system<T: RenderResources>(
 | 
					fn asset_render_resources_node_system<T: RenderResources>(
 | 
				
			||||||
    mut state: Local<RenderResourcesNodeState<T>>,
 | 
					    mut state: Local<RenderResourcesNodeState<Handle<T>, T>>,
 | 
				
			||||||
    assets: Res<Assets<T>>,
 | 
					    assets: Res<Assets<T>>,
 | 
				
			||||||
    //    asset_events: Res<Events<AssetEvent<T>>>,
 | 
					 | 
				
			||||||
    mut asset_render_resource_bindings: ResMut<AssetRenderResourceBindings>,
 | 
					    mut asset_render_resource_bindings: ResMut<AssetRenderResourceBindings>,
 | 
				
			||||||
    render_resource_context: Res<Box<dyn RenderResourceContext>>,
 | 
					    render_resource_context: Res<Box<dyn RenderResourceContext>>,
 | 
				
			||||||
    mut query: Query<(&Handle<T>, &Draw, &mut RenderPipelines)>,
 | 
					    mut query: Query<(&Handle<T>, &Draw, &mut RenderPipelines)>,
 | 
				
			||||||
) {
 | 
					) {
 | 
				
			||||||
    let state = state.deref_mut();
 | 
					    let state = state.deref_mut();
 | 
				
			||||||
 | 
					    let uniform_buffer_arrays = &mut state.uniform_buffer_arrays;
 | 
				
			||||||
    let render_resource_context = &**render_resource_context;
 | 
					    let render_resource_context = &**render_resource_context;
 | 
				
			||||||
    state.uniform_buffer_arrays.reset_changed_item_counts();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let modified_assets = assets
 | 
					    let modified_assets = assets
 | 
				
			||||||
        .iter()
 | 
					        .iter()
 | 
				
			||||||
        .map(|(handle, _)| handle)
 | 
					        .map(|(handle, _)| handle)
 | 
				
			||||||
        .collect::<Vec<Handle<T>>>();
 | 
					        .collect::<Vec<Handle<T>>>();
 | 
				
			||||||
    // TODO: uncomment this when asset dependency events are added https://github.com/bevyengine/bevy/issues/26
 | 
					 | 
				
			||||||
    // 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
 | 
					    uniform_buffer_arrays.begin_update();
 | 
				
			||||||
    for asset_handle in modified_assets.iter() {
 | 
					    // initialize uniform buffer arrays using the first RenderResources
 | 
				
			||||||
        let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
 | 
					    if let Some(first_handle) = modified_assets.get(0) {
 | 
				
			||||||
        state
 | 
					        let asset = assets.get(first_handle).expect(EXPECT_ASSET_MESSAGE);
 | 
				
			||||||
            .uniform_buffer_arrays
 | 
					        uniform_buffer_arrays.initialize(asset);
 | 
				
			||||||
            .increment_changed_item_counts(&asset);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state
 | 
					 | 
				
			||||||
        .uniform_buffer_arrays
 | 
					 | 
				
			||||||
        .setup_buffer_arrays(render_resource_context, state.dynamic_uniforms);
 | 
					 | 
				
			||||||
    state
 | 
					 | 
				
			||||||
        .uniform_buffer_arrays
 | 
					 | 
				
			||||||
        .update_staging_buffer(render_resource_context);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    for asset_handle in modified_assets.iter() {
 | 
					    for asset_handle in modified_assets.iter() {
 | 
				
			||||||
        let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
 | 
					        let asset = assets.get(&asset_handle).expect(EXPECT_ASSET_MESSAGE);
 | 
				
			||||||
        let mut render_resource_bindings =
 | 
					        uniform_buffer_arrays.prepare_uniform_buffers(*asset_handle, asset);
 | 
				
			||||||
            asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
					        let mut bindings = asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
				
			||||||
        setup_uniform_texture_resources::<T>(
 | 
					        setup_uniform_texture_resources::<T>(&asset, render_resource_context, &mut bindings);
 | 
				
			||||||
            &asset,
 | 
					 | 
				
			||||||
            render_resource_context,
 | 
					 | 
				
			||||||
            &mut render_resource_bindings,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uniform_buffer_arrays.resize_buffer_arrays(render_resource_context);
 | 
				
			||||||
 | 
					    uniform_buffer_arrays.resize_staging_buffer(render_resource_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer {
 | 
					    if let Some(staging_buffer) = state.uniform_buffer_arrays.staging_buffer {
 | 
				
			||||||
        render_resource_context.map_buffer(staging_buffer);
 | 
					        render_resource_context.map_buffer(staging_buffer);
 | 
				
			||||||
        render_resource_context.write_mapped_buffer(
 | 
					        render_resource_context.write_mapped_buffer(
 | 
				
			||||||
@ -628,7 +607,8 @@ fn asset_render_resources_node_system<T: RenderResources>(
 | 
				
			|||||||
                    let mut render_resource_bindings =
 | 
					                    let mut render_resource_bindings =
 | 
				
			||||||
                        asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
					                        asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
				
			||||||
                    // TODO: only setup buffer if we haven't seen this handle before
 | 
					                    // TODO: only setup buffer if we haven't seen this handle before
 | 
				
			||||||
                    state.uniform_buffer_arrays.setup_uniform_buffer_resources(
 | 
					                    state.uniform_buffer_arrays.write_uniform_buffers(
 | 
				
			||||||
 | 
					                        *asset_handle,
 | 
				
			||||||
                        &asset,
 | 
					                        &asset,
 | 
				
			||||||
                        state.dynamic_uniforms,
 | 
					                        state.dynamic_uniforms,
 | 
				
			||||||
                        render_resource_context,
 | 
					                        render_resource_context,
 | 
				
			||||||
@ -650,7 +630,8 @@ fn asset_render_resources_node_system<T: RenderResources>(
 | 
				
			|||||||
            let mut render_resource_bindings =
 | 
					            let mut render_resource_bindings =
 | 
				
			||||||
                asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
					                asset_render_resource_bindings.get_or_insert_mut(*asset_handle);
 | 
				
			||||||
            // TODO: only setup buffer if we haven't seen this handle before
 | 
					            // TODO: only setup buffer if we haven't seen this handle before
 | 
				
			||||||
            state.uniform_buffer_arrays.setup_uniform_buffer_resources(
 | 
					            state.uniform_buffer_arrays.write_uniform_buffers(
 | 
				
			||||||
 | 
					                *asset_handle,
 | 
				
			||||||
                &asset,
 | 
					                &asset,
 | 
				
			||||||
                state.dynamic_uniforms,
 | 
					                state.dynamic_uniforms,
 | 
				
			||||||
                render_resource_context,
 | 
					                render_resource_context,
 | 
				
			||||||
@ -677,7 +658,7 @@ fn setup_uniform_texture_resources<T>(
 | 
				
			|||||||
) where
 | 
					) where
 | 
				
			||||||
    T: renderer::RenderResources,
 | 
					    T: renderer::RenderResources,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    for (i, render_resource) in uniforms.iter_render_resources().enumerate() {
 | 
					    for (i, render_resource) in uniforms.iter().enumerate() {
 | 
				
			||||||
        if let Some(RenderResourceType::Texture) = render_resource.resource_type() {
 | 
					        if let Some(RenderResourceType::Texture) = render_resource.resource_type() {
 | 
				
			||||||
            let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
 | 
					            let render_resource_name = uniforms.get_render_resource_name(i).unwrap();
 | 
				
			||||||
            let sampler_name = format!("{}_sampler", render_resource_name);
 | 
					            let sampler_name = format!("{}_sampler", render_resource_name);
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ pub trait RenderResources: Send + Sync + 'static {
 | 
				
			|||||||
    fn get_render_resource_hints(&self, _index: usize) -> Option<RenderResourceHints> {
 | 
					    fn get_render_resource_hints(&self, _index: usize) -> Option<RenderResourceHints> {
 | 
				
			||||||
        None
 | 
					        None
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    fn iter_render_resources(&self) -> RenderResourceIterator;
 | 
					    fn iter(&self) -> RenderResourceIterator;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct RenderResourceIterator<'a> {
 | 
					pub struct RenderResourceIterator<'a> {
 | 
				
			||||||
@ -200,7 +200,7 @@ impl RenderResources for bevy_transform::prelude::Transform {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn iter_render_resources(&self) -> RenderResourceIterator {
 | 
					    fn iter(&self) -> RenderResourceIterator {
 | 
				
			||||||
        RenderResourceIterator::new(self)
 | 
					        RenderResourceIterator::new(self)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user