naga/
lib.rs

1/*!
2Naga can be used to translate source code written in one shading language to another.
3
4# Example
5
6The following example translates WGSL to GLSL.
7It requires the features `"wgsl-in"` and `"glsl-out"` to be enabled.
8
9*/
10// If we don't have the required front- and backends, don't try to build this example.
11#![cfg_attr(all(feature = "wgsl-in", feature = "glsl-out"), doc = "```")]
12#![cfg_attr(not(all(feature = "wgsl-in", feature = "glsl-out")), doc = "```ignore")]
13/*!
14let wgsl_source = "
15@fragment
16fn main_fs() -> @location(0) vec4<f32> {
17    return vec4<f32>(1.0, 1.0, 1.0, 1.0);
18}
19";
20
21// Parse the source into a Module.
22let module: naga::Module = naga::front::wgsl::parse_str(wgsl_source)?;
23
24// Validate the module.
25// Validation can be made less restrictive by changing the ValidationFlags.
26let module_info: naga::valid::ModuleInfo =
27    naga::valid::Validator::new(
28        naga::valid::ValidationFlags::all(),
29        naga::valid::Capabilities::all(),
30    )
31    .subgroup_stages(naga::valid::ShaderStages::all())
32    .subgroup_operations(naga::valid::SubgroupOperationSet::all())
33    .validate(&module)?;
34
35// Translate the module.
36use naga::back::glsl;
37let mut glsl_source = String::new();
38glsl::Writer::new(
39    &mut glsl_source,
40    &module,
41    &module_info,
42    &glsl::Options::default(),
43    &glsl::PipelineOptions {
44        entry_point: "main_fs".into(),
45        shader_stage: naga::ShaderStage::Fragment,
46        multiview: None,
47    },
48    naga::proc::BoundsCheckPolicies::default(),
49)?.write()?;
50
51assert_eq!(glsl_source, "\
52#version 310 es
53
54precision highp float;
55precision highp int;
56
57layout(location = 0) out vec4 _fs2p_location0;
58
59void main() {
60    _fs2p_location0 = vec4(1.0, 1.0, 1.0, 1.0);
61    return;
62}
63
64");
65
66# Ok::<(), Box<dyn core::error::Error>>(())
67```
68*/
69
70#![allow(
71    clippy::new_without_default,
72    clippy::unneeded_field_pattern,
73    clippy::match_like_matches_macro,
74    clippy::collapsible_if,
75    clippy::derive_partial_eq_without_eq,
76    clippy::needless_borrowed_reference,
77    clippy::single_match,
78    clippy::enum_variant_names,
79    clippy::result_large_err
80)]
81#![warn(
82    trivial_casts,
83    trivial_numeric_casts,
84    unused_extern_crates,
85    unused_qualifications,
86    clippy::pattern_type_mismatch,
87    clippy::missing_const_for_fn,
88    clippy::rest_pat_in_fully_bound_structs,
89    clippy::match_wildcard_for_single_variants
90)]
91#![deny(clippy::exit)]
92#![cfg_attr(
93    not(test),
94    warn(
95        clippy::dbg_macro,
96        clippy::panic,
97        clippy::print_stderr,
98        clippy::print_stdout,
99        clippy::todo
100    )
101)]
102#![no_std]
103
104#[cfg(std)]
105extern crate std;
106
107extern crate alloc;
108
109mod arena;
110pub mod back;
111pub mod common;
112pub mod compact;
113pub mod diagnostic_filter;
114pub mod error;
115pub mod front;
116pub mod ir;
117pub mod keywords;
118mod non_max_u32;
119mod path_like;
120pub mod proc;
121mod racy_lock;
122mod span;
123pub mod valid;
124
125use alloc::string::String;
126
127pub use crate::arena::{Arena, Handle, Range, UniqueArena};
128pub use crate::span::{SourceLocation, Span, SpanContext, WithSpan};
129
130// TODO: Eliminate this re-export and migrate uses of `crate::Foo` to `use crate::ir; ir::Foo`.
131pub use ir::*;
132
133/// Width of a boolean type, in bytes.
134pub const BOOL_WIDTH: Bytes = 1;
135
136/// Width of abstract types, in bytes.
137pub const ABSTRACT_WIDTH: Bytes = 8;
138
139/// Hash map that is faster but not resilient to DoS attacks.
140/// (Similar to rustc_hash::FxHashMap but using hashbrown::HashMap instead of alloc::collections::HashMap.)
141/// To construct a new instance: `FastHashMap::default()`
142pub type FastHashMap<K, T> =
143    hashbrown::HashMap<K, T, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
144
145/// Hash set that is faster but not resilient to DoS attacks.
146/// (Similar to rustc_hash::FxHashSet but using hashbrown::HashSet instead of alloc::collections::HashMap.)
147pub type FastHashSet<K> =
148    hashbrown::HashSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
149
150/// Insertion-order-preserving hash set (`IndexSet<K>`), but with the same
151/// hasher as `FastHashSet<K>` (faster but not resilient to DoS attacks).
152pub type FastIndexSet<K> =
153    indexmap::IndexSet<K, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
154
155/// Insertion-order-preserving hash map (`IndexMap<K, V>`), but with the same
156/// hasher as `FastHashMap<K, V>` (faster but not resilient to DoS attacks).
157pub type FastIndexMap<K, V> =
158    indexmap::IndexMap<K, V, core::hash::BuildHasherDefault<rustc_hash::FxHasher>>;
159
160/// Map of expressions that have associated variable names
161pub(crate) type NamedExpressions = FastIndexMap<Handle<Expression>, String>;