• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 input vertices are assembled into primitives.
11 
12 use crate::{
13     buffer::BufferContents,
14     macros::vulkan_enum,
15     pipeline::{PartialStateMode, StateMode},
16     DeviceSize,
17 };
18 
19 /// The state in a graphics pipeline describing how the input assembly stage should behave.
20 #[derive(Clone, Copy, Debug)]
21 pub struct InputAssemblyState {
22     /// The type of primitives.
23     ///
24     /// Note that some topologies require a feature to be enabled on the device.
25     ///
26     /// If set to `Dynamic`, the device API version must be at least 1.3, or the
27     /// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be
28     /// enabled on the device.
29     pub topology: PartialStateMode<PrimitiveTopology, PrimitiveTopologyClass>,
30 
31     /// If true, then when drawing with an index buffer, the special index value consisting of the
32     /// maximum unsigned value (`0xff`, `0xffff` or `0xffffffff`) will tell the GPU that it is the
33     /// end of the current primitive. A new primitive will restart at the next index.
34     ///
35     /// Primitive restart is mostly useful in combination with "strip" and "fan" topologies. "List"
36     /// topologies require a feature to be enabled on the device when combined with primitive
37     /// restart.
38     ///
39     /// If set to `Dynamic`, the device API version must be at least 1.3, or the
40     /// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must
41     /// be enabled on the device.
42     pub primitive_restart_enable: StateMode<bool>,
43 }
44 
45 impl InputAssemblyState {
46     /// Creates an `InputAssemblyState` with the `TriangleList` topology and primitive restart
47     /// disabled.
48     #[inline]
new() -> Self49     pub fn new() -> Self {
50         Self {
51             topology: PartialStateMode::Fixed(PrimitiveTopology::TriangleList),
52             primitive_restart_enable: StateMode::Fixed(false),
53         }
54     }
55 
56     /// Sets the primitive topology.
57     #[inline]
topology(mut self, topology: PrimitiveTopology) -> Self58     pub fn topology(mut self, topology: PrimitiveTopology) -> Self {
59         self.topology = PartialStateMode::Fixed(topology);
60         self
61     }
62 
63     /// Sets the primitive topology to dynamic.
64     #[inline]
topology_dynamic(mut self, topology_class: PrimitiveTopologyClass) -> Self65     pub fn topology_dynamic(mut self, topology_class: PrimitiveTopologyClass) -> Self {
66         self.topology = PartialStateMode::Dynamic(topology_class);
67         self
68     }
69 
70     /// Enables primitive restart.
71     #[inline]
primitive_restart_enable(mut self) -> Self72     pub fn primitive_restart_enable(mut self) -> Self {
73         self.primitive_restart_enable = StateMode::Fixed(true);
74         self
75     }
76 
77     /// Sets primitive restart enable to dynmamic.
78     #[inline]
primitive_restart_enable_dynamic(mut self) -> Self79     pub fn primitive_restart_enable_dynamic(mut self) -> Self {
80         self.primitive_restart_enable = StateMode::Dynamic;
81         self
82     }
83 }
84 
85 impl Default for InputAssemblyState {
86     /// Returns [`InputAssemblyState::new()`].
87     #[inline]
default() -> Self88     fn default() -> Self {
89         Self::new()
90     }
91 }
92 
93 vulkan_enum! {
94     #[non_exhaustive]
95 
96     /// Describes how vertices must be grouped together to form primitives.
97     ///
98     /// When enabling primitive restart, "list" topologies require a feature to be enabled on the
99     /// device:
100     /// - The `PatchList` topology requires the
101     ///   [`primitive_topology_patch_list_restart`](crate::device::Features::primitive_topology_patch_list_restart)
102     ///   feature.
103     /// - All other "list" topologies require the
104     ///   [`primitive_topology_list_restart`](crate::device::Features::primitive_topology_list_restart)
105     ///   feature.
106     PrimitiveTopology impl {
107         /// Returns the topology class of this topology.
108         #[inline]
109         pub fn class(self) -> PrimitiveTopologyClass {
110             match self {
111                 Self::PointList => PrimitiveTopologyClass::Point,
112                 Self::LineList
113                 | Self::LineStrip
114                 | Self::LineListWithAdjacency
115                 | Self::LineStripWithAdjacency => PrimitiveTopologyClass::Line,
116                 Self::TriangleList
117                 | Self::TriangleStrip
118                 | Self::TriangleFan
119                 | Self::TriangleListWithAdjacency
120                 | Self::TriangleStripWithAdjacency => PrimitiveTopologyClass::Triangle,
121                 Self::PatchList => PrimitiveTopologyClass::Patch,
122             }
123         }
124     }
125     = PrimitiveTopology(i32);
126 
127     /// A series of separate point primitives.
128     PointList = POINT_LIST,
129 
130     /// A series of separate line primitives.
131     LineList = LINE_LIST,
132 
133     /// A series of consecutive line primitives, with consecutive lines sharing a vertex.
134     LineStrip = LINE_STRIP,
135 
136     /// A series of separate triangle primitives.
137     TriangleList = TRIANGLE_LIST,
138 
139     /// A series of consecutive triangle primitives, with consecutive triangles sharing an edge (two vertices).
140     TriangleStrip = TRIANGLE_STRIP,
141 
142     /// A series of consecutive triangle primitives, with all triangles sharing a common vertex (the first).
143     ///
144     /// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag)
145     /// devices, the [`triangle_fans`](crate::device::Features::triangle_fans)
146     /// feature must be enabled on the device.
147     TriangleFan = TRIANGLE_FAN,
148 
149     /// As `LineList, but with adjacency, used in combination with geometry shaders. Requires the
150     /// [`geometry_shader`](crate::device::Features::geometry_shader) feature.
151     LineListWithAdjacency = LINE_LIST_WITH_ADJACENCY,
152 
153     /// As `LineStrip`, but with adjacency, used in combination with geometry shaders. Requires the
154     /// [`geometry_shader`](crate::device::Features::geometry_shader) feature.
155     LineStripWithAdjacency = LINE_STRIP_WITH_ADJACENCY,
156 
157     /// As `TriangleList`, but with adjacency, used in combination with geometry shaders. Requires
158     /// the [`geometry_shader`](crate::device::Features::geometry_shader) feature.
159     TriangleListWithAdjacency = TRIANGLE_LIST_WITH_ADJACENCY,
160 
161     /// As `TriangleStrip`, but with adjacency, used in combination with geometry shaders. Requires
162     /// the [`geometry_shader`](crate::device::Features::geometry_shader) feature.
163     TriangleStripWithAdjacency = TRIANGLE_STRIP_WITH_ADJACENCY,
164 
165     /// Separate patch primitives, used in combination with tessellation shaders. Requires the
166     /// [`tessellation_shader`](crate::device::Features::tessellation_shader) feature.
167     PatchList = PATCH_LIST,
168 
169 }
170 
171 // TODO: use the #[default] attribute once it's stable.
172 // See: https://github.com/rust-lang/rust/issues/87517
173 impl Default for PrimitiveTopology {
174     #[inline]
default() -> Self175     fn default() -> Self {
176         PrimitiveTopology::TriangleList
177     }
178 }
179 
180 /// Describes the shape of a primitive topology.
181 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
182 pub enum PrimitiveTopologyClass {
183     Point,
184     Line,
185     Triangle,
186     Patch,
187 }
188 
189 impl PrimitiveTopologyClass {
190     /// Returns a representative example of this topology class.
example(self) -> PrimitiveTopology191     pub(crate) fn example(self) -> PrimitiveTopology {
192         match self {
193             Self::Point => PrimitiveTopology::PointList,
194             Self::Line => PrimitiveTopology::LineList,
195             Self::Triangle => PrimitiveTopology::TriangleList,
196             Self::Patch => PrimitiveTopology::PatchList,
197         }
198     }
199 }
200 
201 /// Trait for types that can be used as indices by the GPU.
202 pub unsafe trait Index: BufferContents + Sized {
203     /// Returns the type of data.
ty() -> IndexType204     fn ty() -> IndexType;
205 }
206 
207 unsafe impl Index for u8 {
208     #[inline(always)]
ty() -> IndexType209     fn ty() -> IndexType {
210         IndexType::U8
211     }
212 }
213 
214 unsafe impl Index for u16 {
215     #[inline(always)]
ty() -> IndexType216     fn ty() -> IndexType {
217         IndexType::U16
218     }
219 }
220 
221 unsafe impl Index for u32 {
222     #[inline(always)]
ty() -> IndexType223     fn ty() -> IndexType {
224         IndexType::U32
225     }
226 }
227 
228 vulkan_enum! {
229     #[non_exhaustive]
230 
231     /// An enumeration of all valid index types.
232     IndexType = IndexType(i32);
233 
234     // TODO: document
235     U8 = UINT8_EXT {
236         device_extensions: [ext_index_type_uint8],
237     },
238 
239     // TODO: document
240     U16 = UINT16,
241 
242     // TODO: document
243     U32 = UINT32,
244 
245     /* TODO: enable
246     // TODO: document
247     None = NONE_KHR {
248         device_extensions: [khr_acceleration_structure, nv_ray_tracing],
249     },*/
250 }
251 
252 impl IndexType {
253     /// Returns the size in bytes of indices of this type.
254     #[inline]
size(self) -> DeviceSize255     pub fn size(self) -> DeviceSize {
256         match self {
257             IndexType::U8 => 1,
258             IndexType::U16 => 2,
259             IndexType::U32 => 4,
260         }
261     }
262 }
263