From 5916e882ee9130c9756bbcb78f4a30b291c2f904 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Sat, 6 May 2017 14:25:56 +0200 Subject: [PATCH] Add CommandBufferBuilder::queue_family() --- vulkano/src/command_buffer/auto.rs | 14 +-- vulkano/src/command_buffer/builder.rs | 22 ++++- .../src/command_buffer/cb/abstract_storage.rs | 10 +- .../src/command_buffer/cb/auto_barriers.rs | 10 +- .../src/command_buffer/cb/context_check.rs | 10 +- vulkano/src/command_buffer/cb/device_check.rs | 10 +- .../src/command_buffer/cb/queue_ty_check.rs | 94 ++++++++----------- vulkano/src/command_buffer/cb/state_cache.rs | 10 +- vulkano/src/command_buffer/cb/submit_sync.rs | 10 +- vulkano/src/command_buffer/cb/sys.rs | 9 ++ .../command_buffer/commands_raw/execute.rs | 6 ++ vulkano/src/command_buffer/traits.rs | 7 ++ 12 files changed, 101 insertions(+), 111 deletions(-) diff --git a/vulkano/src/command_buffer/auto.rs b/vulkano/src/command_buffer/auto.rs index 803a8ee4..4763f06b 100644 --- a/vulkano/src/command_buffer/auto.rs +++ b/vulkano/src/command_buffer/auto.rs @@ -41,9 +41,6 @@ impl AutoCommandBufferBuilder> { pub fn new(device: Arc, queue_family: QueueFamily) -> Result>, OomError> { - let supports_graphics = queue_family.supports_graphics(); - let supports_compute = queue_family.supports_compute(); - let pool = Device::standard_command_pool(&device, queue_family); let cmd = unsafe { @@ -53,7 +50,7 @@ impl AutoCommandBufferBuilder> { let c = cb::SubmitSyncBuilderLayer::new(c); let c = cb::StateCacheLayer::new(c); let c = cb::ContextCheckLayer::new(c, false, true); - let c = cb::QueueTyCheckLayer::new(c, supports_graphics, supports_compute); + let c = cb::QueueTyCheckLayer::new(c); let c = cb::DeviceCheckLayer::new(c); c }; @@ -124,13 +121,8 @@ unsafe impl

CommandBufferBuilder for AutoCommandBufferBuilder

P: CommandPool { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/builder.rs b/vulkano/src/command_buffer/builder.rs index f8ee3f7f..698b0a57 100644 --- a/vulkano/src/command_buffer/builder.rs +++ b/vulkano/src/command_buffer/builder.rs @@ -26,6 +26,7 @@ use framebuffer::FramebufferAbstract; use framebuffer::RenderPassAbstract; use framebuffer::RenderPassDescClearValues; use image::Image; +use instance::QueueFamily; use pipeline::ComputePipelineAbstract; use pipeline::GraphicsPipelineAbstract; use pipeline::vertex::VertexSource; @@ -247,10 +248,19 @@ pub unsafe trait CommandBufferBuilder: DeviceOwned { } /// Returns true if the pool of the builder supports graphics operations. - fn supports_graphics(&self) -> bool; + #[inline] + fn supports_graphics(&self) -> bool { + self.queue_family().supports_graphics() + } /// Returns true if the pool of the builder supports compute operations. - fn supports_compute(&self) -> bool; + #[inline] + fn supports_compute(&self) -> bool { + self.queue_family().supports_compute() + } + + /// Returns the queue family of the command buffer builder. + fn queue_family(&self) -> QueueFamily; } /// Error that can happen when adding a command to a command buffer builder. @@ -320,6 +330,10 @@ pub enum CommandAddError { /// The queue family doesn't support compute operations. ComputeOperationsNotSupported, + + /// Trying to execute a secondary command buffer in a primary command buffer of a different + /// queue family. + QueueFamilyMismatch, } impl error::Error for CommandAddError { @@ -341,6 +355,10 @@ impl error::Error for CommandAddError { CommandAddError::ComputeOperationsNotSupported => { "the queue family doesn't support compute operations" }, + CommandAddError::QueueFamilyMismatch => { + "trying to execute a secondary command buffer in a primary command buffer of a \ + different queue family" + }, } } } diff --git a/vulkano/src/command_buffer/cb/abstract_storage.rs b/vulkano/src/command_buffer/cb/abstract_storage.rs index b6022e88..66a10dbd 100644 --- a/vulkano/src/command_buffer/cb/abstract_storage.rs +++ b/vulkano/src/command_buffer/cb/abstract_storage.rs @@ -23,6 +23,7 @@ use device::Device; use device::DeviceOwned; use device::Queue; use image::ImageAccess; +use instance::QueueFamily; use sync::AccessFlagBits; use sync::GpuFuture; use sync::PipelineStages; @@ -98,13 +99,8 @@ unsafe impl CommandBufferBuild for AbstractStorageLayer unsafe impl CommandBufferBuilder for AbstractStorageLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/auto_barriers.rs b/vulkano/src/command_buffer/cb/auto_barriers.rs index 1cef48a5..f004e231 100644 --- a/vulkano/src/command_buffer/cb/auto_barriers.rs +++ b/vulkano/src/command_buffer/cb/auto_barriers.rs @@ -15,6 +15,7 @@ use command_buffer::CommandBufferBuilder; use command_buffer::commands_raw; use device::Device; use device::DeviceOwned; +use instance::QueueFamily; pub struct AutoPipelineBarriersLayer { inner: I, @@ -67,13 +68,8 @@ unsafe impl CommandBufferBuilder for AutoPipelineBarriersLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/context_check.rs b/vulkano/src/command_buffer/cb/context_check.rs index 573865c6..b52e6ace 100644 --- a/vulkano/src/command_buffer/cb/context_check.rs +++ b/vulkano/src/command_buffer/cb/context_check.rs @@ -15,6 +15,7 @@ use command_buffer::CommandBufferBuilder; use command_buffer::commands_raw; use device::Device; use device::DeviceOwned; +use instance::QueueFamily; /// Layer around a command buffer builder that checks whether the commands can be executed in the /// given context related to render passes. @@ -91,13 +92,8 @@ unsafe impl CommandBufferBuilder for ContextCheckLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/device_check.rs b/vulkano/src/command_buffer/cb/device_check.rs index 9653d0df..f163efb9 100644 --- a/vulkano/src/command_buffer/cb/device_check.rs +++ b/vulkano/src/command_buffer/cb/device_check.rs @@ -15,6 +15,7 @@ use command_buffer::CommandBufferBuilder; use command_buffer::commands_raw; use device::Device; use device::DeviceOwned; +use instance::QueueFamily; use VulkanObject; /// Layer around a command buffer builder that checks whether the commands added to it belong to @@ -52,13 +53,8 @@ unsafe impl CommandBufferBuilder for DeviceCheckLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/queue_ty_check.rs b/vulkano/src/command_buffer/cb/queue_ty_check.rs index ecfc68c9..0c8b74dd 100644 --- a/vulkano/src/command_buffer/cb/queue_ty_check.rs +++ b/vulkano/src/command_buffer/cb/queue_ty_check.rs @@ -12,9 +12,12 @@ use command_buffer::cb::AddCommand; use command_buffer::cb::CommandBufferBuild; use command_buffer::CommandAddError; use command_buffer::CommandBufferBuilder; +use command_buffer::CommandBuffer; use command_buffer::commands_raw; use device::Device; use device::DeviceOwned; +use instance::QueueFamily; +use VulkanObject; /// Layer around a command buffer builder that checks whether the commands added to it match the /// type of the queue family of the underlying builder. @@ -23,22 +26,14 @@ use device::DeviceOwned; /// that support graphical or compute operations. This is what this layer verifies. pub struct QueueTyCheckLayer { inner: I, - supports_graphics: bool, - supports_compute: bool, } impl QueueTyCheckLayer { /// Builds a new `QueueTyCheckLayer`. - /// - /// Note that this layer will only protect you if you pass correct values for - /// `supports_graphics` and `supports_compute`. It is not unsafe to pass wrong values, but if - /// you do so then the layer will be inefficient as a safety tool. #[inline] - pub fn new(inner: I, supports_graphics: bool, supports_compute: bool) -> QueueTyCheckLayer { + pub fn new(inner: I) -> QueueTyCheckLayer { QueueTyCheckLayer { inner: inner, - supports_graphics: supports_graphics, - supports_compute: supports_compute, } } @@ -47,22 +42,6 @@ impl QueueTyCheckLayer { pub fn into_inner(self) -> I { self.inner } - - /// Returns true if graphical operations can be added to this layer. - /// - /// This returns the same value as what was passed to the constructor. - #[inline] - pub fn supports_graphics(&self) -> bool { - self.supports_graphics - } - - /// Returns true if compute operations can be added to this layer. - /// - /// This returns the same value as what was passed to the constructor. - #[inline] - pub fn supports_compute(&self) -> bool { - self.supports_compute - } } unsafe impl DeviceOwned for QueueTyCheckLayer @@ -74,15 +53,12 @@ unsafe impl DeviceOwned for QueueTyCheckLayer } } -unsafe impl CommandBufferBuilder for QueueTyCheckLayer where I: DeviceOwned { +unsafe impl CommandBufferBuilder for QueueTyCheckLayer + where I: CommandBufferBuilder +{ #[inline] - fn supports_graphics(&self) -> bool { - self.supports_graphics - } - - #[inline] - fn supports_compute(&self) -> bool { - self.supports_compute + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } @@ -98,15 +74,10 @@ unsafe impl CommandBufferBuild for QueueTyCheckLayer } } -// TODO: actually implement - -// TODO: implement CmdExecuteCommands -//q_ty_impl!((C), commands_raw::CmdExecuteCommands); - macro_rules! q_ty_impl_always { (($($param:ident),*), $cmd:ty) => { unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer - where I: AddCommand<$cmd, Out = O> + where I: CommandBufferBuilder + AddCommand<$cmd, Out = O> { type Out = QueueTyCheckLayer; @@ -114,8 +85,6 @@ macro_rules! q_ty_impl_always { fn add(self, command: $cmd) -> Result { Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, }) } } @@ -131,7 +100,7 @@ q_ty_impl_always!((B, D), commands_raw::CmdUpdateBuffer); macro_rules! q_ty_impl_graphics { (($($param:ident),*), $cmd:ty) => { unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer - where I: AddCommand<$cmd, Out = O> + where I: CommandBufferBuilder + AddCommand<$cmd, Out = O> { type Out = QueueTyCheckLayer; @@ -143,8 +112,6 @@ macro_rules! q_ty_impl_graphics { Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, }) } } @@ -166,7 +133,7 @@ q_ty_impl_graphics!((S, D), commands_raw::CmdResolveImage); macro_rules! q_ty_impl_compute { (($($param:ident),*), $cmd:ty) => { unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer - where I: AddCommand<$cmd, Out = O> + where I: CommandBufferBuilder + AddCommand<$cmd, Out = O> { type Out = QueueTyCheckLayer; @@ -178,8 +145,6 @@ macro_rules! q_ty_impl_compute { Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, }) } } @@ -191,7 +156,7 @@ q_ty_impl_compute!((), commands_raw::CmdDispatchRaw); macro_rules! q_ty_impl_graphics_or_compute { (($($param:ident),*), $cmd:ty) => { unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer - where I: AddCommand<$cmd, Out = O> + where I: CommandBufferBuilder + AddCommand<$cmd, Out = O> { type Out = QueueTyCheckLayer; @@ -200,8 +165,6 @@ macro_rules! q_ty_impl_graphics_or_compute { assert!(self.supports_graphics() || self.supports_compute()); // TODO: proper error? Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, }) } } @@ -213,7 +176,7 @@ q_ty_impl_graphics_or_compute!((), commands_raw::CmdSetEvent); q_ty_impl_graphics_or_compute!((), commands_raw::CmdSetState); unsafe impl AddCommand> for QueueTyCheckLayer - where I: AddCommand, Out = O> + where I: CommandBufferBuilder + AddCommand, Out = O> { type Out = QueueTyCheckLayer; @@ -231,14 +194,12 @@ unsafe impl AddCommand> for QueueTyC Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, }) } } unsafe impl AddCommand> for QueueTyCheckLayer - where I: AddCommand, Out = O> + where I: CommandBufferBuilder + AddCommand, Out = O> { type Out = QueueTyCheckLayer; @@ -256,8 +217,29 @@ unsafe impl AddCommand> Ok(QueueTyCheckLayer { inner: self.inner.add(command)?, - supports_graphics: self.supports_graphics, - supports_compute: self.supports_compute, + }) + } +} + +unsafe impl AddCommand> for QueueTyCheckLayer + where I: CommandBufferBuilder + AddCommand, Out = O>, + C: CommandBuffer +{ + type Out = QueueTyCheckLayer; + + #[inline] + fn add(self, command: commands_raw::CmdExecuteCommands) -> Result { + // Note that safety rules guarantee that the secondary command buffer belongs to the same + // device as ourselves. Therefore this assert is only a debug assert. + debug_assert_eq!(command.command_buffer().queue_family().physical_device().internal_object(), + self.queue_family().physical_device().internal_object()); + + if command.command_buffer().queue_family().id() != self.queue_family().id() { + return Err(CommandAddError::QueueFamilyMismatch); + } + + Ok(QueueTyCheckLayer { + inner: self.inner.add(command)?, }) } } diff --git a/vulkano/src/command_buffer/cb/state_cache.rs b/vulkano/src/command_buffer/cb/state_cache.rs index f32585ba..9aafbf8b 100644 --- a/vulkano/src/command_buffer/cb/state_cache.rs +++ b/vulkano/src/command_buffer/cb/state_cache.rs @@ -16,6 +16,7 @@ use command_buffer::commands_raw; use command_buffer::DynamicState; use device::Device; use device::DeviceOwned; +use instance::QueueFamily; use VulkanObject; use vk; @@ -80,13 +81,8 @@ unsafe impl CommandBufferBuilder for StateCacheLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/submit_sync.rs b/vulkano/src/command_buffer/cb/submit_sync.rs index c7142c28..2b410eae 100644 --- a/vulkano/src/command_buffer/cb/submit_sync.rs +++ b/vulkano/src/command_buffer/cb/submit_sync.rs @@ -19,6 +19,7 @@ use command_buffer::CommandBuffer; use command_buffer::CommandBufferBuilder; use command_buffer::commands_raw; use image::ImageAccess; +use instance::QueueFamily; use device::Device; use device::DeviceOwned; use device::Queue; @@ -108,13 +109,8 @@ unsafe impl CommandBufferBuilder for SubmitSyncBuilderLayer where I: CommandBufferBuilder { #[inline] - fn supports_graphics(&self) -> bool { - self.inner.supports_graphics() - } - - #[inline] - fn supports_compute(&self) -> bool { - self.inner.supports_compute() + fn queue_family(&self) -> QueueFamily { + self.inner.queue_family() } } diff --git a/vulkano/src/command_buffer/cb/sys.rs b/vulkano/src/command_buffer/cb/sys.rs index 9ec0f219..2dbf3d38 100644 --- a/vulkano/src/command_buffer/cb/sys.rs +++ b/vulkano/src/command_buffer/cb/sys.rs @@ -14,6 +14,7 @@ use std::sync::atomic::AtomicBool; use buffer::BufferAccess; use command_buffer::CommandBuffer; +use command_buffer::CommandBufferBuilder; use command_buffer::cb::CommandBufferBuild; use command_buffer::pool::AllocatedCommandBuffer; use command_buffer::pool::CommandPool; @@ -27,6 +28,7 @@ use framebuffer::RenderPass; use framebuffer::RenderPassAbstract; use framebuffer::Subpass; use image::ImageAccess; +use instance::QueueFamily; use sync::AccessFlagBits; use sync::PipelineStages; use sync::GpuFuture; @@ -235,6 +237,13 @@ unsafe impl

DeviceOwned for UnsafeCommandBufferBuilder

where P: CommandPoo } } +unsafe impl

CommandBufferBuilder for UnsafeCommandBufferBuilder

where P: CommandPool { + #[inline] + fn queue_family(&self) -> QueueFamily { + self.pool.as_ref().unwrap().queue_family() + } +} + unsafe impl

VulkanObject for UnsafeCommandBufferBuilder

where P: CommandPool { type Object = vk::CommandBuffer; diff --git a/vulkano/src/command_buffer/commands_raw/execute.rs b/vulkano/src/command_buffer/commands_raw/execute.rs index e6726187..5924a758 100644 --- a/vulkano/src/command_buffer/commands_raw/execute.rs +++ b/vulkano/src/command_buffer/commands_raw/execute.rs @@ -44,6 +44,12 @@ impl CmdExecuteCommands { command_buffer: command_buffer, }*/ } + + /// Returns the command buffer to be executed. + #[inline] + pub fn command_buffer(&self) -> &Cb { + &self.command_buffer + } } unsafe impl DeviceOwned for CmdExecuteCommands diff --git a/vulkano/src/command_buffer/traits.rs b/vulkano/src/command_buffer/traits.rs index cf904478..fc3f3303 100644 --- a/vulkano/src/command_buffer/traits.rs +++ b/vulkano/src/command_buffer/traits.rs @@ -22,6 +22,7 @@ use device::Device; use device::DeviceOwned; use device::Queue; use image::ImageAccess; +use instance::QueueFamily; use sync::AccessFlagBits; use sync::DummyFuture; use sync::GpuFuture; @@ -36,6 +37,12 @@ pub unsafe trait CommandBuffer: DeviceOwned { /// Returns the underlying `UnsafeCommandBuffer` of this command buffer. fn inner(&self) -> &UnsafeCommandBuffer; + /// Returns the queue family of the command buffer. + #[inline] + fn queue_family(&self) -> QueueFamily { + self.inner().queue_family() + } + /// Checks whether this command buffer is allowed to be submitted after the `future` and on /// the given queue. ///