1use crate::back::glsl::{BackendResult, Error, VaryingOptions};
2
3pub(in crate::back::glsl) struct ScalarString<'a> {
7 pub prefix: &'a str,
9 pub full: &'a str,
11}
12
13pub(in crate::back::glsl) const fn glsl_scalar(
20 scalar: crate::Scalar,
21) -> Result<ScalarString<'static>, Error> {
22 use crate::ScalarKind as Sk;
23
24 Ok(match scalar.kind {
25 Sk::Sint => ScalarString {
26 prefix: "i",
27 full: "int",
28 },
29 Sk::Uint => ScalarString {
30 prefix: "u",
31 full: "uint",
32 },
33 Sk::Float => match scalar.width {
34 4 => ScalarString {
35 prefix: "",
36 full: "float",
37 },
38 8 => ScalarString {
39 prefix: "d",
40 full: "double",
41 },
42 _ => return Err(Error::UnsupportedScalar(scalar)),
43 },
44 Sk::Bool => ScalarString {
45 prefix: "b",
46 full: "bool",
47 },
48 Sk::AbstractInt | Sk::AbstractFloat => {
49 return Err(Error::UnsupportedScalar(scalar));
50 }
51 })
52}
53
54pub(in crate::back::glsl) const fn glsl_built_in(
56 built_in: crate::BuiltIn,
57 options: VaryingOptions,
58) -> &'static str {
59 use crate::BuiltIn as Bi;
60
61 match built_in {
62 Bi::Position { .. } => {
63 if options.output {
64 "gl_Position"
65 } else {
66 "gl_FragCoord"
67 }
68 }
69 Bi::ViewIndex => {
70 if options.targeting_webgl {
71 "gl_ViewID_OVR"
72 } else {
73 "uint(gl_ViewIndex)"
74 }
75 }
76 Bi::BaseInstance => "uint(gl_BaseInstance)",
78 Bi::BaseVertex => "uint(gl_BaseVertex)",
79 Bi::ClipDistance => "gl_ClipDistance",
80 Bi::CullDistance => "gl_CullDistance",
81 Bi::InstanceIndex => {
82 if options.draw_parameters {
83 "(uint(gl_InstanceID) + uint(gl_BaseInstanceARB))"
84 } else {
85 "(uint(gl_InstanceID) + naga_vs_first_instance)"
87 }
88 }
89 Bi::PointSize => "gl_PointSize",
90 Bi::VertexIndex => "uint(gl_VertexID)",
91 Bi::DrawID => "gl_DrawID",
92 Bi::FragDepth => "gl_FragDepth",
94 Bi::PointCoord => "gl_PointCoord",
95 Bi::FrontFacing => "gl_FrontFacing",
96 Bi::PrimitiveIndex => "uint(gl_PrimitiveID)",
97 Bi::Barycentric { perspective: true } => "gl_BaryCoordEXT",
98 Bi::Barycentric { perspective: false } => "gl_BaryCoordNoPerspEXT",
99 Bi::SampleIndex => "gl_SampleID",
100 Bi::SampleMask => {
101 if options.output {
102 "gl_SampleMask"
103 } else {
104 "gl_SampleMaskIn"
105 }
106 }
107 Bi::GlobalInvocationId => "gl_GlobalInvocationID",
109 Bi::LocalInvocationId => "gl_LocalInvocationID",
110 Bi::LocalInvocationIndex => "gl_LocalInvocationIndex",
111 Bi::WorkGroupId => "gl_WorkGroupID",
112 Bi::WorkGroupSize => "gl_WorkGroupSize",
113 Bi::NumWorkGroups => "gl_NumWorkGroups",
114 Bi::NumSubgroups => "gl_NumSubgroups",
116 Bi::SubgroupId => "gl_SubgroupID",
117 Bi::SubgroupSize => "gl_SubgroupSize",
118 Bi::SubgroupInvocationId => "gl_SubgroupInvocationID",
119 Bi::CullPrimitive
122 | Bi::PointIndex
123 | Bi::LineIndices
124 | Bi::TriangleIndices
125 | Bi::MeshTaskSize
126 | Bi::VertexCount
127 | Bi::PrimitiveCount
128 | Bi::Vertices
129 | Bi::Primitives => {
130 unimplemented!()
131 }
132 }
133}
134
135pub(in crate::back::glsl) const fn glsl_storage_qualifier(
137 space: crate::AddressSpace,
138) -> Option<&'static str> {
139 use crate::AddressSpace as As;
140
141 match space {
142 As::Function => None,
143 As::Private => None,
144 As::Storage { .. } => Some("buffer"),
145 As::Uniform => Some("uniform"),
146 As::Handle => Some("uniform"),
147 As::WorkGroup => Some("shared"),
148 As::Immediate => Some("uniform"),
149 As::TaskPayload => unreachable!(),
150 }
151}
152
153pub(in crate::back::glsl) const fn glsl_interpolation(
155 interpolation: crate::Interpolation,
156) -> &'static str {
157 use crate::Interpolation as I;
158
159 match interpolation {
160 I::Perspective => "smooth",
161 I::Linear => "noperspective",
162 I::Flat => "flat",
163 I::PerVertex => unreachable!(),
164 }
165}
166
167pub(in crate::back::glsl) const fn glsl_sampling(
169 sampling: crate::Sampling,
170) -> BackendResult<Option<&'static str>> {
171 use crate::Sampling as S;
172
173 Ok(match sampling {
174 S::First => return Err(Error::FirstSamplingNotSupported),
175 S::Center | S::Either => None,
176 S::Centroid => Some("centroid"),
177 S::Sample => Some("sample"),
178 })
179}
180
181pub(in crate::back::glsl) const fn glsl_dimension(dim: crate::ImageDimension) -> &'static str {
183 use crate::ImageDimension as IDim;
184
185 match dim {
186 IDim::D1 => "1D",
187 IDim::D2 => "2D",
188 IDim::D3 => "3D",
189 IDim::Cube => "Cube",
190 }
191}
192
193pub(in crate::back::glsl) fn glsl_storage_format(
195 format: crate::StorageFormat,
196) -> Result<&'static str, Error> {
197 use crate::StorageFormat as Sf;
198
199 Ok(match format {
200 Sf::R8Unorm => "r8",
201 Sf::R8Snorm => "r8_snorm",
202 Sf::R8Uint => "r8ui",
203 Sf::R8Sint => "r8i",
204 Sf::R16Uint => "r16ui",
205 Sf::R16Sint => "r16i",
206 Sf::R16Float => "r16f",
207 Sf::Rg8Unorm => "rg8",
208 Sf::Rg8Snorm => "rg8_snorm",
209 Sf::Rg8Uint => "rg8ui",
210 Sf::Rg8Sint => "rg8i",
211 Sf::R32Uint => "r32ui",
212 Sf::R32Sint => "r32i",
213 Sf::R32Float => "r32f",
214 Sf::Rg16Uint => "rg16ui",
215 Sf::Rg16Sint => "rg16i",
216 Sf::Rg16Float => "rg16f",
217 Sf::Rgba8Unorm => "rgba8",
218 Sf::Rgba8Snorm => "rgba8_snorm",
219 Sf::Rgba8Uint => "rgba8ui",
220 Sf::Rgba8Sint => "rgba8i",
221 Sf::Rgb10a2Uint => "rgb10_a2ui",
222 Sf::Rgb10a2Unorm => "rgb10_a2",
223 Sf::Rg11b10Ufloat => "r11f_g11f_b10f",
224 Sf::R64Uint => "r64ui",
225 Sf::Rg32Uint => "rg32ui",
226 Sf::Rg32Sint => "rg32i",
227 Sf::Rg32Float => "rg32f",
228 Sf::Rgba16Uint => "rgba16ui",
229 Sf::Rgba16Sint => "rgba16i",
230 Sf::Rgba16Float => "rgba16f",
231 Sf::Rgba32Uint => "rgba32ui",
232 Sf::Rgba32Sint => "rgba32i",
233 Sf::Rgba32Float => "rgba32f",
234 Sf::R16Unorm => "r16",
235 Sf::R16Snorm => "r16_snorm",
236 Sf::Rg16Unorm => "rg16",
237 Sf::Rg16Snorm => "rg16_snorm",
238 Sf::Rgba16Unorm => "rgba16",
239 Sf::Rgba16Snorm => "rgba16_snorm",
240
241 Sf::Bgra8Unorm => {
242 return Err(Error::Custom(
243 "Support format BGRA8 is not implemented".into(),
244 ))
245 }
246 })
247}