diff --git a/vulkano/src/command_buffer/auto.rs b/vulkano/src/command_buffer/auto.rs index cc20e5a11..67337a4ba 100644 --- a/vulkano/src/command_buffer/auto.rs +++ b/vulkano/src/command_buffer/auto.rs @@ -153,4 +153,4 @@ pass_through!((B), cmd::CmdFillBuffer); pass_through!((), cmd::CmdNextSubpass); pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((), cmd::CmdSetState); -//pass_through!((B), cmd::CmdUpdateBuffer); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/builder.rs b/vulkano/src/command_buffer/builder.rs index ba4fcb14d..fd69fc320 100644 --- a/vulkano/src/command_buffer/builder.rs +++ b/vulkano/src/command_buffer/builder.rs @@ -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(self, buffer: B, data: D) -> Result + where Self: Sized + AddCommand, 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 diff --git a/vulkano/src/command_buffer/cb/abstract_storage.rs b/vulkano/src/command_buffer/cb/abstract_storage.rs index b400843cc..35d7867b5 100644 --- a/vulkano/src/command_buffer/cb/abstract_storage.rs +++ b/vulkano/src/command_buffer/cb/abstract_storage.rs @@ -141,4 +141,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((S, D), cmd::CmdResolveImage); pass_through!((), cmd::CmdSetEvent); pass_through!((), cmd::CmdSetState); -pass_through!((B, D), cmd::CmdUpdateBuffer<'static, B, D>); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/cb/context_check.rs b/vulkano/src/command_buffer/cb/context_check.rs index 5e9faa869..65639c52a 100644 --- a/vulkano/src/command_buffer/cb/context_check.rs +++ b/vulkano/src/command_buffer/cb/context_check.rs @@ -106,4 +106,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((S, D), cmd::CmdResolveImage); pass_through!((), cmd::CmdSetEvent); pass_through!((), cmd::CmdSetState); -pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/cb/device_check.rs b/vulkano/src/command_buffer/cb/device_check.rs index 0613f4775..cfda1f711 100644 --- a/vulkano/src/command_buffer/cb/device_check.rs +++ b/vulkano/src/command_buffer/cb/device_check.rs @@ -121,4 +121,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((S, D), cmd::CmdResolveImage); pass_through!((), cmd::CmdSetEvent); pass_through!((), cmd::CmdSetState); -pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/cb/queue_ty_check.rs b/vulkano/src/command_buffer/cb/queue_ty_check.rs index 45c248cc8..0d3401792 100644 --- a/vulkano/src/command_buffer/cb/queue_ty_check.rs +++ b/vulkano/src/command_buffer/cb/queue_ty_check.rs @@ -106,4 +106,4 @@ pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((S, D), cmd::CmdResolveImage); pass_through!((), cmd::CmdSetEvent); pass_through!((), cmd::CmdSetState); -pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/cb/state_cache.rs b/vulkano/src/command_buffer/cb/state_cache.rs index 0feac986a..ee4c9144c 100644 --- a/vulkano/src/command_buffer/cb/state_cache.rs +++ b/vulkano/src/command_buffer/cb/state_cache.rs @@ -218,4 +218,4 @@ pass_through!((), cmd::CmdNextSubpass); pass_through!((Pc, Pl), cmd::CmdPushConstants); pass_through!((S, D), cmd::CmdResolveImage); pass_through!((), cmd::CmdSetEvent); -pass_through!((B, D), cmd::CmdUpdateBuffer<'a, B, D>); +pass_through!((B, D), cmd::CmdUpdateBuffer); diff --git a/vulkano/src/command_buffer/cb/submit_sync.rs b/vulkano/src/command_buffer/cb/submit_sync.rs index 231ef5b9d..c4102b175 100644 --- a/vulkano/src/command_buffer/cb/submit_sync.rs +++ b/vulkano/src/command_buffer/cb/submit_sync.rs @@ -404,14 +404,14 @@ unsafe impl AddCommand for SubmitSyncBuilderLayer } } -unsafe impl<'a, I, O, B, D> AddCommand> for SubmitSyncBuilderLayer - where I: AddCommand, Out = O>, +unsafe impl AddCommand> for SubmitSyncBuilderLayer + where I: AddCommand, Out = O>, B: Buffer + Clone + 'static { type Out = SubmitSyncBuilderLayer; #[inline] - fn add(mut self, command: cmd::CmdUpdateBuffer<'a, B, D>) -> Self::Out { + fn add(mut self, command: cmd::CmdUpdateBuffer) -> Self::Out { self.add_buffer(command.buffer(), true); SubmitSyncBuilderLayer { diff --git a/vulkano/src/command_buffer/cmd/update_buffer.rs b/vulkano/src/command_buffer/cmd/update_buffer.rs index ac181f050..03afc8cdc 100644 --- a/vulkano/src/command_buffer/cmd/update_buffer.rs +++ b/vulkano/src/command_buffer/cmd/update_buffer.rs @@ -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 { // 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 CmdUpdateBuffer + 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, CmdUpdateBufferError> { + // TODO: type safety + pub fn new(buffer: B, data: D) -> Result, 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 CmdUpdateBuffer { /// 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 DeviceOwned for CmdUpdateBuffer 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

+unsafe impl<'a, P, B, D> AddCommand<&'a CmdUpdateBuffer> for UnsafeCommandBufferBuilder

where B: Buffer, - D: Copy + 'static, P: CommandPool, { type Out = UnsafeCommandBufferBuilder

; #[inline] - fn add(self, command: &'a CmdUpdateBuffer<'d, B, D>) -> Self::Out { + fn add(self, command: &'a CmdUpdateBuffer) -> 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