1 // Copyright (c) 2017 The vulkano developers
2 // Licensed under the Apache License, Version 2.0
3 // <LICENSE-APACHE or
4 // https://www.apache.org/licenses/LICENSE-2.0> or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>,
6 // at your option. All files in the project carrying such
7 // notice may not be copied, modified, or distributed except
8 // according to those terms.
9
10 use std::error;
11 use std::fmt;
12
13 use crate::command_buffer::DynamicState;
14 use crate::pipeline::GraphicsPipelineAbstract;
15
16 /// Checks whether states that are about to be set are correct.
check_dynamic_state_validity<Pl>( pipeline: &Pl, state: &DynamicState, ) -> Result<(), CheckDynamicStateValidityError> where Pl: GraphicsPipelineAbstract,17 pub fn check_dynamic_state_validity<Pl>(
18 pipeline: &Pl,
19 state: &DynamicState,
20 ) -> Result<(), CheckDynamicStateValidityError>
21 where
22 Pl: GraphicsPipelineAbstract,
23 {
24 let device = pipeline.device();
25
26 if pipeline.has_dynamic_line_width() {
27 if let Some(value) = state.line_width {
28 if value != 1.0 && !pipeline.device().enabled_features().wide_lines {
29 return Err(CheckDynamicStateValidityError::LineWidthMissingExtension);
30 }
31 } else {
32 return Err(CheckDynamicStateValidityError::LineWidthMissing);
33 }
34 } else {
35 if state.line_width.is_some() {
36 return Err(CheckDynamicStateValidityError::LineWidthNotDynamic);
37 }
38 }
39
40 if pipeline.has_dynamic_viewports() {
41 if let Some(ref viewports) = state.viewports {
42 if viewports.len() != pipeline.num_viewports() as usize {
43 return Err(CheckDynamicStateValidityError::ViewportsCountMismatch {
44 expected: pipeline.num_viewports() as usize,
45 obtained: viewports.len(),
46 });
47 }
48 } else {
49 return Err(CheckDynamicStateValidityError::ViewportsMissing);
50 }
51 } else {
52 if state.viewports.is_some() {
53 return Err(CheckDynamicStateValidityError::ViewportsNotDynamic);
54 }
55 }
56
57 if pipeline.has_dynamic_scissors() {
58 if let Some(ref scissors) = state.scissors {
59 if scissors.len() != pipeline.num_viewports() as usize {
60 return Err(CheckDynamicStateValidityError::ScissorsCountMismatch {
61 expected: pipeline.num_viewports() as usize,
62 obtained: scissors.len(),
63 });
64 }
65 } else {
66 return Err(CheckDynamicStateValidityError::ScissorsMissing);
67 }
68 } else {
69 if state.scissors.is_some() {
70 return Err(CheckDynamicStateValidityError::ScissorsNotDynamic);
71 }
72 }
73
74 if pipeline.has_dynamic_stencil_compare_mask() {
75 if let None = state.compare_mask {
76 return Err(CheckDynamicStateValidityError::CompareMaskMissing);
77 }
78 } else {
79 if state.compare_mask.is_some() {
80 return Err(CheckDynamicStateValidityError::CompareMaskNotDynamic);
81 }
82 }
83
84 if pipeline.has_dynamic_stencil_write_mask() {
85 if let None = state.write_mask {
86 return Err(CheckDynamicStateValidityError::WriteMaskMissing);
87 }
88 } else {
89 if state.write_mask.is_some() {
90 return Err(CheckDynamicStateValidityError::WriteMaskNotDynamic);
91 }
92 }
93
94 if pipeline.has_dynamic_stencil_reference() {
95 if let None = state.reference {
96 return Err(CheckDynamicStateValidityError::ReferenceMissing);
97 }
98 } else {
99 if state.reference.is_some() {
100 return Err(CheckDynamicStateValidityError::ReferenceNotDynamic);
101 }
102 }
103
104 Ok(())
105 }
106
107 /// Error that can happen when validating dynamic states.
108 #[derive(Debug, Copy, Clone)]
109 pub enum CheckDynamicStateValidityError {
110 /// Passed a dynamic line width, while the pipeline doesn't have line width set as dynamic.
111 LineWidthNotDynamic,
112 /// The pipeline has a dynamic line width, but no line width value was passed.
113 LineWidthMissing,
114 /// The `wide_lines` extension must be enabled in order to use line width values different
115 /// from 1.0.
116 LineWidthMissingExtension,
117 /// Passed dynamic viewports, while the pipeline doesn't have viewports set as dynamic.
118 ViewportsNotDynamic,
119 /// The pipeline has dynamic viewports, but no viewports were passed.
120 ViewportsMissing,
121 /// The number of dynamic viewports doesn't match the expected number of viewports.
122 ViewportsCountMismatch {
123 /// Expected number of viewports.
124 expected: usize,
125 /// Number of viewports that were passed.
126 obtained: usize,
127 },
128 /// Passed dynamic scissors, while the pipeline doesn't have scissors set as dynamic.
129 ScissorsNotDynamic,
130 /// The pipeline has dynamic scissors, but no scissors were passed.
131 ScissorsMissing,
132 /// The number of dynamic scissors doesn't match the expected number of scissors.
133 ScissorsCountMismatch {
134 /// Expected number of scissors.
135 expected: usize,
136 /// Number of scissors that were passed.
137 obtained: usize,
138 },
139 /// Passed dynamic compare mask, while the pipeline doesn't have the compare mask set as dynamic.
140 CompareMaskNotDynamic,
141 /// The pipeline has dynamic compare mask, but no compare mask was passed.
142 CompareMaskMissing,
143 /// Passed dynamic write mask, while the pipeline doesn't have the write mask set as dynamic.
144 WriteMaskNotDynamic,
145 /// The pipeline has dynamic write mask, but no write mask was passed.
146 WriteMaskMissing,
147 /// Passed dynamic reference, while the pipeline doesn't have the reference set as dynamic.
148 ReferenceNotDynamic,
149 /// The pipeline has dynamic reference, but no reference was passed.
150 ReferenceMissing,
151 }
152
153 impl error::Error for CheckDynamicStateValidityError {}
154
155 impl fmt::Display for CheckDynamicStateValidityError {
156 #[inline]
fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error>157 fn fmt(&self, fmt: &mut fmt::Formatter) -> Result<(), fmt::Error> {
158 write!(
159 fmt,
160 "{}",
161 match *self {
162 CheckDynamicStateValidityError::LineWidthNotDynamic => {
163 "passed a dynamic line width, while the pipeline doesn't have line width set as \
164 dynamic"
165 }
166 CheckDynamicStateValidityError::LineWidthMissing => {
167 "the pipeline has a dynamic line width, but no line width value was passed"
168 }
169 CheckDynamicStateValidityError::LineWidthMissingExtension => {
170 "the `wide_lines` extension must be enabled in order to use line width values \
171 different from 1.0"
172 }
173 CheckDynamicStateValidityError::ViewportsNotDynamic => {
174 "passed dynamic viewports, while the pipeline doesn't have viewports set as \
175 dynamic"
176 }
177 CheckDynamicStateValidityError::ViewportsMissing => {
178 "the pipeline has dynamic viewports, but no viewports were passed"
179 }
180 CheckDynamicStateValidityError::ViewportsCountMismatch { .. } => {
181 "the number of dynamic viewports doesn't match the expected number of viewports"
182 }
183 CheckDynamicStateValidityError::ScissorsNotDynamic => {
184 "passed dynamic scissors, while the pipeline doesn't have scissors set as dynamic"
185 }
186 CheckDynamicStateValidityError::ScissorsMissing => {
187 "the pipeline has dynamic scissors, but no scissors were passed"
188 }
189 CheckDynamicStateValidityError::ScissorsCountMismatch { .. } => {
190 "the number of dynamic scissors doesn't match the expected number of scissors"
191 }
192 CheckDynamicStateValidityError::CompareMaskNotDynamic => {
193 "passed dynamic compare mask, while the pipeline doesn't have compare mask set as dynamic"
194 }
195 CheckDynamicStateValidityError::CompareMaskMissing => {
196 "the pipeline has dynamic compare mask, but no compare mask was passed"
197 }
198 CheckDynamicStateValidityError::WriteMaskNotDynamic => {
199 "passed dynamic write mask, while the pipeline doesn't have write mask set as dynamic"
200 }
201 CheckDynamicStateValidityError::WriteMaskMissing => {
202 "the pipeline has dynamic write mask, but no write mask was passed"
203 }
204 CheckDynamicStateValidityError::ReferenceNotDynamic => {
205 "passed dynamic Reference, while the pipeline doesn't have reference set as dynamic"
206 }
207 CheckDynamicStateValidityError::ReferenceMissing => {
208 "the pipeline has dynamic reference, but no reference was passed"
209 }
210 }
211 )
212 }
213 }
214
215 // TODO: tests
216