mirror of
https://github.com/vulkano-rs/vulkano.git
synced 2024-11-22 14:56:42 +00:00
Check depth and stencil presence when creating a pipeline
This commit is contained in:
parent
5982778cd2
commit
32076a1e0c
@ -129,6 +129,42 @@ unsafe impl RenderPassDesc for EmptySinglePassRenderPass {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_depth(&self, subpass: u32) -> Option<bool> {
|
||||
if subpass == 0 {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_writable_depth(&self, subpass: u32) -> Option<bool> {
|
||||
if subpass == 0 {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_stencil(&self, subpass: u32) -> Option<bool> {
|
||||
if subpass == 0 {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn has_writable_stencil(&self, subpass: u32) -> Option<bool> {
|
||||
if subpass == 0 {
|
||||
Some(false)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl RenderPassAttachmentsList<()> for EmptySinglePassRenderPass {
|
||||
|
@ -95,6 +95,86 @@ pub unsafe trait RenderPassDesc {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if a subpass has a depth attachment or a depth-stencil attachment.
|
||||
#[inline]
|
||||
fn has_depth(&self, subpass: u32) -> Option<bool> {
|
||||
self.passes().skip(subpass as usize).next().map(|p| {
|
||||
let atch_num = match p.depth_stencil {
|
||||
Some((d, _)) => d,
|
||||
None => return false
|
||||
};
|
||||
|
||||
match self.attachments().skip(atch_num).next().unwrap().format.ty() {
|
||||
FormatTy::Depth => true,
|
||||
FormatTy::Stencil => false,
|
||||
FormatTy::DepthStencil => true,
|
||||
_ => unreachable!()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if a subpass has a depth attachment or a depth-stencil attachment whose
|
||||
/// layout is not `DepthStencilReadOnlyOptimal`.
|
||||
#[inline]
|
||||
fn has_writable_depth(&self, subpass: u32) -> Option<bool> {
|
||||
self.passes().skip(subpass as usize).next().map(|p| {
|
||||
let atch_num = match p.depth_stencil {
|
||||
Some((d, l)) => {
|
||||
if l == ImageLayout::DepthStencilReadOnlyOptimal { return false; }
|
||||
d
|
||||
},
|
||||
None => return false
|
||||
};
|
||||
|
||||
match self.attachments().skip(atch_num).next().unwrap().format.ty() {
|
||||
FormatTy::Depth => true,
|
||||
FormatTy::Stencil => false,
|
||||
FormatTy::DepthStencil => true,
|
||||
_ => unreachable!()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if a subpass has a stencil attachment or a depth-stencil attachment.
|
||||
#[inline]
|
||||
fn has_stencil(&self, subpass: u32) -> Option<bool> {
|
||||
self.passes().skip(subpass as usize).next().map(|p| {
|
||||
let atch_num = match p.depth_stencil {
|
||||
Some((d, _)) => d,
|
||||
None => return false
|
||||
};
|
||||
|
||||
match self.attachments().skip(atch_num).next().unwrap().format.ty() {
|
||||
FormatTy::Depth => false,
|
||||
FormatTy::Stencil => true,
|
||||
FormatTy::DepthStencil => true,
|
||||
_ => unreachable!()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true if a subpass has a stencil attachment or a depth-stencil attachment whose
|
||||
/// layout is not `DepthStencilReadOnlyOptimal`.
|
||||
#[inline]
|
||||
fn has_writable_stencil(&self, subpass: u32) -> Option<bool> {
|
||||
self.passes().skip(subpass as usize).next().map(|p| {
|
||||
let atch_num = match p.depth_stencil {
|
||||
Some((d, l)) => {
|
||||
if l == ImageLayout::DepthStencilReadOnlyOptimal { return false; }
|
||||
d
|
||||
},
|
||||
None => return false
|
||||
};
|
||||
|
||||
match self.attachments().skip(atch_num).next().unwrap().format.ty() {
|
||||
FormatTy::Depth => false,
|
||||
FormatTy::Stencil => true,
|
||||
FormatTy::DepthStencil => true,
|
||||
_ => unreachable!()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/// Extension trait for `RenderPass`. Defines which types are allowed as an attachments list.
|
||||
@ -346,6 +426,32 @@ impl<'a, L: 'a> Subpass<'a, L> where L: RenderPass + RenderPassDesc {
|
||||
self.render_pass.num_color_attachments(self.subpass_id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if the subpass has a depth attachment or a depth-stencil attachment.
|
||||
#[inline]
|
||||
pub fn has_depth(&self) -> bool {
|
||||
self.render_pass.has_depth(self.subpass_id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if the subpass has a depth attachment or a depth-stencil attachment whose
|
||||
/// layout is not `DepthStencilReadOnlyOptimal`.
|
||||
#[inline]
|
||||
pub fn has_writable_depth(&self) -> bool {
|
||||
self.render_pass.has_writable_depth(self.subpass_id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if the subpass has a stencil attachment or a depth-stencil attachment.
|
||||
#[inline]
|
||||
pub fn has_stencil(&self) -> bool {
|
||||
self.render_pass.has_stencil(self.subpass_id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if the subpass has a stencil attachment or a depth-stencil attachment whose
|
||||
/// layout is not `DepthStencilReadOnlyOptimal`.
|
||||
#[inline]
|
||||
pub fn has_writable_stencil(&self) -> bool {
|
||||
self.render_pass.has_writable_stencil(self.subpass_id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns true if the subpass has any color or depth/stencil attachment.
|
||||
#[inline]
|
||||
pub fn has_color_or_depth_stencil_attachment(&self) -> bool {
|
||||
|
@ -469,6 +469,25 @@ impl<Vdef, L, Rp> GraphicsPipeline<Vdef, L, Rp>
|
||||
_ => return Err(GraphicsPipelineCreationError::WrongStencilState)
|
||||
};
|
||||
|
||||
if params.depth_stencil.depth_write && !params.render_pass.has_writable_depth() {
|
||||
return Err(GraphicsPipelineCreationError::NoDepthAttachment);
|
||||
}
|
||||
|
||||
if params.depth_stencil.depth_compare != Compare::Always &&
|
||||
!params.render_pass.has_depth()
|
||||
{
|
||||
return Err(GraphicsPipelineCreationError::NoDepthAttachment);
|
||||
}
|
||||
|
||||
if (!params.depth_stencil.stencil_front.always_keep() ||
|
||||
!params.depth_stencil.stencil_back.always_keep()) &&
|
||||
!params.render_pass.has_stencil()
|
||||
{
|
||||
return Err(GraphicsPipelineCreationError::NoStencilAttachment);
|
||||
}
|
||||
|
||||
// FIXME: stencil writability
|
||||
|
||||
vk::PipelineDepthStencilStateCreateInfo {
|
||||
sType: vk::STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO,
|
||||
pNext: ptr::null(),
|
||||
@ -828,6 +847,14 @@ pub enum GraphicsPipelineCreationError {
|
||||
|
||||
/// The `logic_op` feature must be enabled in order to use logic operations.
|
||||
LogicOpFeatureNotEnabled,
|
||||
|
||||
/// The depth test requires a depth attachment but render pass has no depth attachment, or
|
||||
/// depth writing is enabled and the depth attachment is read-only.
|
||||
NoDepthAttachment,
|
||||
|
||||
/// The stencil test requires a stencil attachment but render pass has no stencil attachment, or
|
||||
/// stencil writing is enabled and the stencil attachment is read-only.
|
||||
NoStencilAttachment,
|
||||
}
|
||||
|
||||
impl error::Error for GraphicsPipelineCreationError {
|
||||
@ -911,6 +938,12 @@ impl error::Error for GraphicsPipelineCreationError {
|
||||
GraphicsPipelineCreationError::LogicOpFeatureNotEnabled => {
|
||||
"the `logic_op` feature must be enabled in order to use logic operations"
|
||||
},
|
||||
GraphicsPipelineCreationError::NoDepthAttachment => {
|
||||
"the depth attachment of the render pass does not match the depth test"
|
||||
},
|
||||
GraphicsPipelineCreationError::NoStencilAttachment => {
|
||||
"the stencil attachment of the render pass does not match the stencil test"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user