1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::device::Device;
use crate::pipeline::graphics::input_assembly::{
InputAssemblyState, PrimitiveTopology, PrimitiveTopologyClass,
};
use crate::pipeline::graphics::GraphicsPipelineCreationError;
use crate::pipeline::{DynamicState, PartialStateMode, StateMode};
use std::collections::HashMap;
#[derive(Clone, Copy, Debug)]
pub struct TessellationState {
pub patch_control_points: StateMode<u32>,
}
impl TessellationState {
#[inline]
pub fn new() -> Self {
Self {
patch_control_points: StateMode::Fixed(3),
}
}
#[inline]
pub fn patch_control_points(mut self, num: u32) -> Self {
self.patch_control_points = StateMode::Fixed(num);
self
}
pub fn patch_control_points_dynamic(mut self) -> Self {
self.patch_control_points = StateMode::Dynamic;
self
}
pub(crate) fn to_vulkan(
&self,
device: &Device,
dynamic_state_modes: &mut HashMap<DynamicState, bool>,
input_assembly_state: &InputAssemblyState,
) -> Result<ash::vk::PipelineTessellationStateCreateInfo, GraphicsPipelineCreationError> {
if !matches!(
input_assembly_state.topology,
PartialStateMode::Dynamic(PrimitiveTopologyClass::Patch)
| PartialStateMode::Fixed(PrimitiveTopology::PatchList)
) {
return Err(GraphicsPipelineCreationError::InvalidPrimitiveTopology);
}
let patch_control_points = match self.patch_control_points {
StateMode::Fixed(patch_control_points) => {
if patch_control_points <= 0
|| patch_control_points
> device
.physical_device()
.properties()
.max_tessellation_patch_size
{
return Err(GraphicsPipelineCreationError::InvalidNumPatchControlPoints);
}
dynamic_state_modes.insert(DynamicState::PatchControlPoints, false);
patch_control_points
}
StateMode::Dynamic => {
if !device
.enabled_features()
.extended_dynamic_state2_patch_control_points
{
return Err(GraphicsPipelineCreationError::FeatureNotEnabled {
feature: "extended_dynamic_state2_patch_control_points",
reason: "TessellationState::patch_control_points was set to Dynamic",
});
}
dynamic_state_modes.insert(DynamicState::PatchControlPoints, true);
Default::default()
}
};
Ok(ash::vk::PipelineTessellationStateCreateInfo {
flags: ash::vk::PipelineTessellationStateCreateFlags::empty(),
patch_control_points,
..Default::default()
})
}
}
impl Default for TessellationState {
#[inline]
fn default() -> Self {
Self::new()
}
}