diff options
Diffstat (limited to 'src/command_buffer/validity/dynamic_state.rs')
-rw-r--r-- | src/command_buffer/validity/dynamic_state.rs | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/src/command_buffer/validity/dynamic_state.rs b/src/command_buffer/validity/dynamic_state.rs new file mode 100644 index 0000000..f9a65ad --- /dev/null +++ b/src/command_buffer/validity/dynamic_state.rs @@ -0,0 +1,215 @@ +// 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 |