1 // Copyright (c) 2016 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 //! Configures how primitives should be converted into collections of fragments. 11 12 use crate::{macros::vulkan_enum, pipeline::StateMode}; 13 14 /// The state in a graphics pipeline describing how the rasterization stage should behave. 15 #[derive(Clone, Debug)] 16 pub struct RasterizationState { 17 /// If true, then the depth value of the vertices will be clamped to the range [0.0, 1.0]. If 18 /// false, fragments whose depth is outside of this range will be discarded. 19 /// 20 /// If enabled, the [`depth_clamp`](crate::device::Features::depth_clamp) feature must be 21 /// enabled on the device. 22 pub depth_clamp_enable: bool, 23 24 /// If true, all the fragments will be discarded, and the fragment shader will not be run. This 25 /// is usually used when your vertex shader has some side effects and you don't need to run the 26 /// fragment shader. 27 /// 28 /// If set to `Dynamic`, the device API version must be at least 1.3, or the 29 /// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must 30 /// be enabled on the device. 31 pub rasterizer_discard_enable: StateMode<bool>, 32 33 /// This setting can ask the rasterizer to downgrade triangles into lines or points, or lines 34 /// into points. 35 /// 36 /// If set to a value other than `Fill`, the 37 /// [`fill_mode_non_solid`](crate::device::Features::fill_mode_non_solid) feature must be 38 /// enabled on the device. 39 pub polygon_mode: PolygonMode, 40 41 /// Specifies whether front faces or back faces should be discarded, or none, or both. 42 /// 43 /// If set to `Dynamic`, the device API version must be at least 1.3, or the 44 /// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be 45 /// enabled on the device. 46 pub cull_mode: StateMode<CullMode>, 47 48 /// Specifies which triangle orientation is considered to be the front of the triangle. 49 /// 50 /// If set to `Dynamic`, the device API version must be at least 1.3, or the 51 /// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be 52 /// enabled on the device. 53 pub front_face: StateMode<FrontFace>, 54 55 /// Sets how to modify depth values in the rasterization stage. 56 /// 57 /// If set to `None`, depth biasing is disabled, the depth values will pass to the fragment 58 /// shader unmodified. 59 pub depth_bias: Option<DepthBiasState>, 60 61 /// Width, in pixels, of lines when drawing lines. 62 /// 63 /// Setting this to a value other than 1.0 requires the 64 /// [`wide_lines`](crate::device::Features::wide_lines) feature to be enabled on 65 /// the device. 66 pub line_width: StateMode<f32>, 67 68 /// The rasterization mode for lines. 69 /// 70 /// If this is not set to `Default`, the 71 /// [`ext_line_rasterization`](crate::device::DeviceExtensions::ext_line_rasterization) 72 /// extension and an additional feature must be enabled on the device. 73 pub line_rasterization_mode: LineRasterizationMode, 74 75 /// Enables and sets the parameters for line stippling. 76 /// 77 /// If this is set to `Some`, the 78 /// [`ext_line_rasterization`](crate::device::DeviceExtensions::ext_line_rasterization) 79 /// extension and an additional feature must be enabled on the device. 80 pub line_stipple: Option<StateMode<LineStipple>>, 81 } 82 83 impl RasterizationState { 84 /// Creates a `RasterizationState` with depth clamping, discard, depth biasing and line 85 /// stippling disabled, filled polygons, no culling, counterclockwise front face, and the 86 /// default line width and line rasterization mode. 87 #[inline] new() -> Self88 pub fn new() -> Self { 89 Self { 90 depth_clamp_enable: false, 91 rasterizer_discard_enable: StateMode::Fixed(false), 92 polygon_mode: Default::default(), 93 cull_mode: StateMode::Fixed(Default::default()), 94 front_face: StateMode::Fixed(Default::default()), 95 depth_bias: None, 96 line_width: StateMode::Fixed(1.0), 97 line_rasterization_mode: Default::default(), 98 line_stipple: None, 99 } 100 } 101 102 /// Sets the polygon mode. 103 #[inline] polygon_mode(mut self, polygon_mode: PolygonMode) -> Self104 pub fn polygon_mode(mut self, polygon_mode: PolygonMode) -> Self { 105 self.polygon_mode = polygon_mode; 106 self 107 } 108 109 /// Sets the cull mode. 110 #[inline] cull_mode(mut self, cull_mode: CullMode) -> Self111 pub fn cull_mode(mut self, cull_mode: CullMode) -> Self { 112 self.cull_mode = StateMode::Fixed(cull_mode); 113 self 114 } 115 116 /// Sets the cull mode to dynamic. 117 #[inline] cull_mode_dynamic(mut self) -> Self118 pub fn cull_mode_dynamic(mut self) -> Self { 119 self.cull_mode = StateMode::Dynamic; 120 self 121 } 122 123 /// Sets the front face. 124 #[inline] front_face(mut self, front_face: FrontFace) -> Self125 pub fn front_face(mut self, front_face: FrontFace) -> Self { 126 self.front_face = StateMode::Fixed(front_face); 127 self 128 } 129 130 /// Sets the front face to dynamic. 131 #[inline] front_face_dynamic(mut self) -> Self132 pub fn front_face_dynamic(mut self) -> Self { 133 self.front_face = StateMode::Dynamic; 134 self 135 } 136 } 137 138 impl Default for RasterizationState { 139 /// Returns [`RasterizationState::new()`]. 140 #[inline] default() -> Self141 fn default() -> Self { 142 Self::new() 143 } 144 } 145 146 /// The state in a graphics pipeline describing how depth biasing should behave when enabled. 147 #[derive(Clone, Copy, Debug)] 148 pub struct DepthBiasState { 149 /// Sets whether depth biasing should be enabled and disabled dynamically. If set to `false`, 150 /// depth biasing is always enabled. 151 /// 152 /// If set to `true`, the 153 /// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must 154 /// be enabled on the device. 155 pub enable_dynamic: bool, 156 157 /// The values to use when depth biasing is enabled. 158 pub bias: StateMode<DepthBias>, 159 } 160 161 /// The values to use for depth biasing. 162 #[derive(Clone, Copy, Debug)] 163 pub struct DepthBias { 164 /// Specifies a constant factor to be added to every depth value. 165 pub constant_factor: f32, 166 167 /// The maximum (or minimum) depth bias of a fragment. 168 /// 169 /// Setting this to a value other than 0.0 requires the 170 /// [`depth_bias_clamp`](crate::device::Features::depth_bias_clamp) feature to be enabled on 171 /// the device. 172 pub clamp: f32, 173 174 /// A scalar factor applied to a fragment's slope in depth bias calculations. 175 pub slope_factor: f32, 176 } 177 178 vulkan_enum! { 179 #[non_exhaustive] 180 181 /// Specifies the culling mode. 182 /// 183 /// This setting works in pair with `front_face`. The `front_face` setting tells the GPU whether 184 /// clockwise or counter-clockwise correspond to the front and the back of each triangle. Then 185 /// `cull_mode` lets you specify whether front faces should be discarded, back faces should be 186 /// discarded, or none, or both. 187 CullMode = CullModeFlags(u32); 188 189 /// No culling. 190 None = NONE, 191 192 /// The faces facing the front of the screen (ie. facing the user) will be removed. 193 Front = FRONT, 194 195 /// The faces facing the back of the screen will be removed. 196 Back = BACK, 197 198 /// All faces will be removed. 199 FrontAndBack = FRONT_AND_BACK, 200 } 201 202 impl Default for CullMode { 203 #[inline] default() -> CullMode204 fn default() -> CullMode { 205 CullMode::None 206 } 207 } 208 209 vulkan_enum! { 210 #[non_exhaustive] 211 212 /// Specifies which triangle orientation corresponds to the front or the triangle. 213 FrontFace = FrontFace(i32); 214 215 /// Triangles whose vertices are oriented counter-clockwise on the screen will be considered 216 /// as facing their front. Otherwise they will be considered as facing their back. 217 CounterClockwise = COUNTER_CLOCKWISE, 218 219 220 /// Triangles whose vertices are oriented clockwise on the screen will be considered 221 /// as facing their front. Otherwise they will be considered as facing their back. 222 Clockwise = CLOCKWISE, 223 } 224 225 impl Default for FrontFace { 226 #[inline] default() -> FrontFace227 fn default() -> FrontFace { 228 FrontFace::CounterClockwise 229 } 230 } 231 232 vulkan_enum! { 233 #[non_exhaustive] 234 235 // TODO: document 236 PolygonMode = PolygonMode(i32); 237 238 // TODO: document 239 Fill = FILL, 240 241 // TODO: document 242 Line = LINE, 243 244 // TODO: document further 245 /// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) 246 /// devices, unless `rasterizer_discard_enable` is active, the 247 /// [`point_polygons`](crate::device::Features::point_polygons) 248 /// feature must be enabled on the device. 249 Point = POINT, 250 251 /* TODO: enable 252 // TODO: document 253 FillRectangle = FILL_RECTANGLE_NV { 254 device_extensions: [nv_fill_rectangle], 255 },*/ 256 } 257 258 impl Default for PolygonMode { 259 #[inline] default() -> PolygonMode260 fn default() -> PolygonMode { 261 PolygonMode::Fill 262 } 263 } 264 265 vulkan_enum! { 266 #[non_exhaustive] 267 268 /// The rasterization mode to use for lines. 269 LineRasterizationMode = LineRasterizationModeEXT(i32); 270 271 /// If the [`strict_lines`](crate::device::Properties::strict_lines) device property is `true`, 272 /// then this is the same as `Rectangular`. Otherwise, lines are drawn as parallelograms. 273 /// 274 /// If [`RasterizationState::line_stipple`] is `Some`, then the 275 /// [`strict_lines`](crate::device::Properties::strict_lines) property must be `true` and the 276 /// [`stippled_rectangular_lines`](crate::device::Features::stippled_rectangular_lines) feature 277 /// must be enabled on the device. 278 Default = DEFAULT, 279 280 /// Lines are drawn as if they were rectangles extruded from the line. 281 /// 282 /// The [`rectangular_lines`](crate::device::Features::rectangular_lines) feature must be 283 /// enabled on the device. If [`RasterizationState::line_stipple`] is `Some`, then the 284 /// [`stippled_rectangular_lines`](crate::device::Features::stippled_rectangular_lines) must 285 /// also be enabled. 286 Rectangular = RECTANGULAR, 287 288 /// Lines are drawn by determining which pixel diamonds the line intersects and exits. 289 /// 290 /// The [`bresenham_lines`](crate::device::Features::bresenham_lines) feature must be 291 /// enabled on the device. If [`RasterizationState::line_stipple`] is `Some`, then the 292 /// [`stippled_bresenham_lines`](crate::device::Features::stippled_bresenham_lines) must 293 /// also be enabled. 294 Bresenham = BRESENHAM, 295 296 /// As `Rectangular`, but with alpha falloff. 297 /// 298 /// The [`smooth_lines`](crate::device::Features::smooth_lines) feature must be 299 /// enabled on the device. If [`RasterizationState::line_stipple`] is `Some`, then the 300 /// [`stippled_smooth_lines`](crate::device::Features::stippled_smooth_lines) must 301 /// also be enabled. 302 RectangularSmooth = RECTANGULAR_SMOOTH, 303 } 304 305 impl Default for LineRasterizationMode { 306 /// Returns `LineRasterizationMode::Default`. 307 #[inline] default() -> Self308 fn default() -> Self { 309 Self::Default 310 } 311 } 312 313 /// The parameters of a stippled line. 314 #[derive(Clone, Copy, Debug)] 315 pub struct LineStipple { 316 /// The repeat factor used in stippled line rasterization. Must be between 1 and 256 inclusive. 317 pub factor: u32, 318 /// The bit pattern used in stippled line rasterization. 319 pub pattern: u16, 320 } 321