Correctly implement check_dynamic_state_validity

This commit is contained in:
Pierre Krieger 2017-06-29 13:19:05 +02:00
parent e191c8ae5c
commit 6daef4e5fc
2 changed files with 217 additions and 1 deletions

View File

@ -20,7 +20,58 @@ pub fn check_dynamic_state_validity<Pl>(pipeline: &Pl, state: &DynamicState)
{ {
let device = pipeline.device(); let device = pipeline.device();
// FIXME: if pipeline.has_dynamic_line_width() {
if let Some(value) = state.line_width {
if value != 1.0 && !pipeline.device().enabled_features().wide_lines {
return Err(CheckDynamicStateValidityError::LineWidthMissingExtension);
}
} else {
return Err(CheckDynamicStateValidityError::LineWidthMissing);
}
} else {
if state.line_width.is_some() {
return Err(CheckDynamicStateValidityError::LineWidthNotDynamic);
}
}
if pipeline.has_dynamic_viewports() {
if let Some(ref viewports) = state.viewports {
if viewports.len() != pipeline.num_viewports() as usize {
return Err(CheckDynamicStateValidityError::ViewportsCountMismatch {
expected: pipeline.num_viewports() as usize,
obtained: viewports.len(),
});
}
} else {
return Err(CheckDynamicStateValidityError::ViewportsMissing);
}
} else {
if state.viewports.is_some() {
return Err(CheckDynamicStateValidityError::ViewportsNotDynamic);
}
}
if pipeline.has_dynamic_scissors() {
if let Some(ref scissors) = state.scissors {
if scissors.len() != pipeline.num_viewports() as usize {
return Err(CheckDynamicStateValidityError::ScissorsCountMismatch {
expected: pipeline.num_viewports() as usize,
obtained: scissors.len(),
});
}
} else {
return Err(CheckDynamicStateValidityError::ScissorsMissing);
}
} else {
if state.scissors.is_some() {
return Err(CheckDynamicStateValidityError::ScissorsNotDynamic);
}
}
// TODO: don't forget to implement the rest
Ok(()) Ok(())
} }
@ -28,12 +79,71 @@ pub fn check_dynamic_state_validity<Pl>(pipeline: &Pl, state: &DynamicState)
/// Error that can happen when validating dynamic states. /// Error that can happen when validating dynamic states.
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum CheckDynamicStateValidityError { pub enum CheckDynamicStateValidityError {
/// Passed a dynamic line width, while the pipeline doesn't have line width set as dynamic.
LineWidthNotDynamic,
/// The pipeline has a dynamic line width, but no line width value was passed.
LineWidthMissing,
/// The `wide_lines` extension must be enabled in order to use line width values different
/// from 1.0.
LineWidthMissingExtension,
/// Passed dynamic viewports, while the pipeline doesn't have viewports set as dynamic.
ViewportsNotDynamic,
/// The pipeline has dynamic viewports, but no viewports were passed.
ViewportsMissing,
/// The number of dynamic viewports doesn't match the expected number of viewports.
ViewportsCountMismatch {
/// Expected number of viewports.
expected: usize,
/// Number of viewports that were passed.
obtained: usize,
},
/// Passed dynamic scissors, while the pipeline doesn't have scissors set as dynamic.
ScissorsNotDynamic,
/// The pipeline has dynamic scissors, but no scissors were passed.
ScissorsMissing,
/// The number of dynamic scissors doesn't match the expected number of scissors.
ScissorsCountMismatch {
/// Expected number of scissors.
expected: usize,
/// Number of scissors that were passed.
obtained: usize,
},
} }
impl error::Error for CheckDynamicStateValidityError { impl error::Error for CheckDynamicStateValidityError {
#[inline] #[inline]
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { match *self {
CheckDynamicStateValidityError::LineWidthNotDynamic => {
"passed a dynamic line width, while the pipeline doesn't have line width set as \
dynamic"
},
CheckDynamicStateValidityError::LineWidthMissing => {
"the pipeline has a dynamic line width, but no line width value was passed"
},
CheckDynamicStateValidityError::LineWidthMissingExtension => {
"the `wide_lines` extension must be enabled in order to use line width values \
different from 1.0"
},
CheckDynamicStateValidityError::ViewportsNotDynamic => {
"passed dynamic viewports, while the pipeline doesn't have viewports set as \
dynamic"
},
CheckDynamicStateValidityError::ViewportsMissing => {
"the pipeline has dynamic viewports, but no viewports were passed"
},
CheckDynamicStateValidityError::ViewportsCountMismatch { .. } => {
"the number of dynamic viewports doesn't match the expected number of viewports"
},
CheckDynamicStateValidityError::ScissorsNotDynamic => {
"passed dynamic scissors, while the pipeline doesn't have scissors set as dynamic"
},
CheckDynamicStateValidityError::ScissorsMissing => {
"the pipeline has dynamic scissors, but no scissors were passed"
},
CheckDynamicStateValidityError::ScissorsCountMismatch { .. } => {
"the number of dynamic scissors doesn't match the expected number of scissors"
},
} }
} }
} }
@ -44,3 +154,5 @@ impl fmt::Display for CheckDynamicStateValidityError {
write!(fmt, "{}", error::Error::description(self)) write!(fmt, "{}", error::Error::description(self))
} }
} }
// TODO: tests

