Added buffer usage field to buffers (#7423)
# Objective Buffers in bevy do not allow for setting buffer usage flags which can be useful for setting COPY_SRC, MAP_READ, MAP_WRITE, which allows for buffers to be copied from gpu to cpu for inspection. ## Solution Add buffer_usage field to buffers and a set_usage function to set them
This commit is contained in:
		
							parent
							
								
									357a16035d
								
							
						
					
					
						commit
						952735f5ae
					
				@ -33,7 +33,8 @@ pub struct StorageBuffer<T: ShaderType> {
 | 
			
		||||
    buffer: Option<Buffer>,
 | 
			
		||||
    capacity: usize,
 | 
			
		||||
    label: Option<String>,
 | 
			
		||||
    label_changed: bool,
 | 
			
		||||
    changed: bool,
 | 
			
		||||
    buffer_usage: BufferUsages,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: ShaderType> From<T> for StorageBuffer<T> {
 | 
			
		||||
@ -44,7 +45,8 @@ impl<T: ShaderType> From<T> for StorageBuffer<T> {
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            capacity: 0,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -57,7 +59,8 @@ impl<T: ShaderType + Default> Default for StorageBuffer<T> {
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            capacity: 0,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -91,7 +94,7 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
 | 
			
		||||
        let label = label.map(str::to_string);
 | 
			
		||||
 | 
			
		||||
        if label != self.label {
 | 
			
		||||
            self.label_changed = true;
 | 
			
		||||
            self.changed = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.label = label;
 | 
			
		||||
@ -101,6 +104,16 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
 | 
			
		||||
        self.label.as_deref()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Add more [`BufferUsages`] to the buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This method only allows addition of flags to the default usage flags.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::STORAGE`.
 | 
			
		||||
    pub fn add_usages(&mut self, usage: BufferUsages) {
 | 
			
		||||
        self.buffer_usage |= usage;
 | 
			
		||||
        self.changed = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
 | 
			
		||||
    /// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
 | 
			
		||||
    ///
 | 
			
		||||
@ -111,14 +124,14 @@ impl<T: ShaderType + WriteInto> StorageBuffer<T> {
 | 
			
		||||
 | 
			
		||||
        let size = self.scratch.as_ref().len();
 | 
			
		||||
 | 
			
		||||
        if self.capacity < size || self.label_changed {
 | 
			
		||||
        if self.capacity < size || self.changed {
 | 
			
		||||
            self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
 | 
			
		||||
                label: self.label.as_deref(),
 | 
			
		||||
                usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
 | 
			
		||||
                usage: self.buffer_usage,
 | 
			
		||||
                contents: self.scratch.as_ref(),
 | 
			
		||||
            }));
 | 
			
		||||
            self.capacity = size;
 | 
			
		||||
            self.label_changed = false;
 | 
			
		||||
            self.changed = false;
 | 
			
		||||
        } else if let Some(buffer) = &self.buffer {
 | 
			
		||||
            queue.write_buffer(buffer, 0, self.scratch.as_ref());
 | 
			
		||||
        }
 | 
			
		||||
@ -152,7 +165,8 @@ pub struct DynamicStorageBuffer<T: ShaderType> {
 | 
			
		||||
    buffer: Option<Buffer>,
 | 
			
		||||
    capacity: usize,
 | 
			
		||||
    label: Option<String>,
 | 
			
		||||
    label_changed: bool,
 | 
			
		||||
    changed: bool,
 | 
			
		||||
    buffer_usage: BufferUsages,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
 | 
			
		||||
@ -163,7 +177,8 @@ impl<T: ShaderType> Default for DynamicStorageBuffer<T> {
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            capacity: 0,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -204,7 +219,7 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
 | 
			
		||||
        let label = label.map(str::to_string);
 | 
			
		||||
 | 
			
		||||
        if label != self.label {
 | 
			
		||||
            self.label_changed = true;
 | 
			
		||||
            self.changed = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.label = label;
 | 
			
		||||
@ -214,18 +229,28 @@ impl<T: ShaderType + WriteInto> DynamicStorageBuffer<T> {
 | 
			
		||||
        self.label.as_deref()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Add more [`BufferUsages`] to the buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This method only allows addition of flags to the default usage flags.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::STORAGE`.
 | 
			
		||||
    pub fn add_usages(&mut self, usage: BufferUsages) {
 | 
			
		||||
        self.buffer_usage |= usage;
 | 
			
		||||
        self.changed = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[inline]
 | 
			
		||||
    pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
 | 
			
		||||
        let size = self.scratch.as_ref().len();
 | 
			
		||||
 | 
			
		||||
        if self.capacity < size || self.label_changed {
 | 
			
		||||
        if self.capacity < size || self.changed {
 | 
			
		||||
            self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
 | 
			
		||||
                label: self.label.as_deref(),
 | 
			
		||||
                usage: BufferUsages::COPY_DST | BufferUsages::STORAGE,
 | 
			
		||||
                usage: self.buffer_usage,
 | 
			
		||||
                contents: self.scratch.as_ref(),
 | 
			
		||||
            }));
 | 
			
		||||
            self.capacity = size;
 | 
			
		||||
            self.label_changed = false;
 | 
			
		||||
            self.changed = false;
 | 
			
		||||
        } else if let Some(buffer) = &self.buffer {
 | 
			
		||||
            queue.write_buffer(buffer, 0, self.scratch.as_ref());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,8 @@ pub struct UniformBuffer<T: ShaderType> {
 | 
			
		||||
    scratch: UniformBufferWrapper<Vec<u8>>,
 | 
			
		||||
    buffer: Option<Buffer>,
 | 
			
		||||
    label: Option<String>,
 | 
			
		||||
    label_changed: bool,
 | 
			
		||||
    changed: bool,
 | 
			
		||||
    buffer_usage: BufferUsages,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: ShaderType> From<T> for UniformBuffer<T> {
 | 
			
		||||
@ -42,7 +43,8 @@ impl<T: ShaderType> From<T> for UniformBuffer<T> {
 | 
			
		||||
            scratch: UniformBufferWrapper::new(Vec::new()),
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -54,7 +56,8 @@ impl<T: ShaderType + Default> Default for UniformBuffer<T> {
 | 
			
		||||
            scratch: UniformBufferWrapper::new(Vec::new()),
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -89,7 +92,7 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
 | 
			
		||||
        let label = label.map(str::to_string);
 | 
			
		||||
 | 
			
		||||
        if label != self.label {
 | 
			
		||||
            self.label_changed = true;
 | 
			
		||||
            self.changed = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.label = label;
 | 
			
		||||
@ -99,6 +102,16 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
 | 
			
		||||
        self.label.as_deref()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Add more [`BufferUsages`] to the buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This method only allows addition of flags to the default usage flags.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::UNIFORM`.
 | 
			
		||||
    pub fn add_usages(&mut self, usage: BufferUsages) {
 | 
			
		||||
        self.buffer_usage |= usage;
 | 
			
		||||
        self.changed = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
 | 
			
		||||
    /// and the provided [`RenderQueue`](crate::renderer::RenderQueue), if a GPU-side backing buffer already exists.
 | 
			
		||||
    ///
 | 
			
		||||
@ -107,13 +120,13 @@ impl<T: ShaderType + WriteInto> UniformBuffer<T> {
 | 
			
		||||
    pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
 | 
			
		||||
        self.scratch.write(&self.value).unwrap();
 | 
			
		||||
 | 
			
		||||
        if self.label_changed || self.buffer.is_none() {
 | 
			
		||||
        if self.changed || self.buffer.is_none() {
 | 
			
		||||
            self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
 | 
			
		||||
                label: self.label.as_deref(),
 | 
			
		||||
                usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
 | 
			
		||||
                usage: self.buffer_usage,
 | 
			
		||||
                contents: self.scratch.as_ref(),
 | 
			
		||||
            }));
 | 
			
		||||
            self.label_changed = false;
 | 
			
		||||
            self.changed = false;
 | 
			
		||||
        } else if let Some(buffer) = &self.buffer {
 | 
			
		||||
            queue.write_buffer(buffer, 0, self.scratch.as_ref());
 | 
			
		||||
        }
 | 
			
		||||
@ -145,7 +158,8 @@ pub struct DynamicUniformBuffer<T: ShaderType> {
 | 
			
		||||
    buffer: Option<Buffer>,
 | 
			
		||||
    capacity: usize,
 | 
			
		||||
    label: Option<String>,
 | 
			
		||||
    label_changed: bool,
 | 
			
		||||
    changed: bool,
 | 
			
		||||
    buffer_usage: BufferUsages,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
 | 
			
		||||
@ -156,7 +170,8 @@ impl<T: ShaderType> Default for DynamicUniformBuffer<T> {
 | 
			
		||||
            buffer: None,
 | 
			
		||||
            capacity: 0,
 | 
			
		||||
            label: None,
 | 
			
		||||
            label_changed: false,
 | 
			
		||||
            changed: false,
 | 
			
		||||
            buffer_usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -198,7 +213,7 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
 | 
			
		||||
        let label = label.map(str::to_string);
 | 
			
		||||
 | 
			
		||||
        if label != self.label {
 | 
			
		||||
            self.label_changed = true;
 | 
			
		||||
            self.changed = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.label = label;
 | 
			
		||||
@ -208,6 +223,16 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
 | 
			
		||||
        self.label.as_deref()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Add more [`BufferUsages`] to the buffer.
 | 
			
		||||
    ///
 | 
			
		||||
    /// This method only allows addition of flags to the default usage flags.
 | 
			
		||||
    ///
 | 
			
		||||
    /// The default values for buffer usage are `BufferUsages::COPY_DST` and `BufferUsages::UNIFORM`.
 | 
			
		||||
    pub fn add_usages(&mut self, usage: BufferUsages) {
 | 
			
		||||
        self.buffer_usage |= usage;
 | 
			
		||||
        self.changed = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /// Queues writing of data from system RAM to VRAM using the [`RenderDevice`](crate::renderer::RenderDevice)
 | 
			
		||||
    /// and the provided [`RenderQueue`](crate::renderer::RenderQueue).
 | 
			
		||||
    ///
 | 
			
		||||
@ -217,14 +242,14 @@ impl<T: ShaderType + WriteInto> DynamicUniformBuffer<T> {
 | 
			
		||||
    pub fn write_buffer(&mut self, device: &RenderDevice, queue: &RenderQueue) {
 | 
			
		||||
        let size = self.scratch.as_ref().len();
 | 
			
		||||
 | 
			
		||||
        if self.capacity < size || self.label_changed {
 | 
			
		||||
        if self.capacity < size || self.changed {
 | 
			
		||||
            self.buffer = Some(device.create_buffer_with_data(&BufferInitDescriptor {
 | 
			
		||||
                label: self.label.as_deref(),
 | 
			
		||||
                usage: BufferUsages::COPY_DST | BufferUsages::UNIFORM,
 | 
			
		||||
                usage: self.buffer_usage,
 | 
			
		||||
                contents: self.scratch.as_ref(),
 | 
			
		||||
            }));
 | 
			
		||||
            self.capacity = size;
 | 
			
		||||
            self.label_changed = false;
 | 
			
		||||
            self.changed = false;
 | 
			
		||||
        } else if let Some(buffer) = &self.buffer {
 | 
			
		||||
            queue.write_buffer(buffer, 0, self.scratch.as_ref());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user