Merge pull request #437 from tomaka/q-fam-builder

Add CommandBufferBuilder::queue_family()
This commit is contained in:
tomaka 2017-05-06 20:37:46 +02:00 committed by GitHub
commit c1f104d2c4
12 changed files with 101 additions and 111 deletions

View File

@ -41,9 +41,6 @@ impl AutoCommandBufferBuilder<Arc<StandardCommandPool>> {
pub fn new(device: Arc<Device>, queue_family: QueueFamily)
-> Result<AutoCommandBufferBuilder<Arc<StandardCommandPool>>, 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<Arc<StandardCommandPool>> {
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<P> CommandBufferBuilder for AutoCommandBufferBuilder<P>
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()
}
}

View File

@ -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"
},
}
}
}

View File

@ -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<I, O, E> CommandBufferBuild for AbstractStorageLayer<I>
unsafe impl<I> CommandBufferBuilder for AbstractStorageLayer<I> 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()
}
}

View File

@ -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<I> {
inner: I,
@ -67,13 +68,8 @@ unsafe impl<I> CommandBufferBuilder for AutoPipelineBarriersLayer<I>
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()
}
}

View File

@ -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<I> CommandBufferBuilder for ContextCheckLayer<I>
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()
}
}

View File

@ -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<I> CommandBufferBuilder for DeviceCheckLayer<I>
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()
}
}

View File

@ -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<I> {
inner: I,
supports_graphics: bool,
supports_compute: bool,
}
impl<I> QueueTyCheckLayer<I> {
/// 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<I> {
pub fn new(inner: I) -> QueueTyCheckLayer<I> {
QueueTyCheckLayer {
inner: inner,
supports_graphics: supports_graphics,
supports_compute: supports_compute,
}
}
@ -47,22 +42,6 @@ impl<I> QueueTyCheckLayer<I> {
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<I> DeviceOwned for QueueTyCheckLayer<I>
@ -74,15 +53,12 @@ unsafe impl<I> DeviceOwned for QueueTyCheckLayer<I>
}
}
unsafe impl<I> CommandBufferBuilder for QueueTyCheckLayer<I> where I: DeviceOwned {
unsafe impl<I> CommandBufferBuilder for QueueTyCheckLayer<I>
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<I, O, E> CommandBufferBuild for QueueTyCheckLayer<I>
}
}
// TODO: actually implement
// TODO: implement CmdExecuteCommands
//q_ty_impl!((C), commands_raw::CmdExecuteCommands<C>);
macro_rules! q_ty_impl_always {
(($($param:ident),*), $cmd:ty) => {
unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer<I>
where I: AddCommand<$cmd, Out = O>
where I: CommandBufferBuilder + AddCommand<$cmd, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -114,8 +85,6 @@ macro_rules! q_ty_impl_always {
fn add(self, command: $cmd) -> Result<Self::Out, CommandAddError> {
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<B, D>);
macro_rules! q_ty_impl_graphics {
(($($param:ident),*), $cmd:ty) => {
unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer<I>
where I: AddCommand<$cmd, Out = O>
where I: CommandBufferBuilder + AddCommand<$cmd, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -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<S, D>);
macro_rules! q_ty_impl_compute {
(($($param:ident),*), $cmd:ty) => {
unsafe impl<'a, I, O $(, $param)*> AddCommand<$cmd> for QueueTyCheckLayer<I>
where I: AddCommand<$cmd, Out = O>
where I: CommandBufferBuilder + AddCommand<$cmd, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -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<I>
where I: AddCommand<$cmd, Out = O>
where I: CommandBufferBuilder + AddCommand<$cmd, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -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<I, O, Pl> AddCommand<commands_raw::CmdBindPipeline<Pl>> for QueueTyCheckLayer<I>
where I: AddCommand<commands_raw::CmdBindPipeline<Pl>, Out = O>
where I: CommandBufferBuilder + AddCommand<commands_raw::CmdBindPipeline<Pl>, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -231,14 +194,12 @@ unsafe impl<I, O, Pl> AddCommand<commands_raw::CmdBindPipeline<Pl>> for QueueTyC
Ok(QueueTyCheckLayer {
inner: self.inner.add(command)?,
supports_graphics: self.supports_graphics,
supports_compute: self.supports_compute,
})
}
}
unsafe impl<I, O, S, Pl> AddCommand<commands_raw::CmdBindDescriptorSets<S, Pl>> for QueueTyCheckLayer<I>
where I: AddCommand<commands_raw::CmdBindDescriptorSets<S, Pl>, Out = O>
where I: CommandBufferBuilder + AddCommand<commands_raw::CmdBindDescriptorSets<S, Pl>, Out = O>
{
type Out = QueueTyCheckLayer<O>;
@ -256,8 +217,29 @@ unsafe impl<I, O, S, Pl> AddCommand<commands_raw::CmdBindDescriptorSets<S, Pl>>
Ok(QueueTyCheckLayer {
inner: self.inner.add(command)?,
supports_graphics: self.supports_graphics,
supports_compute: self.supports_compute,
})
}
}
unsafe impl<I, O, C> AddCommand<commands_raw::CmdExecuteCommands<C>> for QueueTyCheckLayer<I>
where I: CommandBufferBuilder + AddCommand<commands_raw::CmdExecuteCommands<C>, Out = O>,
C: CommandBuffer
{
type Out = QueueTyCheckLayer<O>;
#[inline]
fn add(self, command: commands_raw::CmdExecuteCommands<C>) -> Result<Self::Out, CommandAddError> {
// 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)?,
})
}
}

View File

@ -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<I> CommandBufferBuilder for StateCacheLayer<I>
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()
}
}

View File

@ -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<I> CommandBufferBuilder for SubmitSyncBuilderLayer<I>
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()
}
}

View File

@ -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<P> DeviceOwned for UnsafeCommandBufferBuilder<P> where P: CommandPoo
}
}
unsafe impl<P> CommandBufferBuilder for UnsafeCommandBufferBuilder<P> where P: CommandPool {
#[inline]
fn queue_family(&self) -> QueueFamily {
self.pool.as_ref().unwrap().queue_family()
}
}
unsafe impl<P> VulkanObject for UnsafeCommandBufferBuilder<P> where P: CommandPool {
type Object = vk::CommandBuffer;

View File

@ -44,6 +44,12 @@ impl<Cb> CmdExecuteCommands<Cb> {
command_buffer: command_buffer,
}*/
}
/// Returns the command buffer to be executed.
#[inline]
pub fn command_buffer(&self) -> &Cb {
&self.command_buffer
}
}
unsafe impl<Cb> DeviceOwned for CmdExecuteCommands<Cb>

View File

@ -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<Self::Pool>;
/// 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.
///