mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-27 09:15:14 +00:00
Merge pull request #420 from tomaka/queue-ty
Implement QueueTyCheckLayer correctly
This commit is contained in:
commit
a1b65b3845
@ -40,6 +40,9 @@ 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 {
|
||||
@ -49,7 +52,7 @@ impl AutoCommandBufferBuilder<Arc<StandardCommandPool>> {
|
||||
let c = cb::SubmitSyncBuilderLayer::new(c);
|
||||
let c = cb::StateCacheLayer::new(c);
|
||||
let c = cb::ContextCheckLayer::new(c);
|
||||
let c = cb::QueueTyCheckLayer::new(c);
|
||||
let c = cb::QueueTyCheckLayer::new(c, supports_graphics, supports_compute);
|
||||
let c = cb::DeviceCheckLayer::new(c);
|
||||
c
|
||||
};
|
||||
@ -119,6 +122,15 @@ unsafe impl<P> CommandBufferBuilder for AutoCommandBufferBuilder<P>
|
||||
where Cb<P>: CommandBufferBuilder,
|
||||
P: CommandPool
|
||||
{
|
||||
#[inline]
|
||||
fn supports_graphics(&self) -> bool {
|
||||
self.inner.supports_graphics()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_compute(&self) -> bool {
|
||||
self.inner.supports_compute()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! pass_through {
|
||||
|
@ -198,6 +198,12 @@ pub unsafe trait CommandBufferBuilder: DeviceOwned {
|
||||
{
|
||||
CommandBufferBuild::build(self)
|
||||
}
|
||||
|
||||
/// Returns true if the pool of the builder supports graphics operations.
|
||||
fn supports_graphics(&self) -> bool;
|
||||
|
||||
/// Returns true if the pool of the builder supports compute operations.
|
||||
fn supports_compute(&self) -> bool;
|
||||
}
|
||||
|
||||
pub unsafe trait CommandBufferBuilderBuffered {
|
||||
|
@ -95,7 +95,16 @@ unsafe impl<I, O, E> CommandBufferBuild for AbstractStorageLayer<I>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I> CommandBufferBuilder for AbstractStorageLayer<I> where I: DeviceOwned {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! pass_through {
|
||||
|
@ -65,6 +65,15 @@ unsafe impl<I> DeviceOwned for AutoPipelineBarriersLayer<I>
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! pass_through {
|
||||
|
@ -64,6 +64,15 @@ unsafe impl<I> DeviceOwned for ContextCheckLayer<I>
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: actually implement
|
||||
|
@ -50,6 +50,15 @@ unsafe impl<I> DeviceOwned for DeviceCheckLayer<I>
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I, O, E> CommandBufferBuild for DeviceCheckLayer<I>
|
||||
|
@ -22,14 +22,22 @@ 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) -> QueueTyCheckLayer<I> {
|
||||
pub fn new(inner: I, supports_graphics: bool, supports_compute: bool) -> QueueTyCheckLayer<I> {
|
||||
QueueTyCheckLayer {
|
||||
inner: inner,
|
||||
supports_graphics: supports_graphics,
|
||||
supports_compute: supports_compute,
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +46,22 @@ 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>
|
||||
@ -49,9 +73,16 @@ unsafe impl<I> DeviceOwned for QueueTyCheckLayer<I>
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I> CommandBufferBuilder for QueueTyCheckLayer<I>
|
||||
where I: CommandBufferBuilder
|
||||
{
|
||||
unsafe impl<I> CommandBufferBuilder for QueueTyCheckLayer<I> where I: DeviceOwned {
|
||||
#[inline]
|
||||
fn supports_graphics(&self) -> bool {
|
||||
self.supports_graphics
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn supports_compute(&self) -> bool {
|
||||
self.supports_compute
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<I, O, E> CommandBufferBuild for QueueTyCheckLayer<I>
|
||||
@ -68,7 +99,10 @@ unsafe impl<I, O, E> CommandBufferBuild for QueueTyCheckLayer<I>
|
||||
|
||||
// TODO: actually implement
|
||||
|
||||
macro_rules! pass_through {
|
||||
// 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>
|
||||
@ -79,32 +113,136 @@ macro_rules! pass_through {
|
||||
fn add(self, command: $cmd) -> Self::Out {
|
||||
QueueTyCheckLayer {
|
||||
inner: self.inner.add(command),
|
||||
supports_graphics: self.supports_graphics,
|
||||
supports_compute: self.supports_compute,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pass_through!((Rp, F), commands_raw::CmdBeginRenderPass<Rp, F>);
|
||||
pass_through!((S, Pl), commands_raw::CmdBindDescriptorSets<S, Pl>);
|
||||
pass_through!((B), commands_raw::CmdBindIndexBuffer<B>);
|
||||
pass_through!((Pl), commands_raw::CmdBindPipeline<Pl>);
|
||||
pass_through!((V), commands_raw::CmdBindVertexBuffers<V>);
|
||||
pass_through!((S, D), commands_raw::CmdBlitImage<S, D>);
|
||||
pass_through!((), commands_raw::CmdClearAttachments);
|
||||
pass_through!((S, D), commands_raw::CmdCopyBuffer<S, D>);
|
||||
pass_through!((S, D), commands_raw::CmdCopyBufferToImage<S, D>);
|
||||
pass_through!((S, D), commands_raw::CmdCopyImage<S, D>);
|
||||
pass_through!((), commands_raw::CmdDispatchRaw);
|
||||
pass_through!((), commands_raw::CmdDrawIndexedRaw);
|
||||
pass_through!((B), commands_raw::CmdDrawIndirectRaw<B>);
|
||||
pass_through!((), commands_raw::CmdDrawRaw);
|
||||
pass_through!((), commands_raw::CmdEndRenderPass);
|
||||
pass_through!((C), commands_raw::CmdExecuteCommands<C>);
|
||||
pass_through!((B), commands_raw::CmdFillBuffer<B>);
|
||||
pass_through!((), commands_raw::CmdNextSubpass);
|
||||
pass_through!((Pc, Pl), commands_raw::CmdPushConstants<Pc, Pl>);
|
||||
pass_through!((S, D), commands_raw::CmdResolveImage<S, D>);
|
||||
pass_through!((), commands_raw::CmdSetEvent);
|
||||
pass_through!((), commands_raw::CmdSetState);
|
||||
pass_through!((B, D), commands_raw::CmdUpdateBuffer<B, D>);
|
||||
q_ty_impl_always!((S, D), commands_raw::CmdCopyBuffer<S, D>);
|
||||
q_ty_impl_always!((S, D), commands_raw::CmdCopyBufferToImage<S, D>);
|
||||
q_ty_impl_always!((S, D), commands_raw::CmdCopyImage<S, D>);
|
||||
q_ty_impl_always!((B), commands_raw::CmdFillBuffer<B>);
|
||||
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>
|
||||
{
|
||||
type Out = QueueTyCheckLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: $cmd) -> Self::Out {
|
||||
assert!(self.supports_graphics()); // TODO: proper error
|
||||
QueueTyCheckLayer {
|
||||
inner: self.inner.add(command),
|
||||
supports_graphics: self.supports_graphics,
|
||||
supports_compute: self.supports_compute,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
q_ty_impl_graphics!((Rp, F), commands_raw::CmdBeginRenderPass<Rp, F>);
|
||||
q_ty_impl_graphics!((B), commands_raw::CmdBindIndexBuffer<B>);
|
||||
q_ty_impl_graphics!((V), commands_raw::CmdBindVertexBuffers<V>);
|
||||
q_ty_impl_graphics!((S, D), commands_raw::CmdBlitImage<S, D>);
|
||||
q_ty_impl_graphics!((), commands_raw::CmdClearAttachments);
|
||||
q_ty_impl_graphics!((), commands_raw::CmdDrawIndexedRaw);
|
||||
q_ty_impl_graphics!((B), commands_raw::CmdDrawIndirectRaw<B>);
|
||||
q_ty_impl_graphics!((), commands_raw::CmdDrawRaw);
|
||||
q_ty_impl_graphics!((), commands_raw::CmdEndRenderPass);
|
||||
q_ty_impl_graphics!((), commands_raw::CmdNextSubpass);
|
||||
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>
|
||||
{
|
||||
type Out = QueueTyCheckLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: $cmd) -> Self::Out {
|
||||
assert!(self.supports_compute()); // TODO: proper error
|
||||
QueueTyCheckLayer {
|
||||
inner: self.inner.add(command),
|
||||
supports_graphics: self.supports_graphics,
|
||||
supports_compute: self.supports_compute,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
type Out = QueueTyCheckLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: $cmd) -> Self::Out {
|
||||
assert!(self.supports_graphics() || self.supports_compute()); // TODO: proper error
|
||||
QueueTyCheckLayer {
|
||||
inner: self.inner.add(command),
|
||||
supports_graphics: self.supports_graphics,
|
||||
supports_compute: self.supports_compute,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
q_ty_impl_graphics_or_compute!((Pc, Pl), commands_raw::CmdPushConstants<Pc, Pl>);
|
||||
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>
|
||||
{
|
||||
type Out = QueueTyCheckLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: commands_raw::CmdBindPipeline<Pl>) -> Self::Out {
|
||||
if command.is_graphics() {
|
||||
assert!(self.supports_graphics()); // TODO: proper error
|
||||
} else {
|
||||
assert!(self.supports_compute()); // TODO: proper error
|
||||
}
|
||||
|
||||
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>
|
||||
{
|
||||
type Out = QueueTyCheckLayer<O>;
|
||||
|
||||
#[inline]
|
||||
fn add(self, command: commands_raw::CmdBindDescriptorSets<S, Pl>) -> Self::Out {
|
||||
if command.is_graphics() {
|
||||
assert!(self.supports_graphics()); // TODO: proper error
|
||||
} else {
|
||||
assert!(self.supports_compute()); // TODO: proper error
|
||||
}
|
||||
|
||||
QueueTyCheckLayer {
|
||||
inner: self.inner.add(command),
|
||||
supports_graphics: self.supports_graphics,
|
||||
supports_compute: self.supports_compute,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,6 +78,15 @@ unsafe impl<I> DeviceOwned for StateCacheLayer<I>
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<Pl, I, O> AddCommand<commands_raw::CmdBindPipeline<Pl>> for StateCacheLayer<I>
|
||||
|
@ -106,6 +106,15 @@ unsafe impl<I> DeviceOwned for SubmitSyncBuilderLayer<I>
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: implement manually
|
||||
|
@ -95,6 +95,15 @@ impl<S, P> CmdBindDescriptorSets<S, P>
|
||||
}
|
||||
}
|
||||
|
||||
impl<S, P> CmdBindDescriptorSets<S, P> {
|
||||
/// True if we bind to the graphics pipeline. False if the compute pipeline.
|
||||
// TODO: should be an enum?
|
||||
#[inline]
|
||||
pub fn is_graphics(&self) -> bool {
|
||||
self.pipeline_ty == vk::PIPELINE_BIND_POINT_GRAPHICS
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<S, Pl> DeviceOwned for CmdBindDescriptorSets<S, Pl>
|
||||
where Pl: DeviceOwned
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user