| // Copyright (c) 2016 The vulkano developers |
| // Licensed under the Apache License, Version 2.0 |
| // <LICENSE-APACHE or |
| // https://www.apache.org/licenses/LICENSE-2.0> or the MIT |
| // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, |
| // at your option. All files in the project carrying such |
| // notice may not be copied, modified, or distributed except |
| // according to those terms. |
| |
| //! Configures how input vertices are assembled into primitives. |
| |
| use crate::{ |
| buffer::BufferContents, |
| macros::vulkan_enum, |
| pipeline::{PartialStateMode, StateMode}, |
| DeviceSize, |
| }; |
| |
| /// The state in a graphics pipeline describing how the input assembly stage should behave. |
| #[derive(Clone, Copy, Debug)] |
| pub struct InputAssemblyState { |
| /// The type of primitives. |
| /// |
| /// Note that some topologies require a feature to be enabled on the device. |
| /// |
| /// If set to `Dynamic`, the device API version must be at least 1.3, or the |
| /// [`extended_dynamic_state`](crate::device::Features::extended_dynamic_state) feature must be |
| /// enabled on the device. |
| pub topology: PartialStateMode<PrimitiveTopology, PrimitiveTopologyClass>, |
| |
| /// If true, then when drawing with an index buffer, the special index value consisting of the |
| /// maximum unsigned value (`0xff`, `0xffff` or `0xffffffff`) will tell the GPU that it is the |
| /// end of the current primitive. A new primitive will restart at the next index. |
| /// |
| /// Primitive restart is mostly useful in combination with "strip" and "fan" topologies. "List" |
| /// topologies require a feature to be enabled on the device when combined with primitive |
| /// restart. |
| /// |
| /// If set to `Dynamic`, the device API version must be at least 1.3, or the |
| /// [`extended_dynamic_state2`](crate::device::Features::extended_dynamic_state2) feature must |
| /// be enabled on the device. |
| pub primitive_restart_enable: StateMode<bool>, |
| } |
| |
| impl InputAssemblyState { |
| /// Creates an `InputAssemblyState` with the `TriangleList` topology and primitive restart |
| /// disabled. |
| #[inline] |
| pub fn new() -> Self { |
| Self { |
| topology: PartialStateMode::Fixed(PrimitiveTopology::TriangleList), |
| primitive_restart_enable: StateMode::Fixed(false), |
| } |
| } |
| |
| /// Sets the primitive topology. |
| #[inline] |
| pub fn topology(mut self, topology: PrimitiveTopology) -> Self { |
| self.topology = PartialStateMode::Fixed(topology); |
| self |
| } |
| |
| /// Sets the primitive topology to dynamic. |
| #[inline] |
| pub fn topology_dynamic(mut self, topology_class: PrimitiveTopologyClass) -> Self { |
| self.topology = PartialStateMode::Dynamic(topology_class); |
| self |
| } |
| |
| /// Enables primitive restart. |
| #[inline] |
| pub fn primitive_restart_enable(mut self) -> Self { |
| self.primitive_restart_enable = StateMode::Fixed(true); |
| self |
| } |
| |
| /// Sets primitive restart enable to dynmamic. |
| #[inline] |
| pub fn primitive_restart_enable_dynamic(mut self) -> Self { |
| self.primitive_restart_enable = StateMode::Dynamic; |
| self |
| } |
| } |
| |
| impl Default for InputAssemblyState { |
| /// Returns [`InputAssemblyState::new()`]. |
| #[inline] |
| fn default() -> Self { |
| Self::new() |
| } |
| } |
| |
| vulkan_enum! { |
| #[non_exhaustive] |
| |
| /// Describes how vertices must be grouped together to form primitives. |
| /// |
| /// When enabling primitive restart, "list" topologies require a feature to be enabled on the |
| /// device: |
| /// - The `PatchList` topology requires the |
| /// [`primitive_topology_patch_list_restart`](crate::device::Features::primitive_topology_patch_list_restart) |
| /// feature. |
| /// - All other "list" topologies require the |
| /// [`primitive_topology_list_restart`](crate::device::Features::primitive_topology_list_restart) |
| /// feature. |
| PrimitiveTopology impl { |
| /// Returns the topology class of this topology. |
| #[inline] |
| pub fn class(self) -> PrimitiveTopologyClass { |
| match self { |
| Self::PointList => PrimitiveTopologyClass::Point, |
| Self::LineList |
| | Self::LineStrip |
| | Self::LineListWithAdjacency |
| | Self::LineStripWithAdjacency => PrimitiveTopologyClass::Line, |
| Self::TriangleList |
| | Self::TriangleStrip |
| | Self::TriangleFan |
| | Self::TriangleListWithAdjacency |
| | Self::TriangleStripWithAdjacency => PrimitiveTopologyClass::Triangle, |
| Self::PatchList => PrimitiveTopologyClass::Patch, |
| } |
| } |
| } |
| = PrimitiveTopology(i32); |
| |
| /// A series of separate point primitives. |
| PointList = POINT_LIST, |
| |
| /// A series of separate line primitives. |
| LineList = LINE_LIST, |
| |
| /// A series of consecutive line primitives, with consecutive lines sharing a vertex. |
| LineStrip = LINE_STRIP, |
| |
| /// A series of separate triangle primitives. |
| TriangleList = TRIANGLE_LIST, |
| |
| /// A series of consecutive triangle primitives, with consecutive triangles sharing an edge (two vertices). |
| TriangleStrip = TRIANGLE_STRIP, |
| |
| /// A series of consecutive triangle primitives, with all triangles sharing a common vertex (the first). |
| /// |
| /// On [portability subset](crate::instance#portability-subset-devices-and-the-enumerate_portability-flag) |
| /// devices, the [`triangle_fans`](crate::device::Features::triangle_fans) |
| /// feature must be enabled on the device. |
| TriangleFan = TRIANGLE_FAN, |
| |
| /// As `LineList, but with adjacency, used in combination with geometry shaders. Requires the |
| /// [`geometry_shader`](crate::device::Features::geometry_shader) feature. |
| LineListWithAdjacency = LINE_LIST_WITH_ADJACENCY, |
| |
| /// As `LineStrip`, but with adjacency, used in combination with geometry shaders. Requires the |
| /// [`geometry_shader`](crate::device::Features::geometry_shader) feature. |
| LineStripWithAdjacency = LINE_STRIP_WITH_ADJACENCY, |
| |
| /// As `TriangleList`, but with adjacency, used in combination with geometry shaders. Requires |
| /// the [`geometry_shader`](crate::device::Features::geometry_shader) feature. |
| TriangleListWithAdjacency = TRIANGLE_LIST_WITH_ADJACENCY, |
| |
| /// As `TriangleStrip`, but with adjacency, used in combination with geometry shaders. Requires |
| /// the [`geometry_shader`](crate::device::Features::geometry_shader) feature. |
| TriangleStripWithAdjacency = TRIANGLE_STRIP_WITH_ADJACENCY, |
| |
| /// Separate patch primitives, used in combination with tessellation shaders. Requires the |
| /// [`tessellation_shader`](crate::device::Features::tessellation_shader) feature. |
| PatchList = PATCH_LIST, |
| |
| } |
| |
| // TODO: use the #[default] attribute once it's stable. |
| // See: https://github.com/rust-lang/rust/issues/87517 |
| impl Default for PrimitiveTopology { |
| #[inline] |
| fn default() -> Self { |
| PrimitiveTopology::TriangleList |
| } |
| } |
| |
| /// Describes the shape of a primitive topology. |
| #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
| pub enum PrimitiveTopologyClass { |
| Point, |
| Line, |
| Triangle, |
| Patch, |
| } |
| |
| impl PrimitiveTopologyClass { |
| /// Returns a representative example of this topology class. |
| pub(crate) fn example(self) -> PrimitiveTopology { |
| match self { |
| Self::Point => PrimitiveTopology::PointList, |
| Self::Line => PrimitiveTopology::LineList, |
| Self::Triangle => PrimitiveTopology::TriangleList, |
| Self::Patch => PrimitiveTopology::PatchList, |
| } |
| } |
| } |
| |
| /// Trait for types that can be used as indices by the GPU. |
| pub unsafe trait Index: BufferContents + Sized { |
| /// Returns the type of data. |
| fn ty() -> IndexType; |
| } |
| |
| unsafe impl Index for u8 { |
| #[inline(always)] |
| fn ty() -> IndexType { |
| IndexType::U8 |
| } |
| } |
| |
| unsafe impl Index for u16 { |
| #[inline(always)] |
| fn ty() -> IndexType { |
| IndexType::U16 |
| } |
| } |
| |
| unsafe impl Index for u32 { |
| #[inline(always)] |
| fn ty() -> IndexType { |
| IndexType::U32 |
| } |
| } |
| |
| vulkan_enum! { |
| #[non_exhaustive] |
| |
| /// An enumeration of all valid index types. |
| IndexType = IndexType(i32); |
| |
| // TODO: document |
| U8 = UINT8_EXT { |
| device_extensions: [ext_index_type_uint8], |
| }, |
| |
| // TODO: document |
| U16 = UINT16, |
| |
| // TODO: document |
| U32 = UINT32, |
| |
| /* TODO: enable |
| // TODO: document |
| None = NONE_KHR { |
| device_extensions: [khr_acceleration_structure, nv_ray_tracing], |
| },*/ |
| } |
| |
| impl IndexType { |
| /// Returns the size in bytes of indices of this type. |
| #[inline] |
| pub fn size(self) -> DeviceSize { |
| match self { |
| IndexType::U8 => 1, |
| IndexType::U16 => 2, |
| IndexType::U32 => 4, |
| } |
| } |
| } |