Skip to main content

molgfx_gpu/
capabilities.rs

1//! Device capability flags.
2//!
3//! The renderer branches on these flags, never on backend identity. Every
4//! capability buys speed or a quality ceiling, never correctness: for each
5//! flag there is a fallback path that renders the same content.
6
7bitflags::bitflags! {
8    /// The boolean capabilities, as one word.
9    #[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
10    pub struct CapabilityFlags: u32 {
11        /// Hardware acceleration structures and WGSL ray queries.
12        const RAY_QUERY = 1;
13        /// Mesh shading pipeline.
14        const MESH_SHADERS = 1 << 1;
15        /// Unbounded descriptor arrays.
16        const BINDLESS = 1 << 2;
17        /// GPU timestamp queries for profiling.
18        const TIMESTAMP_QUERIES = 1 << 3;
19        /// Subgroup (wave/warp) operations in compute.
20        const SUBGROUP_OPS = 1 << 4;
21        /// A depth texture may be a read-only attachment and a bound texture in
22        /// one pass. Without it a pass that samples depth cannot also test
23        /// against it, and reads a copy instead.
24        const DEPTH_READ_WHILE_SAMPLED = 1 << 5;
25    }
26}
27
28/// Renderer-relevant usage support for one texture format.
29#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
30pub struct TextureFormatCapabilities {
31    /// The format may be bound as a sampled texture.
32    pub sampled: bool,
33    /// The format may be bound as a write-only storage texture.
34    pub storage_write: bool,
35}
36
37/// What the opened device can do beyond the baseline.
38#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
39pub struct Capabilities {
40    /// The boolean capabilities.
41    pub flags: CapabilityFlags,
42    /// Required byte alignment for a uniform-buffer binding offset.
43    pub min_uniform_buffer_offset_alignment: u32,
44    /// Largest single storage buffer binding, bytes.
45    pub max_storage_buffer_bytes: u64,
46    /// Maximum storage-buffer bindings visible to one shader stage.
47    pub max_storage_buffers_per_shader_stage: u32,
48    /// Largest 2-D texture dimension, texels.
49    pub max_texture_dim: u32,
50    /// Largest 3-D texture dimension, texels.
51    pub max_texture_dim_3d: u32,
52    /// `r32float` sampling and storage-write support.
53    pub r32float: TextureFormatCapabilities,
54    /// `rg32float` sampling and storage-write support.
55    pub rg32float: TextureFormatCapabilities,
56    /// `rgba32float` sampling and storage-write support.
57    pub rgba32float: TextureFormatCapabilities,
58}
59
60/// Device ceilings relevant to acceleration-structure allocation.
61#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
62pub struct RayQueryLimits {
63    /// Maximum primitives in one BLAS.
64    pub max_blas_primitives: u32,
65    /// Maximum geometry groups in one BLAS.
66    pub max_blas_geometries: u32,
67    /// Maximum instances in one TLAS.
68    pub max_tlas_instances: u32,
69    /// Maximum acceleration-structure bindings visible to one shader stage.
70    pub max_bindings_per_shader_stage: u32,
71}
72
73impl Capabilities {
74    /// Hardware acceleration-structure traversal is available.
75    ///
76    /// This is a resource capability, not evidence that a renderer has wired
77    /// a complete hardware quality path.
78    #[must_use]
79    pub fn hardware_ray_tracing(&self) -> bool {
80        self.ray_query()
81    }
82
83    /// Hardware acceleration structures and WGSL ray queries are available.
84    #[must_use]
85    pub fn ray_query(&self) -> bool {
86        self.flags.contains(CapabilityFlags::RAY_QUERY)
87    }
88
89    /// Mesh shading is available.
90    #[must_use]
91    pub fn mesh_shaders(&self) -> bool {
92        self.flags.contains(CapabilityFlags::MESH_SHADERS)
93    }
94
95    /// Bindless descriptor arrays are available.
96    #[must_use]
97    pub fn bindless(&self) -> bool {
98        self.flags.contains(CapabilityFlags::BINDLESS)
99    }
100
101    /// GPU timestamp queries are available.
102    #[must_use]
103    pub fn timestamp_queries(&self) -> bool {
104        self.flags.contains(CapabilityFlags::TIMESTAMP_QUERIES)
105    }
106
107    /// Subgroup operations are available.
108    #[must_use]
109    pub fn subgroup_ops(&self) -> bool {
110        self.flags.contains(CapabilityFlags::SUBGROUP_OPS)
111    }
112
113    /// One pass may depth-test against a texture it also samples.
114    #[must_use]
115    pub fn depth_read_while_sampled(&self) -> bool {
116        self.flags
117            .contains(CapabilityFlags::DEPTH_READ_WHILE_SAMPLED)
118    }
119}
120
121#[cfg(test)]
122#[path = "capabilities_tests.rs"]
123mod tests;