1use std::fmt::Display;
2
3use itertools::Itertools;
4
5use crate::{
6 CallSignature,
7 inst::{
8 ArrayInstance, AtomicInstance, Instance, LiteralInstance, MatInstance, MemView,
9 PtrInstance, RefInstance, StructInstance, VecInstance,
10 },
11 syntax::Enumerant,
12 tplt::TpltParam,
13 ty::{SamplerType, TextureType, Ty, Type},
14};
15
16impl Display for TpltParam {
17 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
18 match self {
19 TpltParam::Type(ty) => write!(f, "{ty}"),
20 TpltParam::Instance(inst) => write!(f, "{inst}"),
21 TpltParam::Enumerant(name) => write!(f, "{name}"),
22 }
23 }
24}
25
26impl Display for CallSignature {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 let name = &self.name;
29 let tplt = self.tplt.as_ref().map(|tplt| tplt.iter().format(", "));
30 let args = self.args.iter().format(", ");
31
32 if let Some(tplt) = tplt {
33 write!(f, "{name}<{tplt}>({args})")
34 } else {
35 write!(f, "{name}({args})")
36 }
37 }
38}
39
40impl Display for Instance {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 match self {
43 Instance::Literal(inst) => write!(f, "{inst}"),
44 Instance::Struct(inst) => write!(f, "{inst}"),
45 Instance::Array(inst) => write!(f, "{inst}"),
46 Instance::Vec(inst) => write!(f, "{inst}"),
47 Instance::Mat(inst) => write!(f, "{inst}"),
48 Instance::Ptr(inst) => write!(f, "{inst}"),
49 Instance::Ref(inst) => write!(f, "{inst}"),
50 Instance::Atomic(inst) => write!(f, "{inst}"),
51 Instance::Deferred(ty) => write!(f, "__deferred<{ty}>"),
52 }
53 }
54}
55
56impl Display for LiteralInstance {
57 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58 match self {
59 LiteralInstance::Bool(lit) => write!(f, "{lit}"),
60 LiteralInstance::AbstractInt(lit) => write!(f, "{lit}"),
61 LiteralInstance::AbstractFloat(lit) => write!(f, "{lit:?}"), LiteralInstance::I32(lit) => write!(f, "{lit}i"),
63 LiteralInstance::U32(lit) => write!(f, "{lit}u"),
64 LiteralInstance::F32(lit) => write!(f, "{lit}f"),
65 LiteralInstance::F16(lit) => write!(f, "{lit}h"),
66 #[cfg(feature = "naga-ext")]
67 LiteralInstance::I64(lit) => write!(f, "{lit}li"),
68 #[cfg(feature = "naga-ext")]
69 LiteralInstance::U64(lit) => write!(f, "{lit}lu"),
70 #[cfg(feature = "naga-ext")]
71 LiteralInstance::F64(lit) => write!(f, "{lit}lf"),
72 }
73 }
74}
75
76impl Display for StructInstance {
77 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
78 let name = &self.ty.name;
79 let comps = self
80 .members
81 .iter()
82 .map(|inst| format!("{inst}"))
83 .format(", ");
84 write!(f, "{name}({comps})")
85 }
86}
87
88impl Display for ArrayInstance {
89 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
90 let comps = self.iter().format(", ");
91 write!(f, "array({comps})")
92 }
93}
94
95impl Display for VecInstance {
96 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
97 let n = self.n();
98 let comps = self.iter().format(", ");
99 write!(f, "vec{n}({comps})")
100 }
101}
102
103impl Display for MatInstance {
104 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
105 let c = self.c();
106 let r = self.r();
107 let comps = (0..c).map(|i| self.col(i).unwrap()).format(", ");
108 write!(f, "mat{c}x{r}({comps})")
109 }
110}
111
112impl Display for Enumerant {
113 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
114 match self {
115 Enumerant::AccessMode(access_mode) => write!(f, "{access_mode}"),
116 Enumerant::AddressSpace(address_space) => write!(f, "{address_space}"),
117 Enumerant::TexelFormat(texel_format) => write!(f, "{texel_format}"),
118 #[cfg(feature = "naga-ext")]
119 Enumerant::AccelerationStructureFlags(flags) => write!(f, "{flags}"),
120 }
121 }
122}
123
124impl Display for PtrInstance {
125 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126 let space = &self.ptr.space;
127 let ty = &self.ptr.ty;
128 let access = &self.ptr.access;
129 let val = self.ptr.read().expect("invalid reference");
130 write!(f, "ptr<{space}, {ty}, {access}>({val})")
131 }
132}
133
134impl Display for RefInstance {
135 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
136 let space = &self.space;
137 let ty = &self.ty;
138 let access = &self.access;
139 let val = self.read().expect("invalid reference");
140 write!(f, "ref<{space}, {ty}, {access}>({val})")
141 }
142}
143
144impl Display for MemView {
145 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
146 fn fmt_view(f: &mut std::fmt::Formatter<'_>, view: &MemView) -> std::fmt::Result {
147 match view {
148 MemView::Whole => Ok(()),
149 MemView::Member(m, v) => {
150 write!(f, ":{m}")?;
151 fmt_view(f, v)
152 }
153 MemView::Index(i, v) => {
154 write!(f, ":{i}")?;
155 fmt_view(f, v)
156 }
157 }
158 }
159
160 fmt_view(f, self)
161 }
162}
163
164impl Display for AtomicInstance {
165 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
166 let ty = &self.inner_ty();
167 let val = self.inner();
168 write!(f, "atomic<{ty}>({val})")
169 }
170}
171
172impl Display for Type {
173 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
174 match self {
175 Type::Bool => write!(f, "bool"),
176 Type::AbstractInt => write!(f, "AbstractInt"),
177 Type::AbstractFloat => write!(f, "AbstractFloat"),
178 Type::I32 => write!(f, "i32"),
179 Type::U32 => write!(f, "u32"),
180 Type::F32 => write!(f, "f32"),
181 Type::F16 => write!(f, "f16"),
182 Type::Struct(s) => write!(f, "{}", s.name),
183 Type::Array(ty, Some(n)) => write!(f, "array<{ty}, {n}>"),
184 Type::Array(ty, None) => write!(f, "array<{ty}>"),
185 Type::Vec(n, ty) => write!(f, "vec{n}<{ty}>"),
186 Type::Mat(m, n, ty) => write!(f, "mat{m}x{n}<{ty}>"),
187 Type::Atomic(ty) => write!(f, "atomic<{ty}>"),
188 Type::Ptr(a_s, ty, a_m) => write!(f, "ptr<{a_s}, {ty}, {a_m}>"),
189 Type::Ref(a_s, ty, a_m) => write!(f, "ref<{a_s}, {ty}, {a_m}>"),
190 Type::Texture(texture_type) => texture_type.fmt(f),
191 Type::Sampler(sampler_type) => sampler_type.fmt(f),
192 #[cfg(feature = "naga-ext")]
193 Type::I64 => write!(f, "i64"),
194 #[cfg(feature = "naga-ext")]
195 Type::U64 => write!(f, "u64"),
196 #[cfg(feature = "naga-ext")]
197 Type::F64 => write!(f, "f64"),
198 #[cfg(feature = "naga-ext")]
199 Type::BindingArray(ty, Some(n)) => write!(f, "binding_array<{ty}, {n}>"),
200 #[cfg(feature = "naga-ext")]
201 Type::BindingArray(ty, None) => write!(f, "binding_array<{ty}>"),
202 #[cfg(feature = "naga-ext")]
203 Type::RayQuery(None) => write!(f, "ray_query"),
204 #[cfg(feature = "naga-ext")]
205 Type::RayQuery(Some(_)) => write!(f, "ray_query<vertex_return>"),
206 #[cfg(feature = "naga-ext")]
207 Type::AccelerationStructure(None) => write!(f, "acceleration_structure"),
208 #[cfg(feature = "naga-ext")]
209 Type::AccelerationStructure(Some(_)) => {
210 write!(f, "acceleration_structure<vertex_return>")
211 }
212 }
213 }
214}
215
216impl Display for TextureType {
217 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
218 match self {
219 TextureType::Sampled1D(sampled) => write!(f, "texture_1d<{sampled}>"),
220 TextureType::Sampled2D(sampled) => write!(f, "texture_2d<{sampled}>"),
221 TextureType::Sampled2DArray(sampled) => write!(f, "texture_2d_array<{sampled}>"),
222 TextureType::Sampled3D(sampled) => write!(f, "texture_3d<{sampled}>"),
223 TextureType::SampledCube(sampled) => write!(f, "texture_cube<{sampled}>"),
224 TextureType::SampledCubeArray(sampled) => write!(f, "texture_cube_array<{sampled}>"),
225 TextureType::Multisampled2D(sampled) => write!(f, "texture_multisampled_2d<{sampled}>"),
226 TextureType::DepthMultisampled2D => write!(f, "texture_depth_multisampled_2d"),
227 TextureType::External => write!(f, "texture_external<>"),
228 TextureType::Storage1D(texel, access) => {
229 write!(f, "texture_storage_1d<{texel}, {access}>")
230 }
231 TextureType::Storage2D(texel, access) => {
232 write!(f, "texture_storage_2d<{texel}, {access}>")
233 }
234 TextureType::Storage2DArray(texel, access) => {
235 write!(f, "texture_storage_2d_array<{texel}, {access}>")
236 }
237 TextureType::Storage3D(texel, access) => {
238 write!(f, "texture_storage_3d<{texel}, {access}>")
239 }
240 TextureType::Depth2D => write!(f, "texture_depth_2d"),
241 TextureType::Depth2DArray => write!(f, "texture_depth_2d_array"),
242 TextureType::DepthCube => write!(f, "texture_depth_cube"),
243 TextureType::DepthCubeArray => write!(f, "texture_depth_cube_array"),
244 #[cfg(feature = "naga-ext")]
245 TextureType::Sampled1DArray(sampled) => write!(f, "texture_1d_array<{sampled}>"),
246 #[cfg(feature = "naga-ext")]
247 TextureType::Storage1DArray(texel, access) => {
248 write!(f, "texture_storage_1d_array<{texel}, {access}>")
249 }
250 #[cfg(feature = "naga-ext")]
251 TextureType::Multisampled2DArray(sampled) => {
252 write!(f, "texture_multisampled_2d_array<{sampled}>")
253 }
254 }
255 }
256}
257
258impl Display for SamplerType {
259 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
260 match self {
261 SamplerType::Sampler => write!(f, "sampler"),
262 SamplerType::SamplerComparison => write!(f, "sampler_comparison"),
263 }
264 }
265}