Rework buffer update command

This commit is contained in:
Pierre Krieger 2017-03-11 14:53:41 +01:00
parent 99305e8643
commit d6cb5aa282
9 changed files with 43 additions and 25 deletions

View File

@ -153,4 +153,4 @@ pass_through!((B), cmd::CmdFillBuffer<B>);
pass_through!((), cmd::CmdNextSubpass);
pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((), cmd::CmdSetState);
//pass_through!((B), cmd::CmdUpdateBuffer<B>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -47,6 +47,16 @@ pub unsafe trait CommandBufferBuilder: DeviceOwned {
Ok(self.add(cmd))
}
/// Adds a command that writes data to a buffer.
#[inline]
fn update_buffer<B, D, O>(self, buffer: B, data: D) -> Result<O, cmd::CmdUpdateBufferError>
where Self: Sized + AddCommand<cmd::CmdUpdateBuffer<B, D>, Out = O>,
B: Buffer
{
let cmd = cmd::CmdUpdateBuffer::new(buffer, data)?;
Ok(self.add(cmd))
}
/// Adds a command that copies the content of a buffer to an image.
///
/// For color images (ie. all formats except depth and/or stencil formats) this command does

View File

@ -141,4 +141,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((S, D), cmd::CmdResolveImage<S, D>);
pass_through!((), cmd::CmdSetEvent);
pass_through!((), cmd::CmdSetState);
pass_through!((B, D), cmd::CmdUpdateBuffer<'static, B, D>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -106,4 +106,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((S, D), cmd::CmdResolveImage<S, D>);
pass_through!((), cmd::CmdSetEvent);
pass_through!((), cmd::CmdSetState);
pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -121,4 +121,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((S, D), cmd::CmdResolveImage<S, D>);
pass_through!((), cmd::CmdSetEvent);
pass_through!((), cmd::CmdSetState);
pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -106,4 +106,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((S, D), cmd::CmdResolveImage<S, D>);
pass_through!((), cmd::CmdSetEvent);
pass_through!((), cmd::CmdSetState);
pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -218,4 +218,4 @@ pass_through!((), cmd::CmdNextSubpass);
pass_through!((Pc, Pl), cmd::CmdPushConstants<Pc, Pl>);
pass_through!((S, D), cmd::CmdResolveImage<S, D>);
pass_through!((), cmd::CmdSetEvent);
pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>);
pass_through!((B, D), cmd::CmdUpdateBuffer<B, D>);

View File

@ -404,14 +404,14 @@ unsafe impl<I, O> AddCommand<cmd::CmdSetState> for SubmitSyncBuilderLayer<I>
}
}
unsafe impl<'a, I, O, B, D> AddCommand<cmd::CmdUpdateBuffer<'a, B, D>> for SubmitSyncBuilderLayer<I>
where I: AddCommand<cmd::CmdUpdateBuffer<'a, B, D>, Out = O>,
unsafe impl<I, O, B, D> AddCommand<cmd::CmdUpdateBuffer<B, D>> for SubmitSyncBuilderLayer<I>
where I: AddCommand<cmd::CmdUpdateBuffer<B, D>, Out = O>,
B: Buffer + Clone + 'static
{
type Out = SubmitSyncBuilderLayer<O>;
#[inline]
fn add(mut self, command: cmd::CmdUpdateBuffer<'a, B, D>) -> Self::Out {
fn add(mut self, command: cmd::CmdUpdateBuffer<B, D>) -> Self::Out {
self.add_buffer(command.buffer(), true);
SubmitSyncBuilderLayer {

View File

@ -10,6 +10,8 @@
use std::error;
use std::fmt;
use std::sync::Arc;
use std::os::raw::c_void;
use std::ptr;
use buffer::Buffer;
use buffer::BufferInner;
@ -23,9 +25,7 @@ use VulkanPointers;
use vk;
/// Command that sets the content of a buffer to some data.
pub struct CmdUpdateBuffer<'a, B, D: ?Sized>
where D: 'a
{
pub struct CmdUpdateBuffer<B, D> {
// The buffer to update.
buffer: B,
// Raw buffer handle.
@ -34,13 +34,15 @@ pub struct CmdUpdateBuffer<'a, B, D: ?Sized>
offset: vk::DeviceSize,
// Size of the update.
size: vk::DeviceSize,
// The data to write to the buffer.
data: &'a D,
// If null, contains a pointer to the raw data to write. If `None`, the data is the `data`
// field.
data_ptr: *const c_void,
// The data to write to the buffer or a reference to it.
data: D,
}
impl<'a, B, D: ?Sized> CmdUpdateBuffer<'a, B, D>
where B: Buffer,
D: Copy + 'static,
impl<B, D> CmdUpdateBuffer<B, D>
where B: Buffer
{
/// Builds a command that writes data to a buffer.
///
@ -49,7 +51,8 @@ impl<'a, B, D: ?Sized> CmdUpdateBuffer<'a, B, D>
///
/// The size of the modification must not exceed 65536 bytes. The offset and size must be
/// multiples of four.
pub fn new(buffer: B, data: &'a D) -> Result<CmdUpdateBuffer<'a, B, D>, CmdUpdateBufferError> {
// TODO: type safety
pub fn new(buffer: B, data: D) -> Result<CmdUpdateBuffer<B, D>, CmdUpdateBufferError> {
let size = buffer.size();
let (buffer_handle, offset) = {
@ -76,12 +79,13 @@ impl<'a, B, D: ?Sized> CmdUpdateBuffer<'a, B, D>
buffer_handle: buffer_handle,
offset: offset as vk::DeviceSize,
size: size as vk::DeviceSize,
data_ptr: ptr::null(),
data: data,
})
}
}
impl<'a, B, D> CmdUpdateBuffer<'a, B, D> {
impl<B, D> CmdUpdateBuffer<B, D> {
/// Returns the buffer that is going to be written.
#[inline]
pub fn buffer(&self) -> &B {
@ -89,7 +93,7 @@ impl<'a, B, D> CmdUpdateBuffer<'a, B, D> {
}
}
unsafe impl<'a, B, D> DeviceOwned for CmdUpdateBuffer<'a, B, D>
unsafe impl<B, D> DeviceOwned for CmdUpdateBuffer<B, D>
where B: DeviceOwned
{
#[inline]
@ -98,20 +102,24 @@ unsafe impl<'a, B, D> DeviceOwned for CmdUpdateBuffer<'a, B, D>
}
}
unsafe impl<'a, 'd, P, B, D: ?Sized> AddCommand<&'a CmdUpdateBuffer<'d, B, D>> for UnsafeCommandBufferBuilder<P>
unsafe impl<'a, P, B, D> AddCommand<&'a CmdUpdateBuffer<B, D>> for UnsafeCommandBufferBuilder<P>
where B: Buffer,
D: Copy + 'static,
P: CommandPool,
{
type Out = UnsafeCommandBufferBuilder<P>;
#[inline]
fn add(self, command: &'a CmdUpdateBuffer<'d, B, D>) -> Self::Out {
fn add(self, command: &'a CmdUpdateBuffer<B, D>) -> Self::Out {
unsafe {
let data = if command.data_ptr.is_null() {
&command.data as *const D as *const _
} else {
command.data_ptr as *const _
};
let vk = self.device().pointers();
let cmd = self.internal_object();
vk.CmdUpdateBuffer(cmd, command.buffer_handle, command.offset, command.size,
command.data as *const D as *const _);
vk.CmdUpdateBuffer(cmd, command.buffer_handle, command.offset, command.size, data);
}
self