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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! A test to discard pixels that would be written to certain areas of a framebuffer.
//!
//! The discard rectangle test is similar to, but separate from the scissor test.
use crate::{
device::Device, macros::vulkan_enum, pipeline::graphics::viewport::Scissor, ValidationError,
};
use smallvec::SmallVec;
/// The state in a graphics pipeline describing how the discard rectangle test should behave.
#[derive(Clone, Debug)]
pub struct DiscardRectangleState {
/// Sets whether the discard rectangle test operates inclusively or exclusively.
///
/// The default value is [`DiscardRectangleMode::Exclusive`].
pub mode: DiscardRectangleMode,
/// Specifies the discard rectangles.
///
/// When [`DynamicState::DiscardRectangle`] is used, the values of each rectangle are ignored
/// and must be set dynamically, but the number of discard rectangles is fixed and
/// must be matched when setting the dynamic value.
///
/// If this not not empty, then the
/// [`ext_discard_rectangles`](crate::device::DeviceExtensions::ext_discard_rectangles)
/// extension must be enabled on the device.
///
/// The default value is empty.
///
/// [`DynamicState::DiscardRectangle`]: crate::pipeline::DynamicState::DiscardRectangle
pub rectangles: Vec<Scissor>,
pub _ne: crate::NonExhaustive,
}
impl Default for DiscardRectangleState {
#[inline]
fn default() -> Self {
Self {
mode: DiscardRectangleMode::Exclusive,
rectangles: Vec::new(),
_ne: crate::NonExhaustive(()),
}
}
}
impl DiscardRectangleState {
/// Creates a `DiscardRectangleState` in exclusive mode with zero rectangles.
#[inline]
#[deprecated(
since = "0.34.0",
note = "use `DiscardRectangleState::default` instead"
)]
pub fn new() -> Self {
Self::default()
}
pub(crate) fn validate(&self, device: &Device) -> Result<(), Box<ValidationError>> {
let &Self {
mode,
ref rectangles,
_ne: _,
} = self;
let properties = device.physical_device().properties();
mode.validate_device(device).map_err(|err| {
err.add_context("mode").set_vuids(&[
"VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleMode-parameter",
])
})?;
if rectangles.len() as u32 > properties.max_discard_rectangles.unwrap() {
return Err(Box::new(ValidationError {
context: "rectangles".into(),
problem: "the length exceeds the `max_discard_rectangles` limit".into(),
vuids: &[
"VUID-VkPipelineDiscardRectangleStateCreateInfoEXT-discardRectangleCount-00582",
],
..Default::default()
}));
}
Ok(())
}
pub(crate) fn to_vk<'a>(
&self,
fields1_vk: &'a DiscardRectangleStateFields1Vk,
) -> ash::vk::PipelineDiscardRectangleStateCreateInfoEXT<'a> {
let &Self {
mode,
rectangles: _,
_ne: _,
} = self;
let DiscardRectangleStateFields1Vk {
discard_rectangles_vk,
} = fields1_vk;
ash::vk::PipelineDiscardRectangleStateCreateInfoEXT::default()
.flags(ash::vk::PipelineDiscardRectangleStateCreateFlagsEXT::empty())
.discard_rectangle_mode(mode.into())
.discard_rectangles(discard_rectangles_vk)
}
pub(crate) fn to_vk_fields1(&self) -> DiscardRectangleStateFields1Vk {
let Self {
mode: _,
rectangles,
_ne: _,
} = self;
let discard_rectangles_vk = rectangles.iter().map(|rect| rect.to_vk()).collect();
DiscardRectangleStateFields1Vk {
discard_rectangles_vk,
}
}
}
pub(crate) struct DiscardRectangleStateFields1Vk {
pub(crate) discard_rectangles_vk: SmallVec<[ash::vk::Rect2D; 2]>,
}
vulkan_enum! {
#[non_exhaustive]
/// The mode in which the discard rectangle test operates.
DiscardRectangleMode = DiscardRectangleModeEXT(i32);
/// Samples that are inside a rectangle are kept, samples that are outside all rectangles
/// are discarded.
Inclusive = INCLUSIVE,
/// Samples that are inside a rectangle are discarded, samples that are outside all rectangles
/// are kept.
Exclusive = EXCLUSIVE,
}