View File

@ -1586,6 +1586,30 @@ impl Drop for Inner {
pub unsafe trait GraphicsPipelineAbstract: PipelineLayoutAbstract + RenderPassAbstract + VertexSource<Vec<Arc<BufferAccess + Send + Sync>>> { pub unsafe trait GraphicsPipelineAbstract: PipelineLayoutAbstract + RenderPassAbstract + VertexSource<Vec<Arc<BufferAccess + Send + Sync>>> {
/// Returns an opaque object that represents the inside of the graphics pipeline. /// Returns an opaque object that represents the inside of the graphics pipeline.
fn inner(&self) -> GraphicsPipelineSys; fn inner(&self) -> GraphicsPipelineSys;
/// Returns true if the line width used by this pipeline is dynamic.
fn has_dynamic_line_width(&self) -> bool;
/// Returns the number of viewports and scissors of this pipeline.
fn num_viewports(&self) -> u32;
/// Returns true if the viewports used by this pipeline are dynamic.
fn has_dynamic_viewports(&self) -> bool;
/// Returns true if the scissors used by this pipeline are dynamic.
fn has_dynamic_scissors(&self) -> bool;
/// Returns true if the depth bounds used by this pipeline are dynamic.
fn has_dynamic_depth_bounds(&self) -> bool;
/// Returns true if the stencil compare masks used by this pipeline are dynamic.
fn has_dynamic_stencil_compare_mask(&self) -> bool;
/// Returns true if the stencil write masks used by this pipeline are dynamic.
fn has_dynamic_stencil_write_mask(&self) -> bool;
/// Returns true if the stencil references used by this pipeline are dynamic.
fn has_dynamic_stencil_reference(&self) -> bool;
} }
unsafe impl<Mv, L, Rp> GraphicsPipelineAbstract for GraphicsPipeline<Mv, L, Rp> unsafe impl<Mv, L, Rp> GraphicsPipelineAbstract for GraphicsPipeline<Mv, L, Rp>
@ -1597,6 +1621,46 @@ unsafe impl<Mv, L, Rp> GraphicsPipelineAbstract for GraphicsPipeline<Mv, L, Rp>
fn inner(&self) -> GraphicsPipelineSys { fn inner(&self) -> GraphicsPipelineSys {
GraphicsPipelineSys(self.inner.pipeline, PhantomData) GraphicsPipelineSys(self.inner.pipeline, PhantomData)
} }
#[inline]
fn has_dynamic_line_width(&self) -> bool {
self.dynamic_line_width
}
#[inline]
fn num_viewports(&self) -> u32 {
self.num_viewports
}
#[inline]
fn has_dynamic_viewports(&self) -> bool {
self.dynamic_viewport
}
#[inline]
fn has_dynamic_scissors(&self) -> bool {
self.dynamic_scissor
}
#[inline]
fn has_dynamic_depth_bounds(&self) -> bool {
self.dynamic_depth_bounds
}
#[inline]
fn has_dynamic_stencil_compare_mask(&self) -> bool {
self.dynamic_stencil_compare_mask
}
#[inline]
fn has_dynamic_stencil_write_mask(&self) -> bool {
self.dynamic_stencil_write_mask
}
#[inline]
fn has_dynamic_stencil_reference(&self) -> bool {
self.dynamic_stencil_reference
}
} }
unsafe impl<T> GraphicsPipelineAbstract for T unsafe impl<T> GraphicsPipelineAbstract for T
@ -1607,6 +1671,46 @@ unsafe impl<T> GraphicsPipelineAbstract for T
fn inner(&self) -> GraphicsPipelineSys { fn inner(&self) -> GraphicsPipelineSys {
GraphicsPipelineAbstract::inner(&**self) GraphicsPipelineAbstract::inner(&**self)
} }
#[inline]
fn has_dynamic_line_width(&self) -> bool {
(**self).has_dynamic_line_width()
}
#[inline]
fn num_viewports(&self) -> u32 {
(**self).num_viewports()
}
#[inline]
fn has_dynamic_viewports(&self) -> bool {
(**self).has_dynamic_viewports()
}
#[inline]
fn has_dynamic_scissors(&self) -> bool {
(**self).has_dynamic_scissors()
}
#[inline]
fn has_dynamic_depth_bounds(&self) -> bool {
(**self).has_dynamic_depth_bounds()
}
#[inline]
fn has_dynamic_stencil_compare_mask(&self) -> bool {
(**self).has_dynamic_stencil_compare_mask()
}
#[inline]
fn has_dynamic_stencil_write_mask(&self) -> bool {
(**self).has_dynamic_stencil_write_mask()
}
#[inline]
fn has_dynamic_stencil_reference(&self) -> bool {
(**self).has_dynamic_stencil_reference()
}
} }
/// Opaque object that represents the inside of the graphics pipeline. /// Opaque object that represents the inside of the graphics pipeline.