blob: f9a65adbb8751bfb19a0f902fedad9117ef84b13 [file] [log] [blame]
// Copyright (c) 2017 The vulkano developers
// Licensed under the Apache License, Version 2.0
// <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT
// license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
// at your option. All files in the project carrying such
// notice may not be copied, modified, or distributed except
// according to those terms.
use std::error;
use std::fmt;
use crate::command_buffer::DynamicState;
use crate::pipeline::GraphicsPipelineAbstract;
/// Checks whether states that are about to be set are correct.
pub fn check_dynamic_state_validity<Pl>(
pipeline: &Pl,
state: &DynamicState,
) -> Result<(), CheckDynamicStateValidityError>
where
Pl: GraphicsPipelineAbstract,
{
let device = pipeline.device();
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);
}
}
if pipeline.has_dynamic_stencil_compare_mask() {
if let None = state.compare_mask {
return Err(CheckDynamicStateValidityError::CompareMaskMissing);
}
} else {
if state.compare_mask.is_some() {
return Err(CheckDynamicStateValidityError::CompareMaskNotDynamic);
}
}
if pipeline.has_dynamic_stencil_write_mask() {
if let None = state.write_mask {
return Err(CheckDynamicStateValidityError::WriteMaskMissing);
}
} else {
if state.write_mask.is_some() {
return Err(CheckDynamicStateValidityError::WriteMaskNotDynamic);
}
}
if pipeline.has_dynamic_stencil_reference() {
if let None = state.reference {
return Err(CheckDynamicStateValidityError::ReferenceMissing);
}
} else {
if state.reference.is_some() {
return Err(CheckDynamicStateValidityError::ReferenceNotDynamic);
}
}
Ok(())
}
/// Error that can happen when validating dynamic states.
#[derive(Debug, Copy, Clone)]
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,
},
/// Passed dynamic compare mask, while the pipeline doesn't have the compare mask set as dynamic.
CompareMaskNotDynamic,
/// The pipeline has dynamic compare mask, but no compare mask was passed.
CompareMaskMissing,
/// Passed dynamic write mask, while the pipeline doesn't have the write mask set as dynamic.
WriteMaskNotDynamic,
/// The pipeline has dynamic write mask, but no write mask was passed.
WriteMaskMissing,
/// Passed dynamic reference, while the pipeline doesn't have the reference set as dynamic.
ReferenceNotDynamic,
/// The pipeline has dynamic reference, but no reference was passed.
ReferenceMissing,
}
impl error::Error for CheckDynamicStateValidityError {}
impl fmt::Display for CheckDynamicStateValidityError {
#[inline]
fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(
fmt,
"{}",
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"
}
CheckDynamicStateValidityError::CompareMaskNotDynamic => {
"passed dynamic compare mask, while the pipeline doesn't have compare mask set as dynamic"
}
CheckDynamicStateValidityError::CompareMaskMissing => {
"the pipeline has dynamic compare mask, but no compare mask was passed"
}
CheckDynamicStateValidityError::WriteMaskNotDynamic => {
"passed dynamic write mask, while the pipeline doesn't have write mask set as dynamic"
}
CheckDynamicStateValidityError::WriteMaskMissing => {
"the pipeline has dynamic write mask, but no write mask was passed"
}
CheckDynamicStateValidityError::ReferenceNotDynamic => {
"passed dynamic Reference, while the pipeline doesn't have reference set as dynamic"
}
CheckDynamicStateValidityError::ReferenceMissing => {
"the pipeline has dynamic reference, but no reference was passed"
}
}
)
}
}
// TODO: tests