support for ext_conservative_rasterization (#2508)

* disabled bad validation code

* conservative rasterization

* validation for conservative_rasterization

* rebuild

* extra_primitive_overestimation_size dynamic state

* safety fixed

* set builder state

* formatted

* unfixed fake bug fix

* actually unfixed fake bug fix

* fixed bad formatting

* deleted duplicate todo

* command buffer documentation

* formatted

* add vuid

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* add vuid

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* more validation

* Update vulkano/src/pipeline/graphics/mod.rs

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* Update vulkano/src/pipeline/graphics/mod.rs

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* Update vulkano/src/pipeline/graphics/mod.rs

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* Update vulkano/src/pipeline/graphics/mod.rs

Co-authored-by: Rua <ruawhitepaw@gmail.com>

* put in block

* add todo

* fixed clippy

* removed redundant checks

---------

Co-authored-by: Rua <ruawhitepaw@gmail.com>
This commit is contained in:
Luke Powers 2024-03-29 14:54:44 -04:00 committed by GitHub
parent 78f3f9f508
commit 5dab2df966
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 560 additions and 25 deletions

View File

@ -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<VertexInputState>,
pub(in crate::command_buffer) viewport: HashMap<u32, Viewport>,
pub(in crate::command_buffer) viewport_with_count: Option<SmallVec<[Viewport; 2]>>,
pub(in crate::command_buffer) conservative_rasterization_mode:
Option<ConservativeRasterizationMode>,
pub(in crate::command_buffer) extra_primitive_overestimation_size: Option<f32>,
// Active queries
pub(in crate::command_buffer) queries: HashMap<QueryType, QueryState>,
@ -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!(), */
}
}
}

View File

@ -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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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<ValidationError>> {
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
}
}

View File

@ -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()
}));
}
}
}
}

View File

@ -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<ValidationError>> {
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
}
}

View File

@ -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<DiscardRectangleState>,
conservative_rasterization_state: Option<ConservativeRasterizationState>,
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<FragmentTestsStages> {
@ -1395,6 +1439,11 @@ pub struct GraphicsPipelineCreateInfo {
/// The default value is `None`.
pub discard_rectangle_state: Option<DiscardRectangleState>,
/// The conservative rasterization state.
///
/// The default value is `None`.
pub conservative_rasterization_state: Option<ConservativeRasterizationState>,
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)
{

View File

@ -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