diff --git a/vulkano/src/command_buffer/auto/builder.rs b/vulkano/src/command_buffer/auto/builder.rs index fd03451dd5..43d80e896a 100644 --- a/vulkano/src/command_buffer/auto/builder.rs +++ b/vulkano/src/command_buffer/auto/builder.rs @@ -18,6 +18,7 @@ use crate::{ pipeline::{ graphics::{ color_blend::LogicOp, + conservative_rasterization::ConservativeRasterizationMode, depth_stencil::{CompareOp, StencilOps}, input_assembly::PrimitiveTopology, rasterization::{CullMode, DepthBiasState, FrontFace, LineStipple}, @@ -1207,6 +1208,9 @@ pub(in crate::command_buffer) struct CommandBufferBuilderState { pub(in crate::command_buffer) vertex_input: Option, pub(in crate::command_buffer) viewport: HashMap, pub(in crate::command_buffer) viewport_with_count: Option>, + pub(in crate::command_buffer) conservative_rasterization_mode: + Option, + pub(in crate::command_buffer) extra_primitive_overestimation_size: Option, // Active queries pub(in crate::command_buffer) queries: HashMap, @@ -1275,25 +1279,28 @@ impl CommandBufferBuilderState { // DynamicState::ColorBlendEquation => todo!(), // DynamicState::ColorWriteMask => todo!(), // DynamicState::RasterizationStream => todo!(), - // DynamicState::ConservativeRasterizationMode => todo!(), - // DynamicState::ExtraPrimitiveOverestimationSize => todo!(), - // DynamicState::DepthClipEnable => todo!(), - // DynamicState::SampleLocationsEnable => todo!(), - // DynamicState::ColorBlendAdvanced => todo!(), - // DynamicState::ProvokingVertexMode => todo!(), - // DynamicState::LineRasterizationMode => todo!(), - // DynamicState::LineStippleEnable => todo!(), - // DynamicState::DepthClipNegativeOneToOne => todo!(), - // DynamicState::ViewportWScalingEnable => todo!(), - // DynamicState::ViewportSwizzle => todo!(), - // DynamicState::CoverageToColorEnable => todo!(), - // DynamicState::CoverageToColorLocation => todo!(), - // DynamicState::CoverageModulationMode => todo!(), - // DynamicState::CoverageModulationTableEnable => todo!(), - // DynamicState::CoverageModulationTable => todo!(), - // DynamicState::ShadingRateImageEnable => todo!(), - // DynamicState::RepresentativeFragmentTestEnable => todo!(), - // DynamicState::CoverageReductionMode => todo!(), + DynamicState::ConservativeRasterizationMode => { + self.conservative_rasterization_mode = None + } + DynamicState::ExtraPrimitiveOverestimationSize => { + self.extra_primitive_overestimation_size = None + } /* DynamicState::DepthClipEnable => todo!(), + * DynamicState::SampleLocationsEnable => todo!(), + * DynamicState::ColorBlendAdvanced => todo!(), + * DynamicState::ProvokingVertexMode => todo!(), + * DynamicState::LineRasterizationMode => todo!(), + * DynamicState::LineStippleEnable => todo!(), + * DynamicState::DepthClipNegativeOneToOne => todo!(), + * DynamicState::ViewportWScalingEnable => todo!(), + * DynamicState::ViewportSwizzle => todo!(), + * DynamicState::CoverageToColorEnable => todo!(), + * DynamicState::CoverageToColorLocation => todo!(), + * DynamicState::CoverageModulationMode => todo!(), + * DynamicState::CoverageModulationTableEnable => todo!(), + * DynamicState::CoverageModulationTable => todo!(), + * DynamicState::ShadingRateImageEnable => todo!(), + * DynamicState::RepresentativeFragmentTestEnable => todo!(), + * DynamicState::CoverageReductionMode => todo!(), */ } } } diff --git a/vulkano/src/command_buffer/commands/dynamic_state.rs b/vulkano/src/command_buffer/commands/dynamic_state.rs index aae8ce6521..c95f18cc2d 100644 --- a/vulkano/src/command_buffer/commands/dynamic_state.rs +++ b/vulkano/src/command_buffer/commands/dynamic_state.rs @@ -4,6 +4,7 @@ use crate::{ pipeline::{ graphics::{ color_blend::LogicOp, + conservative_rasterization::ConservativeRasterizationMode, depth_stencil::{CompareOp, StencilFaces, StencilOp, StencilOps}, input_assembly::PrimitiveTopology, rasterization::{CullMode, DepthBiasState, FrontFace, LineStipple}, @@ -1196,6 +1197,91 @@ impl RecordingCommandBuffer { self } + + /// Sets the dynamic conservative rasterization mode for future draw calls. + #[inline] + pub fn set_conservative_rasterization_mode( + &mut self, + conservative_rasterization_mode: ConservativeRasterizationMode, + ) -> Result<&mut Self, Box> { + self.validate_set_conservative_rasterization_mode()?; + + unsafe { + Ok(self.set_conservative_rasterization_mode_unchecked(conservative_rasterization_mode)) + } + } + + fn validate_set_conservative_rasterization_mode(&self) -> Result<(), Box> { + self.inner.validate_set_conservative_rasterization_mode()?; + + self.validate_graphics_pipeline_fixed_state(DynamicState::ConservativeRasterizationMode)?; + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn set_conservative_rasterization_mode_unchecked( + &mut self, + conservative_rasterization_mode: ConservativeRasterizationMode, + ) -> &mut Self { + self.builder_state.conservative_rasterization_mode = Some(conservative_rasterization_mode); + + self.add_command( + "set_conservative_rasterization_mode", + Default::default(), + move |out: &mut RawRecordingCommandBuffer| { + out.set_conservative_rasterization_mode_unchecked(conservative_rasterization_mode); + }, + ); + + self + } + + /// Sets the dynamic extra primitive overestimation size for future draw calls. + #[inline] + pub fn set_extra_primitive_overestimation_size( + &mut self, + extra_primitive_overestimation_size: f32, + ) -> Result<&mut Self, Box> { + self.validate_set_extra_primitive_overestimation_size()?; + + unsafe { + Ok(self.set_extra_primitive_overestimation_size_unchecked( + extra_primitive_overestimation_size, + )) + } + } + + fn validate_set_extra_primitive_overestimation_size(&self) -> Result<(), Box> { + self.inner.validate_set_conservative_rasterization_mode()?; + + self.validate_graphics_pipeline_fixed_state( + DynamicState::ExtraPrimitiveOverestimationSize, + )?; + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn set_extra_primitive_overestimation_size_unchecked( + &mut self, + extra_primitive_overestimation_size: f32, + ) -> &mut Self { + self.builder_state.extra_primitive_overestimation_size = + Some(extra_primitive_overestimation_size); + + self.add_command( + "set_extra_primitive_overestimation_size", + Default::default(), + move |out: &mut RawRecordingCommandBuffer| { + out.set_extra_primitive_overestimation_size_unchecked( + extra_primitive_overestimation_size, + ); + }, + ); + + self + } } impl RawRecordingCommandBuffer { @@ -3186,4 +3272,144 @@ impl RawRecordingCommandBuffer { self } + + #[inline] + pub unsafe fn set_conservative_rasterization_mode( + &mut self, + conservative_rasterization_mode: ConservativeRasterizationMode, + ) -> Result<&mut Self, Box> { + self.validate_set_conservative_rasterization_mode()?; + + Ok(self.set_conservative_rasterization_mode_unchecked(conservative_rasterization_mode)) + } + + fn validate_set_conservative_rasterization_mode(&self) -> Result<(), Box> { + if !(self + .device() + .enabled_features() + .extended_dynamic_state3_conservative_rasterization_mode) + { + return Err(Box::new(ValidationError { + requires_one_of: RequiresOneOf(&[ + RequiresAllOf(&[Requires::DeviceFeature( + "extended_dynamic_state3_conservative_rasterization_mode", + )]), + RequiresAllOf(&[Requires::DeviceFeature("shader_object")]), + ]), + vuids: &["VUID-vkCmdSetConservativeRasterizationModeEXT-None-09423"], + ..Default::default() + })); + } + + if !self + .queue_family_properties() + .queue_flags + .intersects(QueueFlags::GRAPHICS) + { + return Err(Box::new(ValidationError { + problem: "the queue family of the command buffer does not support \ + graphics operations" + .into(), + vuids: &["VUID-vkCmdSetConservativeRasterizationModeEXT-commandBuffer-cmdpool"], + ..Default::default() + })); + } + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn set_conservative_rasterization_mode_unchecked( + &mut self, + conservative_rasterization_mode: ConservativeRasterizationMode, + ) -> &mut Self { + let fns = self.device().fns(); + (fns.ext_extended_dynamic_state3 + .cmd_set_conservative_rasterization_mode_ext)( + self.handle(), + conservative_rasterization_mode.into(), + ); + + self + } + + #[inline] + pub unsafe fn set_extra_primitive_overestimation_size( + &mut self, + extra_primitive_overestimation_size: f32, + ) -> Result<&mut Self, Box> { + self.validate_set_extra_primitive_overestimation_size(extra_primitive_overestimation_size)?; + + Ok(self + .set_extra_primitive_overestimation_size_unchecked(extra_primitive_overestimation_size)) + } + + fn validate_set_extra_primitive_overestimation_size( + &self, + extra_primitive_overestimation_size: f32, + ) -> Result<(), Box> { + let properties = self.device().physical_device().properties(); + + if !(self + .device() + .enabled_features() + .extended_dynamic_state3_extra_primitive_overestimation_size) + { + return Err(Box::new(ValidationError { + requires_one_of: RequiresOneOf(&[ + RequiresAllOf(&[Requires::DeviceFeature( + "extended_dynamic_state3_extra_primitive_overestimation_size", + )]), + RequiresAllOf(&[Requires::DeviceFeature("shader_object")]), + ]), + vuids: &["VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-None-09423"], + ..Default::default() + })); + } + + if !self + .queue_family_properties() + .queue_flags + .intersects(QueueFlags::GRAPHICS) + { + return Err(Box::new(ValidationError { + problem: "the queue family of the command buffer does not support \ + graphics operations" + .into(), + vuids: &["VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-commandBuffer-cmdpool"], + ..Default::default() + })); + } + + if extra_primitive_overestimation_size < 0.0 + || extra_primitive_overestimation_size + > properties.max_extra_primitive_overestimation_size.unwrap() + { + return Err(Box::new(ValidationError { + context: "overestimation size".into(), + problem: "the overestimation size is not in the range of 0.0 to `max_extra_primitive_overestimation_size` inclusive".into(), + vuids: &[ + "VUID-vkCmdSetExtraPrimitiveOverestimationSizeEXT-extraPrimitiveOverestimationSize-07428", + ], + ..Default::default() + })); + } + + Ok(()) + } + + #[cfg_attr(not(feature = "document_unchecked"), doc(hidden))] + pub unsafe fn set_extra_primitive_overestimation_size_unchecked( + &mut self, + extra_primitive_overestimation_size: f32, + ) -> &mut Self { + let fns = self.device().fns(); + (fns.ext_extended_dynamic_state3 + .cmd_set_extra_primitive_overestimation_size_ext)( + self.handle(), + extra_primitive_overestimation_size, + ); + + self + } } diff --git a/vulkano/src/command_buffer/commands/pipeline.rs b/vulkano/src/command_buffer/commands/pipeline.rs index df7519b941..0f2c374619 100644 --- a/vulkano/src/command_buffer/commands/pipeline.rs +++ b/vulkano/src/command_buffer/commands/pipeline.rs @@ -3219,6 +3219,43 @@ impl RecordingCommandBuffer { // the viewportCount parameter of // vkCmdSetViewportWithCountEXT must be 1 } + DynamicState::ConservativeRasterizationMode => { + if self.builder_state.conservative_rasterization_mode.is_none() { + return Err(Box::new(ValidationError { + problem: format!( + "the currently bound graphics pipeline requires the \ + `DynamicState::{:?}` dynamic state, but \ + this state was either not set, or it was overwritten by a \ + more recent `bind_pipeline_graphics` command", + dynamic_state + ) + .into(), + vuids: vuids!(vuid_type, "None-07631"), + ..Default::default() + })); + } + // TODO: VUID-vkCmdDraw-conservativePointAndLineRasterization-07499 + } + DynamicState::ExtraPrimitiveOverestimationSize => { + if self + .builder_state + .extra_primitive_overestimation_size + .is_none() + { + return Err(Box::new(ValidationError { + problem: format!( + "the currently bound graphics pipeline requires the \ + `DynamicState::{:?}` dynamic state, but \ + this state was either not set, or it was overwritten by a \ + more recent `bind_pipeline_graphics` command", + dynamic_state + ) + .into(), + vuids: vuids!(vuid_type, "None-07632"), + ..Default::default() + })); + } + } } } diff --git a/vulkano/src/pipeline/graphics/conservative_rasterization.rs b/vulkano/src/pipeline/graphics/conservative_rasterization.rs new file mode 100644 index 0000000000..5ead23ec0f --- /dev/null +++ b/vulkano/src/pipeline/graphics/conservative_rasterization.rs @@ -0,0 +1,90 @@ +//! A mode of rasterization where the edges of primitives are modified so that fragments are +//! generated if the edge of a primitive touches any part of a pixel, or if a pixel is fully +//! covered by a primitive. +use crate::{device::Device, macros::vulkan_enum, ValidationError}; + +/// The state in a graphics pipeline describing how the conservative rasterization mode should +/// behave. +#[derive(Clone, Debug)] +pub struct ConservativeRasterizationState { + /// Sets the conservative rasterization mode. + /// + /// The default value is [`ConservativeRasterizationMode::Disabled`]. + pub mode: ConservativeRasterizationMode, + + /// The extra size in pixels to increase the generating primitive during conservative + /// rasterization. If the mode is set to anything other than + /// [`ConservativeRasterizationMode::Overestimate`] this value is ignored. + /// + /// The default value is 0.0. + pub overestimation_size: f32, + + pub _ne: crate::NonExhaustive, +} + +impl Default for ConservativeRasterizationState { + #[inline] + fn default() -> Self { + Self { + mode: ConservativeRasterizationMode::Disabled, + overestimation_size: 0.0, + _ne: crate::NonExhaustive(()), + } + } +} + +impl ConservativeRasterizationState { + pub(crate) fn validate(&self, device: &Device) -> Result<(), Box> { + let &Self { + mode, + overestimation_size, + _ne: _, + } = self; + + let properties = device.physical_device().properties(); + + mode.validate_device(device).map_err(|err| { + err.add_context("mode").set_vuids(&[ + "VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-conservativeRasterizationMode-parameter", + ]) + })?; + + if overestimation_size < 0.0 + || overestimation_size > properties.max_extra_primitive_overestimation_size.unwrap() + { + return Err(Box::new(ValidationError { + context: "overestimation size".into(), + problem: "the overestimation size is not in the range of 0.0 to `max_extra_primitive_overestimation_size` inclusive".into(), + vuids: &[ + "VUID-VkPipelineRasterizationConservativeStateCreateInfoEXT-extraPrimitiveOverestimationSize-01769", + ], + ..Default::default() + })); + } + + Ok(()) + } +} + +vulkan_enum! { + #[non_exhaustive] + + /// Describes how fragments will be generated based on how much is covered by a primitive. + ConservativeRasterizationMode = ConservativeRasterizationModeEXT(i32); + + /// Conservative rasterization is disabled and rasterization proceeds as normal. + Disabled = DISABLED, + + /// Fragments will be generated if any part of a primitive touches a pixel. + Overestimate = OVERESTIMATE, + + /// Fragments will be generated only if a primitive completely covers a pixel. + Underestimate = UNDERESTIMATE, +} + +impl Default for ConservativeRasterizationMode { + #[inline] + fn default() -> ConservativeRasterizationMode { + ConservativeRasterizationMode::Disabled + } +} diff --git a/vulkano/src/pipeline/graphics/mod.rs b/vulkano/src/pipeline/graphics/mod.rs index 7196fae356..b08f506433 100644 --- a/vulkano/src/pipeline/graphics/mod.rs +++ b/vulkano/src/pipeline/graphics/mod.rs @@ -79,6 +79,7 @@ use self::{ color_blend::ColorBlendState, + conservative_rasterization::ConservativeRasterizationMode, depth_stencil::{DepthState, DepthStencilState}, discard_rectangle::DiscardRectangleState, input_assembly::{InputAssemblyState, PrimitiveTopology}, @@ -104,6 +105,7 @@ use crate::{ macros::impl_id_counter, pipeline::graphics::{ color_blend::ColorBlendAttachmentState, + conservative_rasterization::ConservativeRasterizationState, depth_stencil::{StencilOpState, StencilState}, rasterization::{CullMode, DepthBiasState}, subpass::PipelineRenderingCreateInfo, @@ -126,6 +128,7 @@ use std::{ }; pub mod color_blend; +pub mod conservative_rasterization; pub mod depth_stencil; pub mod discard_rectangle; pub mod input_assembly; @@ -163,6 +166,7 @@ pub struct GraphicsPipeline { subpass: PipelineSubpassType, discard_rectangle_state: Option, + conservative_rasterization_state: Option, descriptor_binding_requirements: HashMap<(u32, u32), DescriptorBindingRequirements>, num_used_descriptor_sets: u32, @@ -222,6 +226,7 @@ impl GraphicsPipeline { ref base_pipeline, ref discard_rectangle_state, + ref conservative_rasterization_state, _ne: _, } = &create_info; @@ -818,6 +823,25 @@ impl GraphicsPipeline { ); } + let mut conservative_rasterization_state_vk = None; + + if let Some(conservative_rasterization_state) = conservative_rasterization_state { + let ConservativeRasterizationState { + mode, + overestimation_size, + _ne: _, + } = conservative_rasterization_state; + + let _ = conservative_rasterization_state_vk.insert( + ash::vk::PipelineRasterizationConservativeStateCreateInfoEXT { + flags: ash::vk::PipelineRasterizationConservativeStateCreateFlagsEXT::empty(), + conservative_rasterization_mode: (*mode).into(), + extra_primitive_overestimation_size: *overestimation_size, + ..Default::default() + }, + ); + } + /* Create */ @@ -877,6 +901,11 @@ impl GraphicsPipeline { create_info_vk.p_next = info as *const _ as *const _; } + if let Some(info) = conservative_rasterization_state_vk.as_mut() { + info.p_next = create_info_vk.p_next; + create_info_vk.p_next = info as *const _ as *const _; + } + if let Some(info) = rendering_create_info_vk.as_mut() { info.p_next = create_info_vk.p_next; create_info_vk.p_next = info as *const _ as *const _; @@ -945,6 +974,7 @@ impl GraphicsPipeline { base_pipeline: _, discard_rectangle_state, + conservative_rasterization_state, _ne: _, } = create_info; @@ -1081,6 +1111,13 @@ impl GraphicsPipeline { fixed_state.extend([DynamicState::DiscardRectangle]); } + if conservative_rasterization_state.is_some() { + fixed_state.extend([ + DynamicState::ConservativeRasterizationMode, + DynamicState::ExtraPrimitiveOverestimationSize, + ]); + } + fixed_state.retain(|state| !dynamic_state.contains(state)); Arc::new(Self { @@ -1104,6 +1141,7 @@ impl GraphicsPipeline { subpass: subpass.unwrap(), discard_rectangle_state, + conservative_rasterization_state, descriptor_binding_requirements, num_used_descriptor_sets, @@ -1203,6 +1241,12 @@ impl GraphicsPipeline { self.discard_rectangle_state.as_ref() } + /// Returns the conservative rasterization state used to create this pipeline. + #[inline] + pub fn conservative_rasterization_state(&self) -> Option<&ConservativeRasterizationState> { + self.conservative_rasterization_state.as_ref() + } + /// If the pipeline has a fragment shader, returns the fragment tests stages used. #[inline] pub fn fragment_tests_stages(&self) -> Option { @@ -1395,6 +1439,11 @@ pub struct GraphicsPipelineCreateInfo { /// The default value is `None`. pub discard_rectangle_state: Option, + /// The conservative rasterization state. + /// + /// The default value is `None`. + pub conservative_rasterization_state: Option, + pub _ne: crate::NonExhaustive, } @@ -1421,6 +1470,7 @@ impl GraphicsPipelineCreateInfo { base_pipeline: None, discard_rectangle_state: None, + conservative_rasterization_state: None, _ne: crate::NonExhaustive(()), } } @@ -1445,6 +1495,7 @@ impl GraphicsPipelineCreateInfo { ref base_pipeline, ref discard_rectangle_state, + ref conservative_rasterization_state, _ne: _, } = self; @@ -2155,6 +2206,23 @@ impl GraphicsPipelineCreateInfo { .map_err(|err| err.add_context("discard_rectangle_state"))?; } + if let Some(conservative_rasterization_state) = conservative_rasterization_state { + if !device.enabled_extensions().ext_conservative_rasterization { + return Err(Box::new(ValidationError { + context: "conservative_rasterization_state".into(), + problem: "is `Some`".into(), + requires_one_of: RequiresOneOf(&[RequiresAllOf(&[Requires::DeviceExtension( + "ext_conservative_rasterization", + )])]), + ..Default::default() + })); + } + + conservative_rasterization_state + .validate(device) + .map_err(|err| err.add_context("conservative_rasterization_state"))?; + } + for dynamic_state in dynamic_state.iter().copied() { dynamic_state.validate_device(device).map_err(|err| { err.add_context("dynamic_state") @@ -2505,6 +2573,107 @@ impl GraphicsPipelineCreateInfo { } } + if let Some(conservative_rasterization_state) = conservative_rasterization_state { + let properties = device.physical_device().properties(); + + if matches!( + conservative_rasterization_state.mode, + ConservativeRasterizationMode::Disabled + ) && !properties + .conservative_point_and_line_rasterization + .unwrap_or(false) + { + if let (None, Some(input_assembly_state)) = (geometry_stage, input_assembly_state) { + if matches!( + input_assembly_state.topology, + PrimitiveTopology::PointList + | PrimitiveTopology::LineList + | PrimitiveTopology::LineStrip + ) && (!dynamic_state.contains(&DynamicState::PrimitiveTopology) + || match device + .physical_device() + .properties() + .dynamic_primitive_topology_unrestricted + { + Some(b) => !b, + None => false, + }) + { + return Err(Box::new(ValidationError { + problem: "`input_assembly_state.topology` is not compatible with the \ + conservative rasterization mode" + .into(), + vuids: &["VUID-VkGraphicsPipelineCreateInfo-conservativePointAndLineRasterization-08892"], + ..Default::default() + })); + } + } + + if let (Some(geometry_stage), Some(_)) = (geometry_stage, input_assembly_state) { + let spirv = geometry_stage.entry_point.module().spirv(); + let entry_point_function = spirv.function(geometry_stage.entry_point.id()); + + let invalid_output = + entry_point_function + .execution_modes() + .iter() + .any(|instruction| { + matches!( + instruction, + Instruction::ExecutionMode { + mode: ExecutionMode::OutputPoints + | ExecutionMode::OutputLineStrip, + .. + }, + ) + }); + + if invalid_output { + return Err(Box::new(ValidationError { + problem: "the output topology of the geometry shader is not compatible with the \ + conservative rasterization mode" + .into(), + vuids: &["VUID-VkGraphicsPipelineCreateInfo-conservativePointAndLineRasterization-06760"], + ..Default::default() + })); + } + } + + if let Some(mesh_stage) = mesh_stage { + let spirv = mesh_stage.entry_point.module().spirv(); + let entry_point_function = spirv.function(mesh_stage.entry_point.id()); + + let mut invalid_output = false; + + for instruction in entry_point_function.execution_modes() { + if let Instruction::ExecutionMode { mode, .. } = *instruction { + match mode { + ExecutionMode::OutputPoints => { + invalid_output = true; + break; + } + ExecutionMode::OutputLineStrip => { + invalid_output = true; + break; + } + _ => {} + } + } + } + + if invalid_output { + return Err(Box::new(ValidationError { + problem: "the output topology of the mesh shader is not compatible with the \ + conservative rasterization mode" + .into(), + vuids: &["VUID-VkGraphicsPipelineCreateInfo-conservativePointAndLineRasterization-06761"], + ..Default::default() + })); + } + } + } + } + if let (Some(fragment_stage), Some(color_blend_state), Some(subpass)) = (fragment_stage, color_blend_state, subpass) { diff --git a/vulkano/src/pipeline/mod.rs b/vulkano/src/pipeline/mod.rs index 57a011868c..1e094b6d24 100644 --- a/vulkano/src/pipeline/mod.rs +++ b/vulkano/src/pipeline/mod.rs @@ -730,19 +730,25 @@ vulkan_enum! { RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]), ]), */ - /* TODO: enable - // TODO: document + /// The value of + /// [`ConservativeRasterizationState::mode`](crate::pipeline::graphics::conservative_rasterization::ConservativeRasterizationState::mode) + /// + /// Set with + /// [`set_conservative_rasterization_mode`](crate::command_buffer::RecordingCommandBuffer::set_conservative_rasterization_mode). ConservativeRasterizationMode = CONSERVATIVE_RASTERIZATION_MODE_EXT RequiresOneOf([ RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]), - ]), */ + ]), - /* TODO: enable - // TODO: document + /// The value of + /// [`ConservativeRasterizationState::overestimation_size`](crate::pipeline::graphics::conservative_rasterization::ConservativeRasterizationState::overestimation_size) + /// + /// Set with + /// [`set_extra_primitive_overestimation_size`](crate::command_buffer::RecordingCommandBuffer::set_extra_primitive_overestimation_size). ExtraPrimitiveOverestimationSize = EXTRA_PRIMITIVE_OVERESTIMATION_SIZE_EXT RequiresOneOf([ RequiresAllOf([DeviceExtension(ext_extended_dynamic_state3)]), - ]), */ + ]), /* TODO: enable // TODO: document