1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 *
5 * Large chunks of this file are derived from the glsl crate which is:
6 * Copyright (c) 2018, Dimitri Sabadie <dimitri.sabadie@gmail.com>
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 *
13 * * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 *
16 * * Redistributions in binary form must reproduce the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer in the documentation and/or other materials provided
19 * with the distribution.
20 *
21 * * Neither the name of Dimitri Sabadie <dimitri.sabadie@gmail.com> nor the names of other
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
36
37 use glsl::syntax;
38 use glsl::syntax::{ArrayedIdentifier, ArraySpecifier, AssignmentOp, BinaryOp, Identifier};
39 use glsl::syntax::{NonEmpty, PrecisionQualifier, StructFieldSpecifier, StructSpecifier};
40 use glsl::syntax::{TypeSpecifier, TypeSpecifierNonArray, UnaryOp};
41 use std::cell::{Cell, Ref, RefCell};
42 use std::collections::HashMap;
43 use std::iter::FromIterator;
44 use std::mem;
45 use std::ops::{Deref, DerefMut};
46 use std::rc::Rc;
47
48 trait LiftFrom<S> {
lift(state: &mut State, s: S) -> Self49 fn lift(state: &mut State, s: S) -> Self;
50 }
51
lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T52 fn lift<S, T: LiftFrom<S>>(state: &mut State, s: S) -> T {
53 LiftFrom::lift(state, s)
54 }
55
56 #[derive(Debug)]
57 pub struct Symbol {
58 pub name: String,
59 pub decl: SymDecl,
60 }
61
62 #[derive(Debug, Clone, PartialEq)]
63 pub struct FunctionSignature {
64 ret: Type,
65 params: Vec<Type>,
66 }
67
68 #[derive(Debug, Clone, PartialEq)]
69 pub struct FunctionType {
70 signatures: NonEmpty<FunctionSignature>,
71 }
72
73 #[derive(Clone, Copy, Debug, PartialEq)]
74 pub enum SamplerFormat {
75 Unknown,
76 RGBA8,
77 RGBA32F,
78 RGBA32I,
79 R8,
80 RG8,
81 }
82
83 impl SamplerFormat {
type_suffix(self) -> Option<&'static str>84 pub fn type_suffix(self) -> Option<&'static str> {
85 match self {
86 SamplerFormat::Unknown => None,
87 SamplerFormat::RGBA8 => Some("RGBA8"),
88 SamplerFormat::RGBA32F => Some("RGBA32F"),
89 SamplerFormat::RGBA32I => Some("RGBA32I"),
90 SamplerFormat::R8 => Some("R8"),
91 SamplerFormat::RG8 => Some("RG8"),
92 }
93 }
94 }
95
96 #[derive(Clone, Copy, Debug, PartialEq)]
97 pub enum StorageClass {
98 None,
99 Const,
100 In,
101 Out,
102 Uniform,
103 Sampler(SamplerFormat),
104 FragColor(i32),
105 }
106
107 #[derive(Clone, Debug, PartialEq)]
108 pub struct ArraySizes {
109 pub sizes: Vec<Expr>,
110 }
111
112 impl LiftFrom<&ArraySpecifier> for ArraySizes {
lift(state: &mut State, a: &ArraySpecifier) -> Self113 fn lift(state: &mut State, a: &ArraySpecifier) -> Self {
114 ArraySizes {
115 sizes: vec![match a {
116 ArraySpecifier::Unsized => panic!(),
117 ArraySpecifier::ExplicitlySized(expr) => translate_expression(state, expr),
118 }],
119 }
120 }
121 }
122
123 #[derive(Copy, Clone, Debug, PartialEq)]
124 pub enum TypeKind {
125 Void,
126 Bool,
127 Int,
128 UInt,
129 Float,
130 Double,
131 Vec2,
132 Vec3,
133 Vec4,
134 DVec2,
135 DVec3,
136 DVec4,
137 BVec2,
138 BVec3,
139 BVec4,
140 IVec2,
141 IVec3,
142 IVec4,
143 UVec2,
144 UVec3,
145 UVec4,
146 Mat2,
147 Mat3,
148 Mat4,
149 Mat23,
150 Mat24,
151 Mat32,
152 Mat34,
153 Mat42,
154 Mat43,
155 DMat2,
156 DMat3,
157 DMat4,
158 DMat23,
159 DMat24,
160 DMat32,
161 DMat34,
162 DMat42,
163 DMat43,
164 // floating point opaque types
165 Sampler1D,
166 Image1D,
167 Sampler2D,
168 Image2D,
169 Sampler3D,
170 Image3D,
171 SamplerCube,
172 ImageCube,
173 Sampler2DRect,
174 Image2DRect,
175 Sampler1DArray,
176 Image1DArray,
177 Sampler2DArray,
178 Image2DArray,
179 SamplerBuffer,
180 ImageBuffer,
181 Sampler2DMS,
182 Image2DMS,
183 Sampler2DMSArray,
184 Image2DMSArray,
185 SamplerCubeArray,
186 ImageCubeArray,
187 Sampler1DShadow,
188 Sampler2DShadow,
189 Sampler2DRectShadow,
190 Sampler1DArrayShadow,
191 Sampler2DArrayShadow,
192 SamplerCubeShadow,
193 SamplerCubeArrayShadow,
194 // signed integer opaque types
195 ISampler1D,
196 IImage1D,
197 ISampler2D,
198 IImage2D,
199 ISampler3D,
200 IImage3D,
201 ISamplerCube,
202 IImageCube,
203 ISampler2DRect,
204 IImage2DRect,
205 ISampler1DArray,
206 IImage1DArray,
207 ISampler2DArray,
208 IImage2DArray,
209 ISamplerBuffer,
210 IImageBuffer,
211 ISampler2DMS,
212 IImage2DMS,
213 ISampler2DMSArray,
214 IImage2DMSArray,
215 ISamplerCubeArray,
216 IImageCubeArray,
217 // unsigned integer opaque types
218 AtomicUInt,
219 USampler1D,
220 UImage1D,
221 USampler2D,
222 UImage2D,
223 USampler3D,
224 UImage3D,
225 USamplerCube,
226 UImageCube,
227 USampler2DRect,
228 UImage2DRect,
229 USampler1DArray,
230 UImage1DArray,
231 USampler2DArray,
232 UImage2DArray,
233 USamplerBuffer,
234 UImageBuffer,
235 USampler2DMS,
236 UImage2DMS,
237 USampler2DMSArray,
238 UImage2DMSArray,
239 USamplerCubeArray,
240 UImageCubeArray,
241 Struct(SymRef),
242 }
243
244 impl TypeKind {
is_sampler(&self) -> bool245 pub fn is_sampler(&self) -> bool {
246 use TypeKind::*;
247 match self {
248 Sampler1D
249 | Image1D
250 | Sampler2D
251 | Image2D
252 | Sampler3D
253 | Image3D
254 | SamplerCube
255 | ImageCube
256 | Sampler2DRect
257 | Image2DRect
258 | Sampler1DArray
259 | Image1DArray
260 | Sampler2DArray
261 | Image2DArray
262 | SamplerBuffer
263 | ImageBuffer
264 | Sampler2DMS
265 | Image2DMS
266 | Sampler2DMSArray
267 | Image2DMSArray
268 | SamplerCubeArray
269 | ImageCubeArray
270 | Sampler1DShadow
271 | Sampler2DShadow
272 | Sampler2DRectShadow
273 | Sampler1DArrayShadow
274 | Sampler2DArrayShadow
275 | SamplerCubeShadow
276 | SamplerCubeArrayShadow
277 | ISampler1D
278 | IImage1D
279 | ISampler2D
280 | IImage2D
281 | ISampler3D
282 | IImage3D
283 | ISamplerCube
284 | IImageCube
285 | ISampler2DRect
286 | IImage2DRect
287 | ISampler1DArray
288 | IImage1DArray
289 | ISampler2DArray
290 | IImage2DArray
291 | ISamplerBuffer
292 | IImageBuffer
293 | ISampler2DMS
294 | IImage2DMS
295 | ISampler2DMSArray
296 | IImage2DMSArray
297 | ISamplerCubeArray
298 | IImageCubeArray
299 | USampler1D
300 | UImage1D
301 | USampler2D
302 | UImage2D
303 | USampler3D
304 | UImage3D
305 | USamplerCube
306 | UImageCube
307 | USampler2DRect
308 | UImage2DRect
309 | USampler1DArray
310 | UImage1DArray
311 | USampler2DArray
312 | UImage2DArray
313 | USamplerBuffer
314 | UImageBuffer
315 | USampler2DMS
316 | UImage2DMS
317 | USampler2DMSArray
318 | UImage2DMSArray
319 | USamplerCubeArray
320 | UImageCubeArray => true,
321 _ => false,
322 }
323 }
324
is_bool(&self) -> bool325 pub fn is_bool(&self) -> bool {
326 use TypeKind::*;
327 match self {
328 Bool | BVec2 | BVec3 | BVec4 => true,
329 _ => false,
330 }
331 }
332
to_bool(&self) -> Self333 pub fn to_bool(&self) -> Self {
334 use TypeKind::*;
335 match self {
336 Int | UInt | Float | Double => Bool,
337 IVec2 | UVec2 | Vec2 | DVec2 => BVec2,
338 IVec3 | UVec3 | Vec3 | DVec3 => BVec3,
339 IVec4 | UVec4 | Vec4 | DVec4 => BVec4,
340 _ => *self,
341 }
342 }
343
to_int(&self) -> Self344 pub fn to_int(&self) -> Self {
345 use TypeKind::*;
346 match self {
347 Bool | UInt | Float | Double => Int,
348 BVec2 | UVec2 | Vec2 | DVec2 => IVec2,
349 BVec3 | UVec3 | Vec3 | DVec3 => IVec3,
350 BVec4 | UVec4 | Vec4 | DVec4 => IVec4,
351 _ => *self,
352 }
353 }
354
to_scalar(&self) -> Self355 pub fn to_scalar(&self) -> Self {
356 use TypeKind::*;
357 match self {
358 IVec2 | IVec3 | IVec4 => Int,
359 UVec2 | UVec3 | UVec4 => UInt,
360 Vec2 | Vec3 | Vec4 => Float,
361 DVec2 | DVec3 | DVec4 => Double,
362 BVec2 | BVec3 | BVec4 => Bool,
363 _ => *self,
364 }
365 }
366
glsl_primitive_type_name(&self) -> Option<&'static str>367 pub fn glsl_primitive_type_name(&self) -> Option<&'static str> {
368 use TypeKind::*;
369 Some(match self {
370 Void => "void",
371 Bool => "bool",
372 Int => "int",
373 UInt => "uint",
374 Float => "float",
375 Double => "double",
376 Vec2 => "vec2",
377 Vec3 => "vec3",
378 Vec4 => "vec4",
379 DVec2 => "dvec2",
380 DVec3 => "dvec3",
381 DVec4 => "dvec4",
382 BVec2 => "bvec2",
383 BVec3 => "bvec3",
384 BVec4 => "bvec4",
385 IVec2 => "ivec2",
386 IVec3 => "ivec3",
387 IVec4 => "ivec4",
388 UVec2 => "uvec2",
389 UVec3 => "uvec3",
390 UVec4 => "uvec4",
391 Mat2 => "mat2",
392 Mat3 => "mat3",
393 Mat4 => "mat4",
394 Mat23 => "mat23",
395 Mat24 => "mat24",
396 Mat32 => "mat32",
397 Mat34 => "mat34",
398 Mat42 => "mat42",
399 Mat43 => "mat43",
400 DMat2 => "dmat2",
401 DMat3 => "dmat3",
402 DMat4 => "dmat4",
403 DMat23 => "dmat23",
404 DMat24 => "dmat24",
405 DMat32 => "dmat32",
406 DMat34 => "dmat34",
407 DMat42 => "dmat42",
408 DMat43 => "dmat43",
409 Sampler1D => "sampler1D",
410 Image1D => "image1D",
411 Sampler2D => "sampler2D",
412 Image2D => "image2D",
413 Sampler3D => "sampler3D",
414 Image3D => "image3D",
415 SamplerCube => "samplerCube",
416 ImageCube => "imageCube",
417 Sampler2DRect => "sampler2DRect",
418 Image2DRect => "image2DRect",
419 Sampler1DArray => "sampler1DArray",
420 Image1DArray => "image1DArray",
421 Sampler2DArray => "sampler2DArray",
422 Image2DArray => "image2DArray",
423 SamplerBuffer => "samplerBuffer",
424 ImageBuffer => "imageBuffer",
425 Sampler2DMS => "sampler2DMS",
426 Image2DMS => "image2DMS",
427 Sampler2DMSArray => "sampler2DMSArray",
428 Image2DMSArray => "image2DMSArray",
429 SamplerCubeArray => "samplerCubeArray",
430 ImageCubeArray => "imageCubeArray",
431 Sampler1DShadow => "sampler1DShadow",
432 Sampler2DShadow => "sampler2DShadow",
433 Sampler2DRectShadow => "sampler2DRectShadow",
434 Sampler1DArrayShadow => "sampler1DArrayShadow",
435 Sampler2DArrayShadow => "sampler2DArrayShadow",
436 SamplerCubeShadow => "samplerCubeShadow",
437 SamplerCubeArrayShadow => "samplerCubeArrayShadow",
438 ISampler1D => "isampler1D",
439 IImage1D => "iimage1D",
440 ISampler2D => "isampler2D",
441 IImage2D => "iimage2D",
442 ISampler3D => "isampler3D",
443 IImage3D => "iimage3D",
444 ISamplerCube => "isamplerCube",
445 IImageCube => "iimageCube",
446 ISampler2DRect => "isampler2DRect",
447 IImage2DRect => "iimage2DRect",
448 ISampler1DArray => "isampler1DArray",
449 IImage1DArray => "iimage1DArray",
450 ISampler2DArray => "isampler2DArray",
451 IImage2DArray => "iimage2DArray",
452 ISamplerBuffer => "isamplerBuffer",
453 IImageBuffer => "iimageBuffer",
454 ISampler2DMS => "isampler2MS",
455 IImage2DMS => "iimage2DMS",
456 ISampler2DMSArray => "isampler2DMSArray",
457 IImage2DMSArray => "iimage2DMSArray",
458 ISamplerCubeArray => "isamplerCubeArray",
459 IImageCubeArray => "iimageCubeArray",
460 AtomicUInt => "atomic_uint",
461 USampler1D => "usampler1D",
462 UImage1D => "uimage1D",
463 USampler2D => "usampler2D",
464 UImage2D => "uimage2D",
465 USampler3D => "usampler3D",
466 UImage3D => "uimage3D",
467 USamplerCube => "usamplerCube",
468 UImageCube => "uimageCube",
469 USampler2DRect => "usampler2DRect",
470 UImage2DRect => "uimage2DRect",
471 USampler1DArray => "usampler1DArray",
472 UImage1DArray => "uimage1DArray",
473 USampler2DArray => "usampler2DArray",
474 UImage2DArray => "uimage2DArray",
475 USamplerBuffer => "usamplerBuffer",
476 UImageBuffer => "uimageBuffer",
477 USampler2DMS => "usampler2DMS",
478 UImage2DMS => "uimage2DMS",
479 USampler2DMSArray => "usamplerDMSArray",
480 UImage2DMSArray => "uimage2DMSArray",
481 USamplerCubeArray => "usamplerCubeArray",
482 UImageCubeArray => "uimageCubeArray",
483 Struct(..) => return None,
484 })
485 }
486
cxx_primitive_type_name(&self) -> Option<&'static str>487 pub fn cxx_primitive_type_name(&self) -> Option<&'static str> {
488 use TypeKind::*;
489 match self {
490 Bool => Some("Bool"),
491 Int => Some("I32"),
492 UInt => Some("U32"),
493 Float => Some("Float"),
494 Double => Some("Double"),
495 _ => self.glsl_primitive_type_name(),
496 }
497 }
498
cxx_primitive_scalar_type_name(&self) -> Option<&'static str>499 pub fn cxx_primitive_scalar_type_name(&self) -> Option<&'static str> {
500 use TypeKind::*;
501 match self {
502 Void => Some("void"),
503 Bool => Some("bool"),
504 Int => Some("int32_t"),
505 UInt => Some("uint32_t"),
506 Float => Some("float"),
507 Double => Some("double"),
508 _ => {
509 if self.is_sampler() {
510 self.cxx_primitive_type_name()
511 } else {
512 None
513 }
514 }
515 }
516 }
517
from_glsl_primitive_type_name(name: &str) -> Option<TypeKind>518 pub fn from_glsl_primitive_type_name(name: &str) -> Option<TypeKind> {
519 use TypeKind::*;
520 Some(match name {
521 "void" => Void,
522 "bool" => Bool,
523 "int" => Int,
524 "uint" => UInt,
525 "float" => Float,
526 "double" => Double,
527 "vec2" => Vec2,
528 "vec3" => Vec3,
529 "vec4" => Vec4,
530 "dvec2" => DVec2,
531 "dvec3" => DVec3,
532 "dvec4" => DVec4,
533 "bvec2" => BVec2,
534 "bvec3" => BVec3,
535 "bvec4" => BVec4,
536 "ivec2" => IVec2,
537 "ivec3" => IVec3,
538 "ivec4" => IVec4,
539 "uvec2" => UVec2,
540 "uvec3" => UVec3,
541 "uvec4" => UVec4,
542 "mat2" => Mat2,
543 "mat3" => Mat3,
544 "mat4" => Mat4,
545 "mat23" => Mat23,
546 "mat24" => Mat24,
547 "mat32" => Mat32,
548 "mat34" => Mat34,
549 "mat42" => Mat42,
550 "mat43" => Mat43,
551 "dmat2" => DMat2,
552 "dmat3" => DMat3,
553 "dmat4" => DMat4,
554 "dmat23" => DMat23,
555 "dmat24" => DMat24,
556 "dmat32" => DMat32,
557 "dmat34" => DMat34,
558 "dmat42" => DMat42,
559 "dmat43" => DMat43,
560 "sampler1D" => Sampler1D,
561 "image1D" => Image1D,
562 "sampler2D" => Sampler2D,
563 "image2D" => Image2D,
564 "sampler3D" => Sampler3D,
565 "image3D" => Image3D,
566 "samplerCube" => SamplerCube,
567 "imageCube" => ImageCube,
568 "sampler2DRect" => Sampler2DRect,
569 "image2DRect" => Image2DRect,
570 "sampler1DArray" => Sampler1DArray,
571 "image1DArray" => Image1DArray,
572 "sampler2DArray" => Sampler2DArray,
573 "image2DArray" => Image2DArray,
574 "samplerBuffer" => SamplerBuffer,
575 "imageBuffer" => ImageBuffer,
576 "sampler2DMS" => Sampler2DMS,
577 "image2DMS" => Image2DMS,
578 "sampler2DMSArray" => Sampler2DMSArray,
579 "image2DMSArray" => Image2DMSArray,
580 "samplerCubeArray" => SamplerCubeArray,
581 "imageCubeArray" => ImageCubeArray,
582 "sampler1DShadow" => Sampler1DShadow,
583 "sampler2DShadow" => Sampler2DShadow,
584 "sampler2DRectShadow" => Sampler2DRectShadow,
585 "sampler1DArrayShadow" => Sampler1DArrayShadow,
586 "sampler2DArrayShadow" => Sampler2DArrayShadow,
587 "samplerCubeShadow" => SamplerCubeShadow,
588 "samplerCubeArrayShadow" => SamplerCubeArrayShadow,
589 "isampler1D" => ISampler1D,
590 "iimage1D" => IImage1D,
591 "isampler2D" => ISampler2D,
592 "iimage2D" => IImage2D,
593 "isampler3D" => ISampler3D,
594 "iimage3D" => IImage3D,
595 "isamplerCube" => ISamplerCube,
596 "iimageCube" => IImageCube,
597 "isampler2DRect" => ISampler2DRect,
598 "iimage2DRect" => IImage2DRect,
599 "isampler1DArray" => ISampler1DArray,
600 "iimage1DArray" => IImage1DArray,
601 "isampler2DArray" => ISampler2DArray,
602 "iimage2DArray" => IImage2DArray,
603 "isamplerBuffer" => ISamplerBuffer,
604 "iimageBuffer" => IImageBuffer,
605 "isampler2MS" => ISampler2DMS,
606 "iimage2DMS" => IImage2DMS,
607 "isampler2DMSArray" => ISampler2DMSArray,
608 "iimage2DMSArray" => IImage2DMSArray,
609 "isamplerCubeArray" => ISamplerCubeArray,
610 "iimageCubeArray" => IImageCubeArray,
611 "atomic_uint" => AtomicUInt,
612 "usampler1D" => USampler1D,
613 "uimage1D" => UImage1D,
614 "usampler2D" => USampler2D,
615 "uimage2D" => UImage2D,
616 "usampler3D" => USampler3D,
617 "uimage3D" => UImage3D,
618 "usamplerCube" => USamplerCube,
619 "uimageCube" => UImageCube,
620 "usampler2DRect" => USampler2DRect,
621 "uimage2DRect" => UImage2DRect,
622 "usampler1DArray" => USampler1DArray,
623 "uimage1DArray" => UImage1DArray,
624 "usampler2DArray" => USampler2DArray,
625 "uimage2DArray" => UImage2DArray,
626 "usamplerBuffer" => USamplerBuffer,
627 "uimageBuffer" => UImageBuffer,
628 "usampler2DMS" => USampler2DMS,
629 "uimage2DMS" => UImage2DMS,
630 "usamplerDMSArray" => USampler2DMSArray,
631 "uimage2DMSArray" => UImage2DMSArray,
632 "usamplerCubeArray" => USamplerCubeArray,
633 "uimageCubeArray" => UImageCubeArray,
634 _ => return None,
635 })
636 }
637
from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind>638 pub fn from_primitive_type_specifier(spec: &syntax::TypeSpecifierNonArray) -> Option<TypeKind> {
639 use TypeKind::*;
640 Some(match spec {
641 TypeSpecifierNonArray::Void => Void,
642 TypeSpecifierNonArray::Bool => Bool,
643 TypeSpecifierNonArray::Int => Int,
644 TypeSpecifierNonArray::UInt => UInt,
645 TypeSpecifierNonArray::Float => Float,
646 TypeSpecifierNonArray::Double => Double,
647 TypeSpecifierNonArray::Vec2 => Vec2,
648 TypeSpecifierNonArray::Vec3 => Vec3,
649 TypeSpecifierNonArray::Vec4 => Vec4,
650 TypeSpecifierNonArray::DVec2 => DVec2,
651 TypeSpecifierNonArray::DVec3 => DVec3,
652 TypeSpecifierNonArray::DVec4 => DVec4,
653 TypeSpecifierNonArray::BVec2 => BVec2,
654 TypeSpecifierNonArray::BVec3 => BVec3,
655 TypeSpecifierNonArray::BVec4 => BVec4,
656 TypeSpecifierNonArray::IVec2 => IVec2,
657 TypeSpecifierNonArray::IVec3 => IVec3,
658 TypeSpecifierNonArray::IVec4 => IVec4,
659 TypeSpecifierNonArray::UVec2 => UVec2,
660 TypeSpecifierNonArray::UVec3 => UVec3,
661 TypeSpecifierNonArray::UVec4 => UVec4,
662 TypeSpecifierNonArray::Mat2 => Mat2,
663 TypeSpecifierNonArray::Mat3 => Mat3,
664 TypeSpecifierNonArray::Mat4 => Mat4,
665 TypeSpecifierNonArray::Mat23 => Mat23,
666 TypeSpecifierNonArray::Mat24 => Mat24,
667 TypeSpecifierNonArray::Mat32 => Mat32,
668 TypeSpecifierNonArray::Mat34 => Mat34,
669 TypeSpecifierNonArray::Mat42 => Mat42,
670 TypeSpecifierNonArray::Mat43 => Mat43,
671 TypeSpecifierNonArray::DMat2 => DMat2,
672 TypeSpecifierNonArray::DMat3 => DMat3,
673 TypeSpecifierNonArray::DMat4 => DMat4,
674 TypeSpecifierNonArray::DMat23 => DMat23,
675 TypeSpecifierNonArray::DMat24 => DMat24,
676 TypeSpecifierNonArray::DMat32 => DMat32,
677 TypeSpecifierNonArray::DMat34 => DMat34,
678 TypeSpecifierNonArray::DMat42 => DMat42,
679 TypeSpecifierNonArray::DMat43 => DMat43,
680 TypeSpecifierNonArray::Sampler1D => Sampler1D,
681 TypeSpecifierNonArray::Image1D => Image1D,
682 TypeSpecifierNonArray::Sampler2D => Sampler2D,
683 TypeSpecifierNonArray::Image2D => Image2D,
684 TypeSpecifierNonArray::Sampler3D => Sampler3D,
685 TypeSpecifierNonArray::Image3D => Image3D,
686 TypeSpecifierNonArray::SamplerCube => SamplerCube,
687 TypeSpecifierNonArray::ImageCube => ImageCube,
688 TypeSpecifierNonArray::Sampler2DRect => Sampler2DRect,
689 TypeSpecifierNonArray::Image2DRect => Image2DRect,
690 TypeSpecifierNonArray::Sampler1DArray => Sampler1DArray,
691 TypeSpecifierNonArray::Image1DArray => Image1DArray,
692 TypeSpecifierNonArray::Sampler2DArray => Sampler2DArray,
693 TypeSpecifierNonArray::Image2DArray => Image2DArray,
694 TypeSpecifierNonArray::SamplerBuffer => SamplerBuffer,
695 TypeSpecifierNonArray::ImageBuffer => ImageBuffer,
696 TypeSpecifierNonArray::Sampler2DMS => Sampler2DMS,
697 TypeSpecifierNonArray::Image2DMS => Image2DMS,
698 TypeSpecifierNonArray::Sampler2DMSArray => Sampler2DMSArray,
699 TypeSpecifierNonArray::Image2DMSArray => Image2DMSArray,
700 TypeSpecifierNonArray::SamplerCubeArray => SamplerCubeArray,
701 TypeSpecifierNonArray::ImageCubeArray => ImageCubeArray,
702 TypeSpecifierNonArray::Sampler1DShadow => Sampler1DShadow,
703 TypeSpecifierNonArray::Sampler2DShadow => Sampler2DShadow,
704 TypeSpecifierNonArray::Sampler2DRectShadow => Sampler2DRectShadow,
705 TypeSpecifierNonArray::Sampler1DArrayShadow => Sampler1DArrayShadow,
706 TypeSpecifierNonArray::Sampler2DArrayShadow => Sampler2DArrayShadow,
707 TypeSpecifierNonArray::SamplerCubeShadow => SamplerCubeShadow,
708 TypeSpecifierNonArray::SamplerCubeArrayShadow => SamplerCubeArrayShadow,
709 TypeSpecifierNonArray::ISampler1D => ISampler1D,
710 TypeSpecifierNonArray::IImage1D => IImage1D,
711 TypeSpecifierNonArray::ISampler2D => ISampler2D,
712 TypeSpecifierNonArray::IImage2D => IImage2D,
713 TypeSpecifierNonArray::ISampler3D => ISampler3D,
714 TypeSpecifierNonArray::IImage3D => IImage3D,
715 TypeSpecifierNonArray::ISamplerCube => ISamplerCube,
716 TypeSpecifierNonArray::IImageCube => IImageCube,
717 TypeSpecifierNonArray::ISampler2DRect => ISampler2DRect,
718 TypeSpecifierNonArray::IImage2DRect => IImage2DRect,
719 TypeSpecifierNonArray::ISampler1DArray => ISampler1DArray,
720 TypeSpecifierNonArray::IImage1DArray => IImage1DArray,
721 TypeSpecifierNonArray::ISampler2DArray => ISampler2DArray,
722 TypeSpecifierNonArray::IImage2DArray => IImage2DArray,
723 TypeSpecifierNonArray::ISamplerBuffer => ISamplerBuffer,
724 TypeSpecifierNonArray::IImageBuffer => IImageBuffer,
725 TypeSpecifierNonArray::ISampler2DMS => ISampler2DMS,
726 TypeSpecifierNonArray::IImage2DMS => IImage2DMS,
727 TypeSpecifierNonArray::ISampler2DMSArray => ISampler2DMSArray,
728 TypeSpecifierNonArray::IImage2DMSArray => IImage2DMSArray,
729 TypeSpecifierNonArray::ISamplerCubeArray => ISamplerCubeArray,
730 TypeSpecifierNonArray::IImageCubeArray => IImageCubeArray,
731 TypeSpecifierNonArray::AtomicUInt => AtomicUInt,
732 TypeSpecifierNonArray::USampler1D => USampler1D,
733 TypeSpecifierNonArray::UImage1D => UImage1D,
734 TypeSpecifierNonArray::USampler2D => USampler2D,
735 TypeSpecifierNonArray::UImage2D => UImage2D,
736 TypeSpecifierNonArray::USampler3D => USampler3D,
737 TypeSpecifierNonArray::UImage3D => UImage3D,
738 TypeSpecifierNonArray::USamplerCube => USamplerCube,
739 TypeSpecifierNonArray::UImageCube => UImageCube,
740 TypeSpecifierNonArray::USampler2DRect => USampler2DRect,
741 TypeSpecifierNonArray::UImage2DRect => UImage2DRect,
742 TypeSpecifierNonArray::USampler1DArray => USampler1DArray,
743 TypeSpecifierNonArray::UImage1DArray => UImage1DArray,
744 TypeSpecifierNonArray::USampler2DArray => USampler2DArray,
745 TypeSpecifierNonArray::UImage2DArray => UImage2DArray,
746 TypeSpecifierNonArray::USamplerBuffer => USamplerBuffer,
747 TypeSpecifierNonArray::UImageBuffer => UImageBuffer,
748 TypeSpecifierNonArray::USampler2DMS => USampler2DMS,
749 TypeSpecifierNonArray::UImage2DMS => UImage2DMS,
750 TypeSpecifierNonArray::USampler2DMSArray => USampler2DMSArray,
751 TypeSpecifierNonArray::UImage2DMSArray => UImage2DMSArray,
752 TypeSpecifierNonArray::USamplerCubeArray => USamplerCubeArray,
753 TypeSpecifierNonArray::UImageCubeArray => UImageCubeArray,
754 TypeSpecifierNonArray::Struct(..) | TypeSpecifierNonArray::TypeName(..) => return None,
755 })
756 }
757 }
758
759 impl LiftFrom<&syntax::TypeSpecifierNonArray> for TypeKind {
lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self760 fn lift(state: &mut State, spec: &syntax::TypeSpecifierNonArray) -> Self {
761 use TypeKind::*;
762 if let Some(kind) = TypeKind::from_primitive_type_specifier(spec) {
763 kind
764 } else {
765 match spec {
766 TypeSpecifierNonArray::Struct(s) => {
767 Struct(state.lookup(s.name.as_ref().unwrap().as_str()).unwrap())
768 }
769 TypeSpecifierNonArray::TypeName(s) => Struct(state.lookup(&s.0).unwrap()),
770 _ => unreachable!(),
771 }
772 }
773 }
774 }
775
776 #[derive(Clone, Debug, PartialEq)]
777 pub struct Type {
778 pub kind: TypeKind,
779 pub precision: Option<PrecisionQualifier>,
780 pub array_sizes: Option<Box<ArraySizes>>,
781 }
782
783 impl Type {
new(kind: TypeKind) -> Self784 pub fn new(kind: TypeKind) -> Self {
785 Type {
786 kind,
787 precision: None,
788 array_sizes: None,
789 }
790 }
791
new_array(kind: TypeKind, size: i32) -> Self792 pub fn new_array(kind: TypeKind, size: i32) -> Self {
793 Type {
794 kind,
795 precision: None,
796 array_sizes: Some(Box::new(ArraySizes { sizes: vec![make_const(TypeKind::Int, size)] })),
797 }
798 }
799 }
800
801 impl LiftFrom<&syntax::FullySpecifiedType> for Type {
lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self802 fn lift(state: &mut State, ty: &syntax::FullySpecifiedType) -> Self {
803 let kind = lift(state, &ty.ty.ty);
804 let array_sizes = match ty.ty.array_specifier.as_ref() {
805 Some(x) => Some(Box::new(lift(state, x))),
806 None => None,
807 };
808 let precision = get_precision(&ty.qualifier);
809 Type {
810 kind,
811 precision,
812 array_sizes,
813 }
814 }
815 }
816
817 impl LiftFrom<&syntax::TypeSpecifier> for Type {
lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self818 fn lift(state: &mut State, ty: &syntax::TypeSpecifier) -> Self {
819 let kind = lift(state, &ty.ty);
820 let array_sizes = ty
821 .array_specifier
822 .as_ref()
823 .map(|x| Box::new(lift(state, x)));
824 Type {
825 kind,
826 precision: None,
827 array_sizes,
828 }
829 }
830 }
831
832 #[derive(Debug, Clone, PartialEq)]
833 pub struct StructField {
834 pub ty: Type,
835 pub name: syntax::Identifier,
836 }
837
get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier>838 fn get_precision(qualifiers: &Option<syntax::TypeQualifier>) -> Option<PrecisionQualifier> {
839 let mut precision = None;
840 for qual in qualifiers.iter().flat_map(|x| x.qualifiers.0.iter()) {
841 match qual {
842 syntax::TypeQualifierSpec::Precision(p) => {
843 if precision.is_some() {
844 panic!("Multiple precisions");
845 }
846 precision = Some(p.clone());
847 }
848 _ => {}
849 }
850 }
851 precision
852 }
853
854 impl LiftFrom<&StructFieldSpecifier> for StructField {
lift(state: &mut State, f: &StructFieldSpecifier) -> Self855 fn lift(state: &mut State, f: &StructFieldSpecifier) -> Self {
856 let mut ty: Type = lift(state, &f.ty);
857 match &f.identifiers.0[..] {
858 [ident] => {
859 if let Some(a) = &ident.array_spec {
860 ty.array_sizes = Some(Box::new(lift(state, a)));
861 }
862 StructField {
863 ty,
864 name: ident.ident.clone(),
865 }
866 }
867 _ => panic!("bad number of identifiers"),
868 }
869 }
870 }
871
872 #[derive(Debug, Clone, PartialEq)]
873 pub struct StructFields {
874 pub fields: Vec<StructField>,
875 }
876
877 impl LiftFrom<&StructSpecifier> for StructFields {
lift(state: &mut State, s: &StructSpecifier) -> Self878 fn lift(state: &mut State, s: &StructSpecifier) -> Self {
879 let fields = s.fields.0.iter().map(|field| lift(state, field)).collect();
880 Self { fields }
881 }
882 }
883
884 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
885 pub enum RunClass {
886 Unknown,
887 Scalar,
888 Vector,
889 Dependent(u32),
890 }
891
892 impl RunClass {
merge(self, run_class: RunClass) -> RunClass893 pub fn merge(self, run_class: RunClass) -> RunClass {
894 match (self, run_class) {
895 (RunClass::Vector, _) | (_, RunClass::Vector) => RunClass::Vector,
896 (RunClass::Dependent(x), RunClass::Dependent(y)) => RunClass::Dependent(x | y),
897 (RunClass::Unknown, _) | (_, RunClass::Dependent(..)) => run_class,
898 _ => self,
899 }
900 }
901 }
902
903 #[derive(Debug, Clone, PartialEq)]
904 pub enum SymDecl {
905 NativeFunction(FunctionType, Option<&'static str>, RunClass),
906 UserFunction(Rc<FunctionDefinition>, RunClass),
907 Local(StorageClass, Type, RunClass),
908 Global(
909 StorageClass,
910 Option<syntax::InterpolationQualifier>,
911 Type,
912 RunClass,
913 ),
914 Struct(StructFields),
915 }
916
917 #[derive(Clone, Debug, PartialEq, Copy, Eq, Hash)]
918 pub struct SymRef(u32);
919
920 #[derive(Debug)]
921 struct Scope {
922 name: String,
923 names: HashMap<String, SymRef>,
924 }
925 impl Scope {
new(name: String) -> Self926 fn new(name: String) -> Self {
927 Scope {
928 name,
929 names: HashMap::new(),
930 }
931 }
932 }
933
934 #[derive(Clone, Debug, PartialEq)]
935 pub struct TexelFetchOffsets {
936 pub min_x: i32,
937 pub max_x: i32,
938 pub min_y: i32,
939 pub max_y: i32,
940 }
941
942 impl TexelFetchOffsets {
new(x: i32, y: i32) -> Self943 fn new(x: i32, y: i32) -> Self {
944 TexelFetchOffsets {
945 min_x: x,
946 max_x: x,
947 min_y: y,
948 max_y: y,
949 }
950 }
951
add_offset(&mut self, x: i32, y: i32)952 fn add_offset(&mut self, x: i32, y: i32) {
953 self.min_x = self.min_x.min(x);
954 self.max_x = self.max_x.max(x);
955 self.min_y = self.min_y.min(y);
956 self.max_y = self.max_y.max(y);
957 }
958 }
959
960 #[derive(Debug)]
961 pub struct State {
962 scopes: Vec<Scope>,
963 syms: Vec<RefCell<Symbol>>,
964 in_function: Option<SymRef>,
965 run_class_changed: Cell<bool>,
966 last_declaration: SymRef,
967 branch_run_class: RunClass,
968 branch_declaration: SymRef,
969 modified_globals: RefCell<Vec<SymRef>>,
970 pub used_globals: RefCell<Vec<SymRef>>,
971 pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
972 clip_dist_sym: SymRef,
973 pub used_clip_dist: u32,
974 }
975
976 impl State {
new() -> Self977 pub fn new() -> Self {
978 State {
979 scopes: Vec::new(),
980 syms: Vec::new(),
981 in_function: None,
982 run_class_changed: Cell::new(false),
983 last_declaration: SymRef(0),
984 branch_run_class: RunClass::Unknown,
985 branch_declaration: SymRef(0),
986 modified_globals: RefCell::new(Vec::new()),
987 used_globals: RefCell::new(Vec::new()),
988 texel_fetches: HashMap::new(),
989 clip_dist_sym: SymRef(0),
990 used_clip_dist: 0,
991 }
992 }
993
lookup(&self, name: &str) -> Option<SymRef>994 pub fn lookup(&self, name: &str) -> Option<SymRef> {
995 for s in self.scopes.iter().rev() {
996 if let Some(sym) = s.names.get(name) {
997 return Some(*sym);
998 }
999 }
1000 return None;
1001 }
1002
declare(&mut self, name: &str, decl: SymDecl) -> SymRef1003 fn declare(&mut self, name: &str, decl: SymDecl) -> SymRef {
1004 let s = SymRef(self.syms.len() as u32);
1005 self.syms.push(RefCell::new(Symbol {
1006 name: name.into(),
1007 decl,
1008 }));
1009 self.scopes.last_mut().unwrap().names.insert(name.into(), s);
1010 s
1011 }
1012
sym(&self, sym: SymRef) -> Ref<Symbol>1013 pub fn sym(&self, sym: SymRef) -> Ref<Symbol> {
1014 self.syms[sym.0 as usize].borrow()
1015 }
1016
sym_mut(&mut self, sym: SymRef) -> &mut Symbol1017 pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol {
1018 self.syms[sym.0 as usize].get_mut()
1019 }
1020
lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol>1021 pub fn lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol> {
1022 self.lookup(name)
1023 .map(move |x| self.syms[x.0 as usize].get_mut())
1024 }
1025
push_scope(&mut self, name: String)1026 fn push_scope(&mut self, name: String) {
1027 self.scopes.push(Scope::new(name));
1028 }
pop_scope(&mut self)1029 fn pop_scope(&mut self) {
1030 self.scopes.pop();
1031 }
1032
return_run_class(&self, mut new_run_class: RunClass)1033 fn return_run_class(&self, mut new_run_class: RunClass) {
1034 new_run_class = self.branch_run_class.merge(new_run_class);
1035 if let Some(sym) = self.in_function {
1036 let mut b = self.syms[sym.0 as usize].borrow_mut();
1037 if let SymDecl::UserFunction(_, ref mut run_class) = b.decl {
1038 *run_class = run_class.merge(new_run_class);
1039 }
1040 }
1041 }
1042
function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)>1043 pub fn function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)> {
1044 if let SymDecl::UserFunction(ref fd, ref run_class) = &self.sym(name).decl {
1045 Some((fd.clone(), *run_class))
1046 } else {
1047 None
1048 }
1049 }
1050
merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass1051 fn merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass {
1052 if sym.0 <= self.branch_declaration.0 {
1053 new_run_class = self.branch_run_class.merge(new_run_class);
1054 }
1055 let mut b = self.syms[sym.0 as usize].borrow_mut();
1056 let mut old_run_class = new_run_class;
1057 if let SymDecl::Local(_, _, ref mut run_class) = b.decl {
1058 old_run_class = *run_class;
1059 new_run_class = old_run_class.merge(new_run_class);
1060 *run_class = new_run_class;
1061 }
1062 if old_run_class != RunClass::Unknown && old_run_class != new_run_class {
1063 self.run_class_changed.set(true);
1064 }
1065 new_run_class
1066 }
1067 }
1068
1069 /// A declaration.
1070 #[derive(Clone, Debug, PartialEq)]
1071 pub enum Declaration {
1072 FunctionPrototype(FunctionPrototype),
1073 StructDefinition(SymRef),
1074 InitDeclaratorList(InitDeclaratorList),
1075 Precision(PrecisionQualifier, TypeSpecifier),
1076 Block(Block),
1077 Global(TypeQualifier, Vec<Identifier>),
1078 }
1079
1080 /// A general purpose block, containing fields and possibly a list of declared identifiers. Semantic
1081 /// is given with the storage qualifier.
1082 #[derive(Clone, Debug, PartialEq)]
1083 pub struct Block {
1084 pub qualifier: TypeQualifier,
1085 pub name: Identifier,
1086 pub fields: Vec<StructFieldSpecifier>,
1087 pub identifier: Option<ArrayedIdentifier>,
1088 }
1089
1090 /// Function identifier.
1091 #[derive(Clone, Debug, PartialEq)]
1092 pub enum FunIdentifier {
1093 Identifier(SymRef),
1094 Constructor(Type),
1095 }
1096
1097 /// Function prototype.
1098 #[derive(Clone, Debug, PartialEq)]
1099 pub struct FunctionPrototype {
1100 pub ty: Type,
1101 pub name: Identifier,
1102 pub parameters: Vec<FunctionParameterDeclaration>,
1103 }
1104
1105 impl FunctionPrototype {
has_parameter(&self, sym: SymRef) -> bool1106 pub fn has_parameter(&self, sym: SymRef) -> bool {
1107 for param in &self.parameters {
1108 match param {
1109 FunctionParameterDeclaration::Named(_, ref d) => {
1110 if d.sym == sym {
1111 return true;
1112 }
1113 }
1114 _ => {}
1115 }
1116 }
1117 false
1118 }
1119 }
1120
1121 /// Function parameter declaration.
1122 #[derive(Clone, Debug, PartialEq)]
1123 pub enum FunctionParameterDeclaration {
1124 Named(Option<ParameterQualifier>, FunctionParameterDeclarator),
1125 Unnamed(Option<ParameterQualifier>, TypeSpecifier),
1126 }
1127
1128 /// Function parameter declarator.
1129 #[derive(Clone, Debug, PartialEq)]
1130 pub struct FunctionParameterDeclarator {
1131 pub ty: Type,
1132 pub name: Identifier,
1133 pub sym: SymRef,
1134 }
1135
1136 /// Init declarator list.
1137 #[derive(Clone, Debug, PartialEq)]
1138 pub struct InitDeclaratorList {
1139 // XXX it feels like separating out the type and the names is better than
1140 // head and tail
1141 // Also, it might be nice to separate out type definitions from name definitions
1142 pub head: SingleDeclaration,
1143 pub tail: Vec<SingleDeclarationNoType>,
1144 }
1145
1146 /// Type qualifier.
1147 #[derive(Clone, Debug, PartialEq)]
1148 pub struct TypeQualifier {
1149 pub qualifiers: NonEmpty<TypeQualifierSpec>,
1150 }
1151
lift_type_qualifier_for_declaration( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<TypeQualifier>1152 fn lift_type_qualifier_for_declaration(
1153 _state: &mut State,
1154 q: &Option<syntax::TypeQualifier>,
1155 ) -> Option<TypeQualifier> {
1156 q.as_ref().and_then(|x| {
1157 NonEmpty::from_non_empty_iter(x.qualifiers.0.iter().flat_map(|x| match x {
1158 syntax::TypeQualifierSpec::Precision(_) => None,
1159 syntax::TypeQualifierSpec::Interpolation(_) => None,
1160 syntax::TypeQualifierSpec::Invariant => Some(TypeQualifierSpec::Invariant),
1161 syntax::TypeQualifierSpec::Layout(l) => Some(TypeQualifierSpec::Layout(l.clone())),
1162 syntax::TypeQualifierSpec::Precise => Some(TypeQualifierSpec::Precise),
1163 syntax::TypeQualifierSpec::Storage(_) => None,
1164 }))
1165 .map(|x| TypeQualifier { qualifiers: x })
1166 })
1167 }
1168
lift_type_qualifier_for_parameter( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<ParameterQualifier>1169 fn lift_type_qualifier_for_parameter(
1170 _state: &mut State,
1171 q: &Option<syntax::TypeQualifier>,
1172 ) -> Option<ParameterQualifier> {
1173 let mut qp: Option<ParameterQualifier> = None;
1174 if let Some(q) = q {
1175 for x in &q.qualifiers.0 {
1176 match (&qp, x) {
1177 (None, syntax::TypeQualifierSpec::Storage(s)) => match s {
1178 syntax::StorageQualifier::Const => qp = Some(ParameterQualifier::Const),
1179 syntax::StorageQualifier::In => qp = Some(ParameterQualifier::In),
1180 syntax::StorageQualifier::Out => qp = Some(ParameterQualifier::Out),
1181 syntax::StorageQualifier::InOut => qp = Some(ParameterQualifier::InOut),
1182 _ => panic!("Bad storage qualifier for parameter"),
1183 },
1184 (_, syntax::TypeQualifierSpec::Precision(_)) => {}
1185 _ => panic!("Bad parameter qualifier {:?}", x),
1186 }
1187 }
1188 }
1189 qp
1190 }
1191
1192 #[derive(Clone, Debug, PartialEq)]
1193 pub enum ParameterQualifier {
1194 Const,
1195 In,
1196 InOut,
1197 Out,
1198 }
1199
1200 #[derive(Clone, Debug, PartialEq)]
1201 pub enum MemoryQualifier {
1202 Coherent,
1203 Volatile,
1204 Restrict,
1205 ReadOnly,
1206 WriteOnly,
1207 }
1208
1209 /// Type qualifier spec.
1210 #[derive(Clone, Debug, PartialEq)]
1211 pub enum TypeQualifierSpec {
1212 Layout(syntax::LayoutQualifier),
1213 Invariant,
1214 Parameter(ParameterQualifier),
1215 Memory(MemoryQualifier),
1216 Precise,
1217 }
1218
1219 /// Single declaration.
1220 #[derive(Clone, Debug, PartialEq)]
1221 pub struct SingleDeclaration {
1222 pub ty: Type,
1223 pub ty_def: Option<SymRef>,
1224 pub qualifier: Option<TypeQualifier>,
1225 pub name: SymRef,
1226 pub initializer: Option<Initializer>,
1227 }
1228
1229 /// A single declaration with implicit, already-defined type.
1230 #[derive(Clone, Debug, PartialEq)]
1231 pub struct SingleDeclarationNoType {
1232 pub ident: ArrayedIdentifier,
1233 pub initializer: Option<Initializer>,
1234 }
1235
1236 /// Initializer.
1237 #[derive(Clone, Debug, PartialEq)]
1238 pub enum Initializer {
1239 Simple(Box<Expr>),
1240 List(NonEmpty<Initializer>),
1241 }
1242
1243 impl From<Expr> for Initializer {
from(e: Expr) -> Self1244 fn from(e: Expr) -> Self {
1245 Initializer::Simple(Box::new(e))
1246 }
1247 }
1248
1249 #[derive(Clone, Debug, PartialEq)]
1250 pub struct Expr {
1251 pub kind: ExprKind,
1252 pub ty: Type,
1253 }
1254
1255 #[derive(Clone, Debug, PartialEq)]
1256 pub enum FieldSet {
1257 Rgba,
1258 Xyzw,
1259 Stpq,
1260 }
1261
1262 #[derive(Clone, Debug, PartialEq)]
1263 pub struct SwizzleSelector {
1264 pub field_set: FieldSet,
1265 pub components: Vec<i8>,
1266 }
1267
1268 impl SwizzleSelector {
parse(s: &str) -> Self1269 fn parse(s: &str) -> Self {
1270 let mut components = Vec::new();
1271 let mut field_set = Vec::new();
1272
1273 for c in s.chars() {
1274 match c {
1275 'r' => {
1276 components.push(0);
1277 field_set.push(FieldSet::Rgba);
1278 }
1279 'x' => {
1280 components.push(0);
1281 field_set.push(FieldSet::Xyzw);
1282 }
1283 's' => {
1284 components.push(0);
1285 field_set.push(FieldSet::Stpq);
1286 }
1287
1288 'g' => {
1289 components.push(1);
1290 field_set.push(FieldSet::Rgba);
1291 }
1292 'y' => {
1293 components.push(1);
1294 field_set.push(FieldSet::Xyzw);
1295 }
1296 't' => {
1297 components.push(1);
1298 field_set.push(FieldSet::Stpq);
1299 }
1300
1301 'b' => {
1302 components.push(2);
1303 field_set.push(FieldSet::Rgba);
1304 }
1305 'z' => {
1306 components.push(2);
1307 field_set.push(FieldSet::Xyzw);
1308 }
1309 'p' => {
1310 components.push(2);
1311 field_set.push(FieldSet::Stpq);
1312 }
1313
1314 'a' => {
1315 components.push(3);
1316 field_set.push(FieldSet::Rgba);
1317 }
1318 'w' => {
1319 components.push(3);
1320 field_set.push(FieldSet::Xyzw);
1321 }
1322 'q' => {
1323 components.push(3);
1324 field_set.push(FieldSet::Stpq);
1325 }
1326 _ => panic!("bad selector"),
1327 }
1328 }
1329
1330 let first = &field_set[0];
1331 assert!(field_set.iter().all(|item| item == first));
1332 assert!(components.len() <= 4);
1333 SwizzleSelector {
1334 field_set: first.clone(),
1335 components,
1336 }
1337 }
1338
to_string(&self) -> String1339 pub fn to_string(&self) -> String {
1340 let mut s = String::new();
1341 let fs = match self.field_set {
1342 FieldSet::Rgba => ['r', 'g', 'b', 'a'],
1343 FieldSet::Xyzw => ['x', 'y', 'z', 'w'],
1344 FieldSet::Stpq => ['s', 't', 'p', 'q'],
1345 };
1346 for i in &self.components {
1347 s.push(fs[*i as usize])
1348 }
1349 s
1350 }
1351 }
1352
1353 /// The most general form of an expression. As you can see if you read the variant list, in GLSL, an
1354 /// assignment is an expression. This is a bit silly but think of an assignment as a statement first
1355 /// then an expression which evaluates to what the statement “returns”.
1356 ///
1357 /// An expression is either an assignment or a list (comma) of assignments.
1358 #[derive(Clone, Debug, PartialEq)]
1359 pub enum ExprKind {
1360 /// A variable expression, using an identifier.
1361 Variable(SymRef),
1362 /// Integral constant expression.
1363 IntConst(i32),
1364 /// Unsigned integral constant expression.
1365 UIntConst(u32),
1366 /// Boolean constant expression.
1367 BoolConst(bool),
1368 /// Single precision floating expression.
1369 FloatConst(f32),
1370 /// Double precision floating expression.
1371 DoubleConst(f64),
1372 /// A unary expression, gathering a single expression and a unary operator.
1373 Unary(UnaryOp, Box<Expr>),
1374 /// A binary expression, gathering two expressions and a binary operator.
1375 Binary(BinaryOp, Box<Expr>, Box<Expr>),
1376 /// A ternary conditional expression, gathering three expressions.
1377 Ternary(Box<Expr>, Box<Expr>, Box<Expr>),
1378 /// An assignment is also an expression. Gathers an expression that defines what to assign to, an
1379 /// assignment operator and the value to associate with.
1380 Assignment(Box<Expr>, AssignmentOp, Box<Expr>),
1381 /// Add an array specifier to an expression.
1382 Bracket(Box<Expr>, Box<Expr>),
1383 /// A functional call. It has a function identifier and a list of expressions (arguments).
1384 FunCall(FunIdentifier, Vec<Expr>),
1385 /// An expression associated with a field selection (struct).
1386 Dot(Box<Expr>, Identifier),
1387 /// An expression associated with a component selection
1388 SwizzleSelector(Box<Expr>, SwizzleSelector),
1389 /// Post-incrementation of an expression.
1390 PostInc(Box<Expr>),
1391 /// Post-decrementation of an expression.
1392 PostDec(Box<Expr>),
1393 /// An expression that contains several, separated with comma.
1394 Comma(Box<Expr>, Box<Expr>),
1395 /// A temporary condition variable
1396 Cond(usize, Box<Expr>),
1397 CondMask,
1398 }
1399
1400 /*
1401 impl From<i32> for Expr {
1402 fn from(x: i32) -> Expr {
1403 ExprKind::IntConst(x)
1404 }
1405 }
1406
1407 impl From<u32> for Expr {
1408 fn from(x: u32) -> Expr {
1409 Expr::UIntConst(x)
1410 }
1411 }
1412
1413 impl From<bool> for Expr {
1414 fn from(x: bool) -> Expr {
1415 Expr::BoolConst(x)
1416 }
1417 }
1418
1419 impl From<f32> for Expr {
1420 fn from(x: f32) -> Expr {
1421 Expr::FloatConst(x)
1422 }
1423 }
1424
1425 impl From<f64> for Expr {
1426 fn from(x: f64) -> Expr {
1427 Expr::DoubleConst(x)
1428 }
1429 }
1430 */
1431 /// Starting rule.
1432 #[derive(Clone, Debug, PartialEq)]
1433 pub struct TranslationUnit(pub NonEmpty<ExternalDeclaration>);
1434
1435 impl TranslationUnit {
1436 /// Construct a translation unit from an iterator.
1437 ///
1438 /// # Errors
1439 ///
1440 /// `None` if the iterator yields no value.
from_iter<I>(iter: I) -> Option<Self> where I: IntoIterator<Item = ExternalDeclaration>,1441 pub fn from_iter<I>(iter: I) -> Option<Self>
1442 where
1443 I: IntoIterator<Item = ExternalDeclaration>,
1444 {
1445 NonEmpty::from_non_empty_iter(iter).map(TranslationUnit)
1446 }
1447 }
1448
1449 impl Deref for TranslationUnit {
1450 type Target = NonEmpty<ExternalDeclaration>;
1451
deref(&self) -> &Self::Target1452 fn deref(&self) -> &Self::Target {
1453 &self.0
1454 }
1455 }
1456
1457 impl DerefMut for TranslationUnit {
deref_mut(&mut self) -> &mut Self::Target1458 fn deref_mut(&mut self) -> &mut Self::Target {
1459 &mut self.0
1460 }
1461 }
1462
1463 impl IntoIterator for TranslationUnit {
1464 type IntoIter = <NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1465 type Item = ExternalDeclaration;
1466
into_iter(self) -> Self::IntoIter1467 fn into_iter(self) -> Self::IntoIter {
1468 self.0.into_iter()
1469 }
1470 }
1471
1472 impl<'a> IntoIterator for &'a TranslationUnit {
1473 type IntoIter = <&'a NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1474 type Item = &'a ExternalDeclaration;
1475
into_iter(self) -> Self::IntoIter1476 fn into_iter(self) -> Self::IntoIter {
1477 (&self.0).into_iter()
1478 }
1479 }
1480
1481 impl<'a> IntoIterator for &'a mut TranslationUnit {
1482 type IntoIter = <&'a mut NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1483 type Item = &'a mut ExternalDeclaration;
1484
into_iter(self) -> Self::IntoIter1485 fn into_iter(self) -> Self::IntoIter {
1486 (&mut self.0).into_iter()
1487 }
1488 }
1489
1490 /// External declaration.
1491 #[derive(Clone, Debug, PartialEq)]
1492 pub enum ExternalDeclaration {
1493 Preprocessor(syntax::Preprocessor),
1494 FunctionDefinition(Rc<FunctionDefinition>),
1495 Declaration(Declaration),
1496 }
1497
1498 /// Function definition.
1499 #[derive(Clone, Debug, PartialEq)]
1500 pub struct FunctionDefinition {
1501 pub prototype: FunctionPrototype,
1502 pub body: CompoundStatement,
1503 pub globals: Vec<SymRef>,
1504 pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
1505 }
1506
1507 /// Compound statement (with no new scope).
1508 #[derive(Clone, Debug, PartialEq)]
1509 pub struct CompoundStatement {
1510 pub statement_list: Vec<Statement>,
1511 }
1512
1513 impl CompoundStatement {
new() -> Self1514 pub fn new() -> Self {
1515 CompoundStatement {
1516 statement_list: Vec::new(),
1517 }
1518 }
1519 }
1520
1521 impl FromIterator<Statement> for CompoundStatement {
from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = Statement>,1522 fn from_iter<T>(iter: T) -> Self
1523 where
1524 T: IntoIterator<Item = Statement>,
1525 {
1526 CompoundStatement {
1527 statement_list: iter.into_iter().collect(),
1528 }
1529 }
1530 }
1531
1532 /// Statement.
1533 #[derive(Clone, Debug, PartialEq)]
1534 pub enum Statement {
1535 Compound(Box<CompoundStatement>),
1536 Simple(Box<SimpleStatement>),
1537 }
1538
1539 /// Simple statement.
1540 #[derive(Clone, Debug, PartialEq)]
1541 pub enum SimpleStatement {
1542 Declaration(Declaration),
1543 Expression(ExprStatement),
1544 Selection(SelectionStatement),
1545 Switch(SwitchStatement),
1546 Iteration(IterationStatement),
1547 Jump(JumpStatement),
1548 }
1549
1550 impl SimpleStatement {
1551 /// Create a new expression statement.
new_expr<E>(expr: E) -> Self where E: Into<Expr>,1552 pub fn new_expr<E>(expr: E) -> Self
1553 where
1554 E: Into<Expr>,
1555 {
1556 SimpleStatement::Expression(Some(expr.into()))
1557 }
1558
1559 /// Create a new selection statement (if / else).
new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self where If: Into<Expr>, True: Into<Statement>, False: Into<Statement>,1560 pub fn new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self
1561 where
1562 If: Into<Expr>,
1563 True: Into<Statement>,
1564 False: Into<Statement>,
1565 {
1566 SimpleStatement::Selection(SelectionStatement {
1567 cond: Box::new(ife.into()),
1568 body: Box::new(truee.into()),
1569 else_stmt: Some(Box::new(falsee.into())),
1570 })
1571 }
1572
1573 /// Create a new while statement.
new_while<C, S>(cond: C, body: S) -> Self where C: Into<Condition>, S: Into<Statement>,1574 pub fn new_while<C, S>(cond: C, body: S) -> Self
1575 where
1576 C: Into<Condition>,
1577 S: Into<Statement>,
1578 {
1579 SimpleStatement::Iteration(IterationStatement::While(
1580 cond.into(),
1581 Box::new(body.into()),
1582 ))
1583 }
1584
1585 /// Create a new do-while statement.
new_do_while<C, S>(body: S, cond: C) -> Self where S: Into<Statement>, C: Into<Expr>,1586 pub fn new_do_while<C, S>(body: S, cond: C) -> Self
1587 where
1588 S: Into<Statement>,
1589 C: Into<Expr>,
1590 {
1591 SimpleStatement::Iteration(IterationStatement::DoWhile(
1592 Box::new(body.into()),
1593 Box::new(cond.into()),
1594 ))
1595 }
1596 }
1597
1598 /// Expression statement.
1599 pub type ExprStatement = Option<Expr>;
1600
1601 /// Selection statement.
1602 #[derive(Clone, Debug, PartialEq)]
1603 pub struct SelectionStatement {
1604 pub cond: Box<Expr>,
1605 pub body: Box<Statement>,
1606 // the else branch
1607 pub else_stmt: Option<Box<Statement>>,
1608 }
1609
1610 /// Condition.
1611 #[derive(Clone, Debug, PartialEq)]
1612 pub enum Condition {
1613 Expr(Box<Expr>),
1614 }
1615
1616 impl From<Expr> for Condition {
from(expr: Expr) -> Self1617 fn from(expr: Expr) -> Self {
1618 Condition::Expr(Box::new(expr))
1619 }
1620 }
1621
1622 /// Switch statement.
1623 #[derive(Clone, Debug, PartialEq)]
1624 pub struct SwitchStatement {
1625 pub head: Box<Expr>,
1626 pub cases: Vec<Case>,
1627 }
1628
1629 /// Case label statement.
1630 #[derive(Clone, Debug, PartialEq)]
1631 pub enum CaseLabel {
1632 Case(Box<Expr>),
1633 Def,
1634 }
1635
1636 /// An individual case
1637 #[derive(Clone, Debug, PartialEq)]
1638 pub struct Case {
1639 pub label: CaseLabel,
1640 pub stmts: Vec<Statement>,
1641 }
1642
1643 /// Iteration statement.
1644 #[derive(Clone, Debug, PartialEq)]
1645 pub enum IterationStatement {
1646 While(Condition, Box<Statement>),
1647 DoWhile(Box<Statement>, Box<Expr>),
1648 For(ForInitStatement, ForRestStatement, Box<Statement>),
1649 }
1650
1651 /// For init statement.
1652 #[derive(Clone, Debug, PartialEq)]
1653 pub enum ForInitStatement {
1654 Expression(Option<Expr>),
1655 Declaration(Box<Declaration>),
1656 }
1657
1658 /// For init statement.
1659 #[derive(Clone, Debug, PartialEq)]
1660 pub struct ForRestStatement {
1661 pub condition: Option<Condition>,
1662 pub post_expr: Option<Box<Expr>>,
1663 }
1664
1665 /// Jump statement.
1666 #[derive(Clone, Debug, PartialEq)]
1667 pub enum JumpStatement {
1668 Continue,
1669 Break,
1670 Return(Option<Box<Expr>>),
1671 Discard,
1672 }
1673
1674 trait NonEmptyExt<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>1675 fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>;
new(x: T) -> NonEmpty<T>1676 fn new(x: T) -> NonEmpty<T>;
1677 }
1678
1679 impl<T> NonEmptyExt<T> for NonEmpty<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U>1680 fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U> {
1681 NonEmpty::from_non_empty_iter(self.into_iter().map(|x| f(s, &x))).unwrap()
1682 }
new(x: T) -> NonEmpty<T>1683 fn new(x: T) -> NonEmpty<T> {
1684 NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap()
1685 }
1686 }
1687
translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer1688 fn translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer {
1689 match i {
1690 syntax::Initializer::Simple(i) => {
1691 Initializer::Simple(Box::new(translate_expression(state, i)))
1692 }
1693 _ => panic!(),
1694 }
1695 }
1696
translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration1697 fn translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration {
1698 let ty = d.ty.clone();
1699 let ty_def = match &ty.ty.ty {
1700 TypeSpecifierNonArray::Struct(s) => {
1701 let decl = SymDecl::Struct(lift(state, s));
1702 Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1703 }
1704 _ => None,
1705 };
1706
1707 let ty_def = ty_def.expect("Must be type definition");
1708
1709 Declaration::StructDefinition(ty_def)
1710 }
1711
get_expr_index(e: &syntax::Expr) -> i321712 fn get_expr_index(e: &syntax::Expr) -> i32 {
1713 match e {
1714 syntax::Expr::IntConst(i) => *i,
1715 syntax::Expr::UIntConst(u) => *u as i32,
1716 syntax::Expr::FloatConst(f) => *f as i32,
1717 syntax::Expr::DoubleConst(f) => *f as i32,
1718 _ => panic!(),
1719 }
1720 }
1721
translate_variable_declaration( state: &mut State, d: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1722 fn translate_variable_declaration(
1723 state: &mut State,
1724 d: &syntax::InitDeclaratorList,
1725 default_run_class: RunClass,
1726 ) -> Declaration {
1727 let mut ty = d.head.ty.clone();
1728 ty.ty.array_specifier = d.head.array_specifier.clone();
1729 let ty_def = match &ty.ty.ty {
1730 TypeSpecifierNonArray::Struct(s) => {
1731 let decl = SymDecl::Struct(lift(state, s));
1732 Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1733 }
1734 _ => None,
1735 };
1736
1737 let mut ty: Type = lift(state, &d.head.ty);
1738 if let Some(array) = &d.head.array_specifier {
1739 ty.array_sizes = Some(Box::new(lift(state, array)))
1740 }
1741
1742 let (sym, decl) = match d.head.name.as_ref() {
1743 Some(name) => {
1744 let mut storage = StorageClass::None;
1745 let mut interpolation = None;
1746 for qual in d
1747 .head
1748 .ty
1749 .qualifier
1750 .iter()
1751 .flat_map(|x| x.qualifiers.0.iter())
1752 {
1753 match qual {
1754 syntax::TypeQualifierSpec::Storage(s) => match (&storage, s) {
1755 (StorageClass::FragColor(..), syntax::StorageQualifier::Out) => {}
1756 (StorageClass::Sampler(..), syntax::StorageQualifier::Uniform) => {}
1757 (StorageClass::None, syntax::StorageQualifier::Out) => {
1758 storage = StorageClass::Out;
1759 }
1760 (StorageClass::None, syntax::StorageQualifier::In) => {
1761 storage = StorageClass::In;
1762 }
1763 (StorageClass::None, syntax::StorageQualifier::Uniform) => {
1764 if ty.kind.is_sampler() {
1765 storage = StorageClass::Sampler(SamplerFormat::Unknown);
1766 } else {
1767 storage = StorageClass::Uniform;
1768 }
1769 }
1770 (StorageClass::None, syntax::StorageQualifier::Const) => {
1771 storage = StorageClass::Const;
1772 }
1773 _ => panic!("bad storage {:?}", (storage, s)),
1774 },
1775 syntax::TypeQualifierSpec::Interpolation(i) => match (&interpolation, i) {
1776 (None, i) => interpolation = Some(i.clone()),
1777 _ => panic!("multiple interpolation"),
1778 },
1779 syntax::TypeQualifierSpec::Layout(l) => {
1780 let mut loc = -1;
1781 let mut index = -1;
1782 for id in &l.ids {
1783 match id {
1784 syntax::LayoutQualifierSpec::Identifier(ref key, None) => {
1785 match key.as_str() {
1786 "rgba8" => {
1787 storage = StorageClass::Sampler(SamplerFormat::RGBA8);
1788 }
1789 "rgba32f" => {
1790 storage = StorageClass::Sampler(SamplerFormat::RGBA32F);
1791 }
1792 "rgba32i" => {
1793 storage = StorageClass::Sampler(SamplerFormat::RGBA32I);
1794 }
1795 "r8" => {
1796 storage = StorageClass::Sampler(SamplerFormat::R8);
1797 }
1798 "rg8" => {
1799 storage = StorageClass::Sampler(SamplerFormat::RG8);
1800 }
1801 _ => {}
1802 }
1803 }
1804 syntax::LayoutQualifierSpec::Identifier(ref key, Some(ref e)) => {
1805 match key.as_str() {
1806 "location" => {
1807 loc = get_expr_index(e);
1808 }
1809 "index" => {
1810 index = get_expr_index(e);
1811 }
1812 _ => {}
1813 }
1814 }
1815 _ => {}
1816 }
1817 }
1818 if index >= 0 {
1819 assert!(loc == 0);
1820 assert!(index <= 1);
1821 assert!(storage == StorageClass::None);
1822 storage = StorageClass::FragColor(index);
1823 }
1824 }
1825 _ => {}
1826 }
1827 }
1828 let decl = if state.in_function.is_some() {
1829 let run_class = match storage {
1830 StorageClass::Const => RunClass::Scalar,
1831 StorageClass::None => default_run_class,
1832 _ => panic!("bad local storage {:?}", storage),
1833 };
1834 SymDecl::Local(storage, ty.clone(), run_class)
1835 } else {
1836 let run_class = match storage {
1837 StorageClass::Const | StorageClass::Uniform | StorageClass::Sampler(..) => {
1838 RunClass::Scalar
1839 }
1840 StorageClass::In | StorageClass::Out | StorageClass::FragColor(..)
1841 if interpolation == Some(syntax::InterpolationQualifier::Flat) =>
1842 {
1843 RunClass::Scalar
1844 }
1845 _ => RunClass::Vector,
1846 };
1847 SymDecl::Global(storage, interpolation, ty.clone(), run_class)
1848 };
1849 (state.declare(name.as_str(), decl.clone()), decl)
1850 }
1851 None => panic!(),
1852 };
1853
1854 let head = SingleDeclaration {
1855 qualifier: lift_type_qualifier_for_declaration(state, &d.head.ty.qualifier),
1856 name: sym,
1857 ty,
1858 ty_def,
1859 initializer: d
1860 .head
1861 .initializer
1862 .as_ref()
1863 .map(|x| translate_initializater(state, x)),
1864 };
1865
1866 let tail = d
1867 .tail
1868 .iter()
1869 .map(|d| {
1870 if let Some(_array) = &d.ident.array_spec {
1871 panic!("unhandled array")
1872 }
1873 state.declare(d.ident.ident.as_str(), decl.clone());
1874 SingleDeclarationNoType {
1875 ident: d.ident.clone(),
1876 initializer: d
1877 .initializer
1878 .as_ref()
1879 .map(|x| translate_initializater(state, x)),
1880 }
1881 })
1882 .collect();
1883 Declaration::InitDeclaratorList(InitDeclaratorList { head, tail })
1884 }
1885
translate_init_declarator_list( state: &mut State, l: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1886 fn translate_init_declarator_list(
1887 state: &mut State,
1888 l: &syntax::InitDeclaratorList,
1889 default_run_class: RunClass,
1890 ) -> Declaration {
1891 match &l.head.name {
1892 Some(_name) => translate_variable_declaration(state, l, default_run_class),
1893 None => translate_struct_declaration(state, &l.head),
1894 }
1895 }
1896
translate_declaration( state: &mut State, d: &syntax::Declaration, default_run_class: RunClass, ) -> Declaration1897 fn translate_declaration(
1898 state: &mut State,
1899 d: &syntax::Declaration,
1900 default_run_class: RunClass,
1901 ) -> Declaration {
1902 match d {
1903 syntax::Declaration::Block(_) => panic!(), //Declaration::Block(..),
1904 syntax::Declaration::FunctionPrototype(p) => {
1905 Declaration::FunctionPrototype(translate_function_prototype(state, p))
1906 }
1907 syntax::Declaration::Global(ty, ids) => {
1908 // glsl non-es supports requalifying variables, but we don't yet.
1909 // However, we still want to allow global layout qualifiers for
1910 // KHR_advanced_blend_equation.
1911 if !ids.is_empty() {
1912 panic!();
1913 }
1914 let _ = for qual in &ty.qualifiers {
1915 match qual {
1916 syntax::TypeQualifierSpec::Layout(l) => {
1917 for id in &l.ids {
1918 match id {
1919 syntax::LayoutQualifierSpec::Identifier(key, _) => {
1920 match key.as_str() {
1921 "blend_support_all_equations" => (),
1922 _ => panic!(),
1923 }
1924 }
1925 _ => panic!(),
1926 }
1927 }
1928 }
1929 syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out) => (),
1930 _ => panic!(),
1931 }
1932 };
1933 Declaration::Global(lift_type_qualifier_for_declaration(state, &Some(ty.clone())).unwrap(), ids.clone())
1934 }
1935 syntax::Declaration::InitDeclaratorList(dl) => {
1936 translate_init_declarator_list(state, dl, default_run_class)
1937 }
1938 syntax::Declaration::Precision(p, ts) => Declaration::Precision(p.clone(), ts.clone()),
1939 }
1940 }
1941
is_vector(ty: &Type) -> bool1942 fn is_vector(ty: &Type) -> bool {
1943 match ty.kind {
1944 TypeKind::Vec2
1945 | TypeKind::Vec3
1946 | TypeKind::Vec4
1947 | TypeKind::BVec2
1948 | TypeKind::BVec3
1949 | TypeKind::BVec4
1950 | TypeKind::IVec2
1951 | TypeKind::IVec3
1952 | TypeKind::IVec4 => ty.array_sizes == None,
1953 _ => false,
1954 }
1955 }
1956
index_vector(ty: &Type) -> Option<TypeKind>1957 fn index_vector(ty: &Type) -> Option<TypeKind> {
1958 use TypeKind::*;
1959 if ty.array_sizes != None {
1960 return None;
1961 }
1962 Some(match ty.kind {
1963 Vec2 => Float,
1964 Vec3 => Float,
1965 Vec4 => Float,
1966 DVec2 => Double,
1967 DVec3 => Double,
1968 DVec4 => Double,
1969 BVec2 => Bool,
1970 BVec3 => Bool,
1971 BVec4 => Bool,
1972 IVec2 => Int,
1973 IVec3 => Int,
1974 IVec4 => Int,
1975 UVec2 => UInt,
1976 UVec3 => UInt,
1977 UVec4 => UInt,
1978 _ => return None,
1979 })
1980
1981 }
1982
index_matrix(ty: &Type) -> Option<TypeKind>1983 fn index_matrix(ty: &Type) -> Option<TypeKind> {
1984 use TypeKind::*;
1985 if ty.array_sizes != None {
1986 return None;
1987 }
1988 Some(match ty.kind {
1989 Mat2 => Vec2,
1990 Mat3 => Vec3,
1991 Mat4 => Vec4,
1992 Mat23 => Vec3,
1993 Mat24 => Vec4,
1994 Mat32 => Vec2,
1995 Mat34 => Vec4,
1996 Mat42 => Vec2,
1997 Mat43 => Vec3,
1998 DMat2 => DVec2,
1999 DMat3 => DVec3,
2000 DMat4 => DVec4,
2001 DMat23 => DVec3,
2002 DMat24 => DVec4,
2003 DMat32 => DVec2,
2004 DMat34 => DVec4,
2005 DMat42 => DVec2,
2006 DMat43 => DVec3,
2007 _ => return None,
2008 })
2009 }
2010
is_ivec(ty: &Type) -> bool2011 fn is_ivec(ty: &Type) -> bool {
2012 match ty.kind {
2013 TypeKind::IVec2 | TypeKind::IVec3 | TypeKind::IVec4 => ty.array_sizes == None,
2014 _ => false,
2015 }
2016 }
2017
can_implicitly_convert_to(src: &Type, dst: &Type) -> bool2018 fn can_implicitly_convert_to(src: &Type, dst: &Type) -> bool {
2019 // XXX: use an underlying type helper
2020 if src == &Type::new(TypeKind::Double) && dst == &Type::new(TypeKind::Float) {
2021 // We're not supposed to implicitly convert from double to float but glsl 4 has a bug
2022 // where it parses unannotated float constants as double.
2023 true
2024 } else if dst == &Type::new(TypeKind::Double) && src == &Type::new(TypeKind::Float) {
2025 true
2026 } else if (dst == &Type::new(TypeKind::Float) || dst == &Type::new(TypeKind::Double)) &&
2027 src == &Type::new(TypeKind::Int)
2028 {
2029 true
2030 } else if (dst == &Type::new(TypeKind::Vec2) || dst == &Type::new(TypeKind::DVec2)) &&
2031 src == &Type::new(TypeKind::IVec2)
2032 {
2033 true
2034 } else if dst == &Type::new(TypeKind::IVec2) &&
2035 (src == &Type::new(TypeKind::Vec2) || src == &Type::new(TypeKind::DVec2))
2036 {
2037 true
2038 } else {
2039 src.kind == dst.kind && src.array_sizes == dst.array_sizes
2040 }
2041 }
2042
promoted_type(lhs: &Type, rhs: &Type) -> Type2043 fn promoted_type(lhs: &Type, rhs: &Type) -> Type {
2044 if lhs == &Type::new(TypeKind::Double) && rhs == &Type::new(TypeKind::Float) {
2045 Type::new(TypeKind::Double)
2046 } else if lhs == &Type::new(TypeKind::Float) && rhs == &Type::new(TypeKind::Double) {
2047 Type::new(TypeKind::Double)
2048 } else if lhs == &Type::new(TypeKind::Int) && rhs == &Type::new(TypeKind::Double) {
2049 Type::new(TypeKind::Double)
2050 } else if is_vector(&lhs) &&
2051 (rhs == &Type::new(TypeKind::Float) ||
2052 rhs == &Type::new(TypeKind::Double) ||
2053 rhs == &Type::new(TypeKind::Int))
2054 {
2055 // scalars promote to vectors
2056 lhs.clone()
2057 } else if is_vector(&rhs) &&
2058 (lhs == &Type::new(TypeKind::Float) ||
2059 lhs == &Type::new(TypeKind::Double) ||
2060 lhs == &Type::new(TypeKind::Int))
2061 {
2062 // scalars promote to vectors
2063 rhs.clone()
2064 } else if lhs == rhs {
2065 lhs.clone()
2066 } else if lhs.kind == rhs.kind {
2067 if lhs.array_sizes == rhs.array_sizes {
2068 // XXX: we need to be able to query the default precision here
2069 match (&lhs.precision, &rhs.precision) {
2070 (Some(PrecisionQualifier::High), _) => lhs.clone(),
2071 (_, Some(PrecisionQualifier::High)) => rhs.clone(),
2072 (None, _) => lhs.clone(),
2073 (_, None) => rhs.clone(),
2074 _ => panic!("precision mismatch {:?} {:?}", lhs.precision, rhs.precision),
2075 }
2076 } else {
2077 panic!("array size mismatch")
2078 }
2079 } else {
2080 assert_eq!(lhs, rhs);
2081 lhs.clone()
2082 }
2083 }
2084
is_output(expr: &Expr, state: &State) -> Option<SymRef>2085 pub fn is_output(expr: &Expr, state: &State) -> Option<SymRef> {
2086 match &expr.kind {
2087 ExprKind::Variable(i) => match state.sym(*i).decl {
2088 SymDecl::Global(storage, ..) => match storage {
2089 StorageClass::In | StorageClass::Out => return Some(*i),
2090 _ => {}
2091 },
2092 SymDecl::Local(..) => {}
2093 _ => panic!("should be variable"),
2094 },
2095 ExprKind::SwizzleSelector(e, ..) => {
2096 return is_output(e, state);
2097 }
2098 ExprKind::Bracket(e, ..) => {
2099 return is_output(e, state);
2100 }
2101 ExprKind::Dot(e, ..) => {
2102 return is_output(e, state);
2103 }
2104 _ => {}
2105 };
2106 None
2107 }
2108
get_texel_fetch_offset( state: &State, sampler_expr: &Expr, uv_expr: &Expr, offset_expr: &Expr, ) -> Option<(SymRef, SymRef, i32, i32)>2109 pub fn get_texel_fetch_offset(
2110 state: &State,
2111 sampler_expr: &Expr,
2112 uv_expr: &Expr,
2113 offset_expr: &Expr,
2114 ) -> Option<(SymRef, SymRef, i32, i32)> {
2115 if let ExprKind::Variable(ref sampler) = &sampler_expr.kind {
2116 //if let ExprKind::Binary(BinaryOp::Add, ref lhs, ref rhs) = &uv_expr.kind {
2117 if let ExprKind::Variable(ref base) = &uv_expr.kind {
2118 if let ExprKind::FunCall(ref fun, ref args) = &offset_expr.kind {
2119 if let FunIdentifier::Identifier(ref offset) = fun {
2120 if state.sym(*offset).name == "ivec2" {
2121 if let ExprKind::IntConst(ref x) = &args[0].kind {
2122 if let ExprKind::IntConst(ref y) = &args[1].kind {
2123 return Some((*sampler, *base, *x, *y));
2124 }
2125 }
2126 }
2127 }
2128 }
2129 }
2130 //}
2131 }
2132 None
2133 }
2134
make_const(t: TypeKind, v: i32) -> Expr2135 fn make_const(t: TypeKind, v: i32) -> Expr {
2136 Expr {
2137 kind: match t {
2138 TypeKind::Int => ExprKind::IntConst(v as _),
2139 TypeKind::UInt => ExprKind::UIntConst(v as _),
2140 TypeKind::Bool => ExprKind::BoolConst(v != 0),
2141 TypeKind::Float => ExprKind::FloatConst(v as _),
2142 TypeKind::Double => ExprKind::DoubleConst(v as _),
2143 _ => panic!("bad constant type"),
2144 },
2145 ty: Type::new(t),
2146 }
2147 }
2148
2149 // Any parameters needing to convert to bool should just compare via != 0.
2150 // This ensures they get the proper all-1s pattern for C++ OpenCL vectors.
force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>)2151 fn force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>) {
2152 for e in params {
2153 if !e.ty.kind.is_bool() {
2154 let k = e.ty.kind;
2155 *e = Expr {
2156 kind: ExprKind::Binary(
2157 BinaryOp::NonEqual,
2158 Box::new(e.clone()),
2159 Box::new(make_const(k.to_scalar(), 0)),
2160 ),
2161 ty: Type::new(k.to_bool()),
2162 };
2163 }
2164 }
2165 }
2166
2167 // Transform bool params to int, then mask off the low bit so they become 0 or 1.
2168 // C++ OpenCL vectors represent bool as all-1s patterns, which will erroneously
2169 // convert to -1 otherwise.
force_params_from_bool(state: &mut State, params: &mut Vec<Expr>)2170 fn force_params_from_bool(state: &mut State, params: &mut Vec<Expr>) {
2171 for e in params {
2172 if e.ty.kind.is_bool() {
2173 let k = e.ty.kind.to_int();
2174 let sym = state.lookup(k.glsl_primitive_type_name().unwrap()).unwrap();
2175 *e = Expr {
2176 kind: ExprKind::Binary(
2177 BinaryOp::BitAnd,
2178 Box::new(Expr {
2179 kind: ExprKind::FunCall(
2180 FunIdentifier::Identifier(sym),
2181 vec![e.clone()],
2182 ),
2183 ty: Type::new(k),
2184 }),
2185 Box::new(make_const(TypeKind::Int, 1)),
2186 ),
2187 ty: Type::new(k),
2188 };
2189 }
2190 }
2191 }
2192
translate_expression(state: &mut State, e: &syntax::Expr) -> Expr2193 fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
2194 match e {
2195 syntax::Expr::Variable(i) => {
2196 let sym = match state.lookup(i.as_str()) {
2197 Some(sym) => sym,
2198 None => panic!("missing declaration {}", i.as_str()),
2199 };
2200 let ty = match &state.sym(sym).decl {
2201 SymDecl::Global(_, _, ty, _) => {
2202 let mut globals = state.used_globals.borrow_mut();
2203 if !globals.contains(&sym) {
2204 globals.push(sym);
2205 }
2206 ty.clone()
2207 }
2208 SymDecl::Local(_, ty, _) => ty.clone(),
2209 _ => panic!("bad variable type"),
2210 };
2211 Expr {
2212 kind: ExprKind::Variable(sym),
2213 ty,
2214 }
2215 }
2216 syntax::Expr::Assignment(lhs, op, rhs) => {
2217 let lhs = Box::new(translate_expression(state, lhs));
2218 let rhs = Box::new(translate_expression(state, rhs));
2219 let ty = if op == &AssignmentOp::Mult {
2220 if lhs.ty.kind == TypeKind::Vec4 && rhs.ty.kind == TypeKind::Float {
2221 lhs.ty.clone()
2222 } else {
2223 promoted_type(&lhs.ty, &rhs.ty)
2224 }
2225 } else {
2226 promoted_type(&lhs.ty, &rhs.ty)
2227 };
2228 if let Some(global) = is_output(&lhs, state) {
2229 let mut globals = state.modified_globals.borrow_mut();
2230 if !globals.contains(&global) {
2231 globals.push(global);
2232 }
2233 if global == state.clip_dist_sym {
2234 if let ExprKind::Bracket(_, idx) = &lhs.kind {
2235 // Get the constant array index used for gl_ClipDistance and add it to the used mask.
2236 let idx = match idx.kind {
2237 ExprKind::IntConst(idx) => idx,
2238 ExprKind::UIntConst(idx) => idx as i32,
2239 _ => panic!("bad index for gl_ClipDistance"),
2240 };
2241 assert!(idx >= 0 && idx < 4);
2242 state.used_clip_dist |= 1 << idx;
2243 }
2244 }
2245 }
2246 Expr {
2247 kind: ExprKind::Assignment(lhs, op.clone(), rhs),
2248 ty,
2249 }
2250 }
2251 syntax::Expr::Binary(op, lhs, rhs) => {
2252 let lhs = Box::new(translate_expression(state, lhs));
2253 let rhs = Box::new(translate_expression(state, rhs));
2254 let ty = match op {
2255 BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
2256 // comparison operators have a bool result
2257 Type::new(TypeKind::Bool)
2258 }
2259 BinaryOp::Mult => {
2260 match (lhs.ty.kind, rhs.ty.kind) {
2261 (TypeKind::Mat2, TypeKind::Vec2) |
2262 (TypeKind::Mat3, TypeKind::Vec3) |
2263 (TypeKind::Mat3, TypeKind::Mat3) |
2264 (TypeKind::Mat3, TypeKind::Mat43) |
2265 (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
2266 (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3),
2267 (TypeKind::Mat2, TypeKind::Float) |
2268 (TypeKind::Mat3, TypeKind::Float) |
2269 (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
2270 _ => promoted_type(&lhs.ty, &rhs.ty),
2271 }
2272 }
2273 _ => promoted_type(&lhs.ty, &rhs.ty),
2274 };
2275
2276 Expr {
2277 kind: ExprKind::Binary(op.clone(), lhs, rhs),
2278 ty,
2279 }
2280 }
2281 syntax::Expr::Unary(op, e) => {
2282 let e = Box::new(translate_expression(state, e));
2283 let ty = e.ty.clone();
2284 Expr {
2285 kind: ExprKind::Unary(op.clone(), e),
2286 ty,
2287 }
2288 }
2289 syntax::Expr::BoolConst(b) => Expr {
2290 kind: ExprKind::BoolConst(*b),
2291 ty: Type::new(TypeKind::Bool),
2292 },
2293 syntax::Expr::Comma(lhs, rhs) => {
2294 let lhs = Box::new(translate_expression(state, lhs));
2295 let rhs = Box::new(translate_expression(state, rhs));
2296 assert_eq!(lhs.ty, rhs.ty);
2297 let ty = lhs.ty.clone();
2298 Expr {
2299 kind: ExprKind::Comma(lhs, rhs),
2300 ty,
2301 }
2302 }
2303 syntax::Expr::DoubleConst(d) => Expr {
2304 kind: ExprKind::DoubleConst(*d),
2305 ty: Type::new(TypeKind::Double),
2306 },
2307 syntax::Expr::FloatConst(f) => Expr {
2308 kind: ExprKind::FloatConst(*f),
2309 ty: Type::new(TypeKind::Float),
2310 },
2311 syntax::Expr::FunCall(fun, params) => {
2312 let ret_ty: Type;
2313 let mut params: Vec<Expr> = params
2314 .iter()
2315 .map(|x| translate_expression(state, x))
2316 .collect();
2317 Expr {
2318 kind: ExprKind::FunCall(
2319 match fun {
2320 syntax::FunIdentifier::Identifier(i) => {
2321 let name = i.as_str();
2322 if name == "texelFetchOffset" && params.len() >= 4 {
2323 if let Some((sampler, base, x, y)) = get_texel_fetch_offset(
2324 state, ¶ms[0], ¶ms[1], ¶ms[3],
2325 ) {
2326 if let Some(offsets) =
2327 state.texel_fetches.get_mut(&(sampler, base))
2328 {
2329 offsets.add_offset(x, y);
2330 } else {
2331 state
2332 .texel_fetches
2333 .insert((sampler, base), TexelFetchOffsets::new(x, y));
2334 }
2335 }
2336 } else if name == "swgl_stepInterp" {
2337 let mut globals = state.modified_globals.borrow_mut();
2338 for (i, sym) in state.syms.iter().enumerate() {
2339 match &sym.borrow().decl {
2340 SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
2341 let symref = SymRef(i as u32);
2342 if !globals.contains(&symref) {
2343 globals.push(symref);
2344 }
2345 }
2346 _ => {}
2347 }
2348 }
2349 }
2350 let sym = match state.lookup(name) {
2351 Some(s) => s,
2352 None => panic!("missing symbol {}", name),
2353 };
2354 // Force any boolean basic type constructors to generate correct
2355 // bit patterns.
2356 if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) {
2357 if t.is_bool() {
2358 force_params_to_bool(state, &mut params);
2359 } else {
2360 force_params_from_bool(state, &mut params);
2361 }
2362 }
2363 match &state.sym(sym).decl {
2364 SymDecl::NativeFunction(fn_ty, _, _) => {
2365 // Search for a signature where all parameter types are
2366 // compatible. If there are many compatible signatures,
2367 // then choose the one with the most exact matches.
2368 // This is an approximation of the algorith described in
2369 // the "Function Definitions" section of the spec.
2370 let mut ret = None;
2371 let mut best_score = 0;
2372 'next_sig: for sig in &fn_ty.signatures {
2373 let mut score = 0;
2374 for (e, p) in params.iter().zip(sig.params.iter()) {
2375 if e.ty == *p {
2376 score += 1;
2377 } else if !can_implicitly_convert_to(&e.ty, p) {
2378 continue 'next_sig;
2379 }
2380 }
2381 if score >= best_score {
2382 ret = Some(sig.ret.clone());
2383 best_score = score;
2384 // If all parameters match exactly, then there
2385 // is no need to search for other matches.
2386 if best_score >= params.len() {
2387 break;
2388 }
2389 }
2390 }
2391 ret_ty = match ret {
2392 Some(t) => t,
2393 None => {
2394 dbg!(&fn_ty.signatures);
2395 dbg!(params.iter().map(|p| p).collect::<Vec<_>>());
2396 panic!("no matching func {}", i.as_str())
2397 }
2398 };
2399 }
2400 SymDecl::UserFunction(fd, _) => {
2401 let mut globals = state.modified_globals.borrow_mut();
2402 for global in &fd.globals {
2403 if !globals.contains(global) {
2404 globals.push(*global);
2405 }
2406 }
2407 let mut matching = true;
2408 for (e, p) in params.iter().zip(fd.prototype.parameters.iter())
2409 {
2410 matching &= match p {
2411 FunctionParameterDeclaration::Named(q, d) => {
2412 match q {
2413 Some(ParameterQualifier::InOut)
2414 | Some(ParameterQualifier::Out) => {
2415 if let Some(global) = is_output(e, state) {
2416 if !globals.contains(&global) {
2417 globals.push(global);
2418 }
2419 }
2420 }
2421 _ => {}
2422 }
2423 can_implicitly_convert_to(&e.ty, &d.ty)
2424 }
2425 FunctionParameterDeclaration::Unnamed(..) => panic!(),
2426 };
2427 }
2428 assert!(matching);
2429 ret_ty = fd.prototype.ty.clone();
2430 }
2431 SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)),
2432 _ => panic!("can only call functions"),
2433 };
2434 FunIdentifier::Identifier(sym)
2435 }
2436 // array constructor
2437 syntax::FunIdentifier::Expr(e) => {
2438 let ty = match &**e {
2439 syntax::Expr::Bracket(i, array) => {
2440 let kind = match &**i {
2441 syntax::Expr::Variable(i) => match i.as_str() {
2442 "vec4" => TypeKind::Vec4,
2443 "vec2" => TypeKind::Vec2,
2444 "int" => TypeKind::Int,
2445 _ => panic!("unexpected type constructor {:?}", i),
2446 },
2447 _ => panic!(),
2448 };
2449
2450 Type {
2451 kind,
2452 precision: None,
2453 array_sizes: Some(Box::new(lift(state, array))),
2454 }
2455 }
2456 _ => panic!(),
2457 };
2458 ret_ty = ty.clone();
2459
2460 FunIdentifier::Constructor(ty)
2461 }
2462 },
2463 params,
2464 ),
2465 ty: ret_ty,
2466 }
2467 }
2468 syntax::Expr::IntConst(i) => Expr {
2469 kind: ExprKind::IntConst(*i),
2470 ty: Type::new(TypeKind::Int),
2471 },
2472 syntax::Expr::UIntConst(u) => Expr {
2473 kind: ExprKind::UIntConst(*u),
2474 ty: Type::new(TypeKind::UInt),
2475 },
2476 syntax::Expr::PostDec(e) => {
2477 let e = Box::new(translate_expression(state, e));
2478 let ty = e.ty.clone();
2479 Expr {
2480 kind: ExprKind::PostDec(e),
2481 ty,
2482 }
2483 }
2484 syntax::Expr::PostInc(e) => {
2485 let e = Box::new(translate_expression(state, e));
2486 let ty = e.ty.clone();
2487 Expr {
2488 kind: ExprKind::PostInc(e),
2489 ty,
2490 }
2491 }
2492 syntax::Expr::Ternary(cond, lhs, rhs) => {
2493 let cond = Box::new(translate_expression(state, cond));
2494 let lhs = Box::new(translate_expression(state, lhs));
2495 let rhs = Box::new(translate_expression(state, rhs));
2496 let ty = promoted_type(&lhs.ty, &rhs.ty);
2497 Expr {
2498 kind: ExprKind::Ternary(cond, lhs, rhs),
2499 ty,
2500 }
2501 }
2502 syntax::Expr::Dot(e, i) => {
2503 let e = Box::new(translate_expression(state, e));
2504 let ty = e.ty.clone();
2505 let ivec = is_ivec(&ty);
2506 if is_vector(&ty) {
2507 let ty = Type::new(match i.as_str().len() {
2508 1 => {
2509 if ivec {
2510 TypeKind::Int
2511 } else {
2512 TypeKind::Float
2513 }
2514 }
2515 2 => {
2516 if ivec {
2517 TypeKind::IVec2
2518 } else {
2519 TypeKind::Vec2
2520 }
2521 }
2522 3 => {
2523 if ivec {
2524 TypeKind::IVec3
2525 } else {
2526 TypeKind::Vec3
2527 }
2528 }
2529 4 => {
2530 if ivec {
2531 TypeKind::IVec4
2532 } else {
2533 TypeKind::Vec4
2534 }
2535 }
2536 _ => panic!(),
2537 });
2538
2539 let sel = SwizzleSelector::parse(i.as_str());
2540
2541 Expr {
2542 kind: ExprKind::SwizzleSelector(e, sel),
2543 ty,
2544 }
2545 } else {
2546 match ty.kind {
2547 TypeKind::Struct(s) => {
2548 let sym = state.sym(s);
2549 let fields = match &sym.decl {
2550 SymDecl::Struct(fields) => fields,
2551 _ => panic!("expected struct"),
2552 };
2553 let field = fields
2554 .fields
2555 .iter()
2556 .find(|x| &x.name == i)
2557 .expect(&format!("missing field `{}` in `{}`", i, sym.name));
2558 Expr {
2559 kind: ExprKind::Dot(e, i.clone()),
2560 ty: field.ty.clone(),
2561 }
2562 }
2563 _ => panic!("expected struct found {:#?} {:#?}", e, ty),
2564 }
2565 }
2566 }
2567 syntax::Expr::Bracket(e, specifier) => {
2568 let e = Box::new(translate_expression(state, e));
2569 let ty = if let Some(ty) = index_vector(&e.ty) {
2570 Type::new(ty)
2571 } else if let Some(ty) = index_matrix(&e.ty) {
2572 Type::new(ty)
2573 } else {
2574 let a = match &e.ty.array_sizes {
2575 Some(a) => {
2576 let mut a = *a.clone();
2577 a.sizes.pop();
2578 if a.sizes.len() == 0 {
2579 None
2580 } else {
2581 Some(Box::new(a))
2582 }
2583 }
2584 _ => panic!("{:#?}", e),
2585 };
2586 Type {
2587 kind: e.ty.kind.clone(),
2588 precision: e.ty.precision.clone(),
2589 array_sizes: a,
2590 }
2591 };
2592 let indx = match specifier {
2593 ArraySpecifier::Unsized => panic!("need expression"),
2594 ArraySpecifier::ExplicitlySized(e) => translate_expression(state, e),
2595 };
2596 Expr {
2597 kind: ExprKind::Bracket(e, Box::new(indx)),
2598 ty,
2599 }
2600 }
2601 }
2602 }
2603
translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement2604 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement {
2605 let mut cases = Vec::new();
2606
2607 let mut case = None;
2608 for stmt in &s.body {
2609 match stmt {
2610 syntax::Statement::Simple(s) => match &**s {
2611 syntax::SimpleStatement::CaseLabel(label) => {
2612 match case.take() {
2613 Some(case) => cases.push(case),
2614 _ => {}
2615 }
2616 case = Some(Case {
2617 label: translate_case(state, &label),
2618 stmts: Vec::new(),
2619 })
2620 }
2621 _ => match case {
2622 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2623 _ => panic!("switch must start with case"),
2624 },
2625 },
2626 _ => match case {
2627 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2628 _ => panic!("switch must start with case"),
2629 },
2630 }
2631 }
2632 match case.take() {
2633 Some(case) => cases.push(case),
2634 _ => {}
2635 }
2636 SwitchStatement {
2637 head: Box::new(translate_expression(state, &s.head)),
2638 cases,
2639 }
2640 }
2641
translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement2642 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement {
2643 match s {
2644 syntax::JumpStatement::Break => JumpStatement::Break,
2645 syntax::JumpStatement::Continue => JumpStatement::Continue,
2646 syntax::JumpStatement::Discard => JumpStatement::Discard,
2647 syntax::JumpStatement::Return(e) => {
2648 JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e))))
2649 }
2650 }
2651 }
2652
translate_condition(state: &mut State, c: &syntax::Condition) -> Condition2653 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition {
2654 match c {
2655 syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))),
2656 _ => panic!(),
2657 }
2658 }
2659
translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement2660 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement {
2661 match s {
2662 syntax::ForInitStatement::Expression(e) => {
2663 ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2664 }
2665 syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new(
2666 translate_declaration(state, d, RunClass::Scalar),
2667 )),
2668 }
2669 }
2670
translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement2671 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement {
2672 ForRestStatement {
2673 condition: s.condition.as_ref().map(|c| translate_condition(state, c)),
2674 post_expr: s
2675 .post_expr
2676 .as_ref()
2677 .map(|e| Box::new(translate_expression(state, e))),
2678 }
2679 }
2680
translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement2681 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement {
2682 match s {
2683 syntax::IterationStatement::While(cond, s) => IterationStatement::While(
2684 translate_condition(state, cond),
2685 Box::new(translate_statement(state, s)),
2686 ),
2687 syntax::IterationStatement::For(init, rest, s) => IterationStatement::For(
2688 translate_for_init(state, init),
2689 translate_for_rest(state, rest),
2690 Box::new(translate_statement(state, s)),
2691 ),
2692 syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile(
2693 Box::new(translate_statement(state, s)),
2694 Box::new(translate_expression(state, e)),
2695 ),
2696 }
2697 }
2698
translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel2699 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel {
2700 match c {
2701 syntax::CaseLabel::Def => CaseLabel::Def,
2702 syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))),
2703 }
2704 }
2705
translate_selection_rest( state: &mut State, s: &syntax::SelectionRestStatement, ) -> (Box<Statement>, Option<Box<Statement>>)2706 fn translate_selection_rest(
2707 state: &mut State,
2708 s: &syntax::SelectionRestStatement,
2709 ) -> (Box<Statement>, Option<Box<Statement>>) {
2710 match s {
2711 syntax::SelectionRestStatement::Statement(s) => {
2712 (Box::new(translate_statement(state, s)), None)
2713 }
2714 syntax::SelectionRestStatement::Else(if_body, rest) => (
2715 Box::new(translate_statement(state, if_body)),
2716 Some(Box::new(translate_statement(state, rest))),
2717 ),
2718 }
2719 }
2720
translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement2721 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement {
2722 let cond = Box::new(translate_expression(state, &s.cond));
2723 let (body, else_stmt) = translate_selection_rest(state, &s.rest);
2724 SelectionStatement {
2725 cond,
2726 body,
2727 else_stmt,
2728 }
2729 }
2730
translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement2731 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement {
2732 match s {
2733 syntax::SimpleStatement::Declaration(d) => {
2734 SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown))
2735 }
2736 syntax::SimpleStatement::Expression(e) => {
2737 SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2738 }
2739 syntax::SimpleStatement::Iteration(i) => {
2740 SimpleStatement::Iteration(translate_iteration(state, i))
2741 }
2742 syntax::SimpleStatement::Selection(s) => {
2743 SimpleStatement::Selection(translate_selection(state, s))
2744 }
2745 syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)),
2746 syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)),
2747 syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"),
2748 }
2749 }
2750
translate_statement(state: &mut State, s: &syntax::Statement) -> Statement2751 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement {
2752 match s {
2753 syntax::Statement::Compound(s) => {
2754 Statement::Compound(Box::new(translate_compound_statement(state, s)))
2755 }
2756 syntax::Statement::Simple(s) => {
2757 Statement::Simple(Box::new(translate_simple_statement(state, s)))
2758 }
2759 }
2760 }
2761
translate_compound_statement( state: &mut State, cs: &syntax::CompoundStatement, ) -> CompoundStatement2762 fn translate_compound_statement(
2763 state: &mut State,
2764 cs: &syntax::CompoundStatement,
2765 ) -> CompoundStatement {
2766 CompoundStatement {
2767 statement_list: cs
2768 .statement_list
2769 .iter()
2770 .map(|x| translate_statement(state, x))
2771 .collect(),
2772 }
2773 }
2774
translate_function_parameter_declaration( state: &mut State, p: &syntax::FunctionParameterDeclaration, index: usize, ) -> FunctionParameterDeclaration2775 fn translate_function_parameter_declaration(
2776 state: &mut State,
2777 p: &syntax::FunctionParameterDeclaration,
2778 index: usize,
2779 ) -> FunctionParameterDeclaration {
2780 match p {
2781 syntax::FunctionParameterDeclaration::Named(qual, p) => {
2782 let mut ty: Type = lift(state, &p.ty);
2783 if let Some(a) = &p.ident.array_spec {
2784 ty.array_sizes = Some(Box::new(lift(state, a)));
2785 }
2786
2787 ty.precision = get_precision(qual);
2788
2789 let decl = SymDecl::Local(
2790 StorageClass::None,
2791 ty.clone(),
2792 RunClass::Dependent(1 << index),
2793 );
2794 let d = FunctionParameterDeclarator {
2795 ty,
2796 name: p.ident.ident.clone(),
2797 sym: state.declare(p.ident.ident.as_str(), decl),
2798 };
2799 FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d)
2800 }
2801 syntax::FunctionParameterDeclaration::Unnamed(qual, p) => {
2802 FunctionParameterDeclaration::Unnamed(
2803 lift_type_qualifier_for_parameter(state, qual),
2804 p.clone(),
2805 )
2806 }
2807 }
2808 }
2809
translate_prototype( state: &mut State, cs: &syntax::FunctionPrototype, ) -> (FunctionPrototype, SymRef)2810 fn translate_prototype(
2811 state: &mut State,
2812 cs: &syntax::FunctionPrototype,
2813 ) -> (FunctionPrototype, SymRef) {
2814 let prototype = FunctionPrototype {
2815 ty: lift(state, &cs.ty),
2816 name: cs.name.clone(),
2817 parameters: cs
2818 .parameters
2819 .iter()
2820 .enumerate()
2821 .map(|(i, x)| translate_function_parameter_declaration(state, x, i))
2822 .collect(),
2823 };
2824 let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) {
2825 match &state.sym(sym).decl {
2826 SymDecl::UserFunction(..) => {}
2827 _ => panic!(
2828 "prototype conflicts with existing symbol: {}",
2829 prototype.name.as_str()
2830 ),
2831 }
2832 sym
2833 } else {
2834 let pfd = Rc::new(FunctionDefinition {
2835 prototype: prototype.clone(),
2836 body: CompoundStatement::new(),
2837 globals: Vec::new(),
2838 texel_fetches: HashMap::new(),
2839 });
2840 state.declare(
2841 prototype.name.as_str(),
2842 SymDecl::UserFunction(pfd, RunClass::Unknown),
2843 )
2844 };
2845 (prototype, sym)
2846 }
2847
translate_function_prototype( state: &mut State, prototype: &syntax::FunctionPrototype, ) -> FunctionPrototype2848 fn translate_function_prototype(
2849 state: &mut State,
2850 prototype: &syntax::FunctionPrototype,
2851 ) -> FunctionPrototype {
2852 let (prototype, _) = translate_prototype(state, prototype);
2853 prototype
2854 }
2855
translate_function_definition( state: &mut State, sfd: &syntax::FunctionDefinition, ) -> Rc<FunctionDefinition>2856 fn translate_function_definition(
2857 state: &mut State,
2858 sfd: &syntax::FunctionDefinition,
2859 ) -> Rc<FunctionDefinition> {
2860 let (prototype, sym) = translate_prototype(state, &sfd.prototype);
2861
2862 state.push_scope(prototype.name.as_str().into());
2863 state.in_function = Some(sym);
2864 state.modified_globals.get_mut().clear();
2865 state.texel_fetches.clear();
2866 let body = translate_compound_statement(state, &sfd.statement);
2867 let mut globals = Vec::new();
2868 mem::swap(&mut globals, state.modified_globals.get_mut());
2869 let mut texel_fetches = HashMap::new();
2870 mem::swap(&mut texel_fetches, &mut state.texel_fetches);
2871 state.in_function = None;
2872 state.pop_scope();
2873
2874 let fd = Rc::new(FunctionDefinition {
2875 prototype,
2876 body,
2877 globals,
2878 texel_fetches,
2879 });
2880 state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown);
2881 fd
2882 }
2883
translate_external_declaration( state: &mut State, ed: &syntax::ExternalDeclaration, ) -> ExternalDeclaration2884 fn translate_external_declaration(
2885 state: &mut State,
2886 ed: &syntax::ExternalDeclaration,
2887 ) -> ExternalDeclaration {
2888 match ed {
2889 syntax::ExternalDeclaration::Declaration(d) => {
2890 ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown))
2891 }
2892 syntax::ExternalDeclaration::FunctionDefinition(fd) => {
2893 ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd))
2894 }
2895 syntax::ExternalDeclaration::Preprocessor(p) => {
2896 ExternalDeclaration::Preprocessor(p.clone())
2897 }
2898 }
2899 }
2900
declare_function_ext( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, run_class: RunClass, )2901 fn declare_function_ext(
2902 state: &mut State,
2903 name: &str,
2904 cxx_name: Option<&'static str>,
2905 ret: Type,
2906 params: Vec<Type>,
2907 run_class: RunClass,
2908 ) {
2909 let sig = FunctionSignature { ret, params };
2910 match state.lookup_sym_mut(name) {
2911 Some(Symbol {
2912 decl: SymDecl::NativeFunction(f, ..),
2913 ..
2914 }) => f.signatures.push(sig),
2915 None => {
2916 state.declare(
2917 name,
2918 SymDecl::NativeFunction(
2919 FunctionType {
2920 signatures: NonEmpty::new(sig),
2921 },
2922 cxx_name,
2923 run_class,
2924 ),
2925 );
2926 }
2927 _ => panic!("overloaded function name {}", name),
2928 }
2929 //state.declare(name, Type::Function(FunctionType{ v}))
2930 }
2931
declare_function( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, )2932 fn declare_function(
2933 state: &mut State,
2934 name: &str,
2935 cxx_name: Option<&'static str>,
2936 ret: Type,
2937 params: Vec<Type>,
2938 ) {
2939 declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
2940 }
2941
ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit2942 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
2943 // global scope
2944 state.push_scope("global".into());
2945 use TypeKind::*;
2946 declare_function(
2947 state,
2948 "vec2",
2949 Some("make_vec2"),
2950 Type::new(Vec2),
2951 vec![Type::new(Float)],
2952 );
2953 declare_function(
2954 state,
2955 "vec2",
2956 Some("make_vec2"),
2957 Type::new(Vec2),
2958 vec![Type::new(Float), Type::new(Float)],
2959 );
2960 declare_function(
2961 state,
2962 "vec2",
2963 Some("make_vec2"),
2964 Type::new(Vec2),
2965 vec![Type::new(IVec2)],
2966 );
2967 declare_function(
2968 state,
2969 "vec2",
2970 Some("make_vec2"),
2971 Type::new(Vec2),
2972 vec![Type::new(IVec3)],
2973 );
2974 declare_function(
2975 state,
2976 "vec3",
2977 Some("make_vec3"),
2978 Type::new(Vec3),
2979 vec![Type::new(Float), Type::new(Float), Type::new(Float)],
2980 );
2981 declare_function(
2982 state,
2983 "vec3",
2984 Some("make_vec3"),
2985 Type::new(Vec3),
2986 vec![Type::new(Float)],
2987 );
2988 declare_function(
2989 state,
2990 "vec3",
2991 Some("make_vec3"),
2992 Type::new(Vec3),
2993 vec![Type::new(Vec2), Type::new(Float)],
2994 );
2995 declare_function(
2996 state,
2997 "vec4",
2998 Some("make_vec4"),
2999 Type::new(Vec4),
3000 vec![Type::new(Float)],
3001 );
3002 declare_function(
3003 state,
3004 "vec4",
3005 Some("make_vec4"),
3006 Type::new(Vec4),
3007 vec![Type::new(Vec3), Type::new(Float)],
3008 );
3009 declare_function(
3010 state,
3011 "vec4",
3012 Some("make_vec4"),
3013 Type::new(Vec4),
3014 vec![
3015 Type::new(Float),
3016 Type::new(Float),
3017 Type::new(Float),
3018 Type::new(Float),
3019 ],
3020 );
3021 declare_function(
3022 state,
3023 "vec4",
3024 Some("make_vec4"),
3025 Type::new(Vec4),
3026 vec![Type::new(Vec2), Type::new(Float), Type::new(Float)],
3027 );
3028 declare_function(
3029 state,
3030 "vec4",
3031 Some("make_vec4"),
3032 Type::new(Vec4),
3033 vec![Type::new(Vec2), Type::new(Vec2)],
3034 );
3035 declare_function(
3036 state,
3037 "vec4",
3038 Some("make_vec4"),
3039 Type::new(Vec4),
3040 vec![Type::new(Float), Type::new(Float), Type::new(Vec2)],
3041 );
3042 declare_function(
3043 state,
3044 "vec4",
3045 Some("make_vec4"),
3046 Type::new(Vec4),
3047 vec![Type::new(Vec4)],
3048 );
3049 declare_function(
3050 state,
3051 "vec4",
3052 Some("make_vec4"),
3053 Type::new(Vec4),
3054 vec![Type::new(IVec4)],
3055 );
3056
3057 declare_function(
3058 state,
3059 "bvec2",
3060 Some("make_bvec2"),
3061 Type::new(BVec2),
3062 vec![Type::new(Bool)],
3063 );
3064 declare_function(
3065 state,
3066 "bvec3",
3067 Some("make_bvec3"),
3068 Type::new(BVec3),
3069 vec![Type::new(Bool)],
3070 );
3071 declare_function(
3072 state,
3073 "bvec4",
3074 Some("make_bvec4"),
3075 Type::new(BVec4),
3076 vec![Type::new(Bool)],
3077 );
3078 declare_function(
3079 state,
3080 "bvec4",
3081 Some("make_bvec4"),
3082 Type::new(BVec4),
3083 vec![Type::new(BVec2), Type::new(BVec2)],
3084 );
3085 declare_function(
3086 state,
3087 "bvec4",
3088 Some("make_bvec4"),
3089 Type::new(BVec4),
3090 vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
3091 );
3092 declare_function(
3093 state,
3094 "int",
3095 Some("make_int"),
3096 Type::new(Int),
3097 vec![Type::new(Float)],
3098 );
3099 declare_function(
3100 state,
3101 "float",
3102 Some("make_float"),
3103 Type::new(Float),
3104 vec![Type::new(Float)],
3105 );
3106 declare_function(
3107 state,
3108 "float",
3109 Some("make_float"),
3110 Type::new(Float),
3111 vec![Type::new(Int)],
3112 );
3113 declare_function(
3114 state,
3115 "int",
3116 Some("make_int"),
3117 Type::new(Int),
3118 vec![Type::new(UInt)],
3119 );
3120 declare_function(
3121 state,
3122 "uint",
3123 Some("make_uint"),
3124 Type::new(UInt),
3125 vec![Type::new(Float)],
3126 );
3127 declare_function(
3128 state,
3129 "uint",
3130 Some("make_uint"),
3131 Type::new(UInt),
3132 vec![Type::new(Int)],
3133 );
3134 declare_function(
3135 state,
3136 "ivec2",
3137 Some("make_ivec2"),
3138 Type::new(IVec2),
3139 vec![Type::new(UInt), Type::new(UInt)],
3140 );
3141 declare_function(
3142 state,
3143 "ivec2",
3144 Some("make_ivec2"),
3145 Type::new(IVec2),
3146 vec![Type::new(Int), Type::new(Int)],
3147 );
3148 declare_function(
3149 state,
3150 "ivec2",
3151 Some("make_ivec2"),
3152 Type::new(IVec2),
3153 vec![Type::new(Vec2)],
3154 );
3155 declare_function(
3156 state,
3157 "ivec3",
3158 Some("make_ivec3"),
3159 Type::new(IVec3),
3160 vec![Type::new(IVec2), Type::new(Int)],
3161 );
3162 declare_function(
3163 state,
3164 "ivec4",
3165 Some("make_ivec4"),
3166 Type::new(IVec4),
3167 vec![
3168 Type::new(Int),
3169 Type::new(Int),
3170 Type::new(Int),
3171 Type::new(Int),
3172 ],
3173 );
3174 declare_function(
3175 state,
3176 "ivec4",
3177 Some("make_ivec4"),
3178 Type::new(IVec4),
3179 vec![Type::new(Vec4)],
3180 );
3181 declare_function(
3182 state,
3183 "ivec4",
3184 Some("make_ivec4"),
3185 Type::new(IVec4),
3186 vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
3187 );
3188
3189 declare_function(
3190 state,
3191 "mat2",
3192 Some("make_mat2"),
3193 Type::new(Mat2),
3194 vec![Type::new(Vec2), Type::new(Vec2)],
3195 );
3196 declare_function(
3197 state,
3198 "mat2",
3199 Some("make_mat2"),
3200 Type::new(Mat2),
3201 vec![Type::new(Float)],
3202 );
3203 declare_function(
3204 state,
3205 "mat2",
3206 Some("make_mat2"),
3207 Type::new(Mat2),
3208 vec![Type::new(Mat4)],
3209 );
3210 declare_function(
3211 state,
3212 "mat3",
3213 Some("make_mat3"),
3214 Type::new(Mat3),
3215 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3216 );
3217 declare_function(
3218 state,
3219 "mat3",
3220 Some("make_mat3"),
3221 Type::new(Mat3),
3222 vec![Type::new(Mat4)],
3223 );
3224 declare_function(
3225 state,
3226 "mat3",
3227 Some("make_mat3"),
3228 Type::new(Mat3),
3229 vec![
3230 Type::new(Float),
3231 Type::new(Float),
3232 Type::new(Float),
3233 Type::new(Float),
3234 Type::new(Float),
3235 Type::new(Float),
3236 Type::new(Float),
3237 Type::new(Float),
3238 Type::new(Float),
3239 ],
3240 );
3241 declare_function(
3242 state,
3243 "mat3x4",
3244 Some("make_mat3x4"),
3245 Type::new(Mat34),
3246 vec![
3247 Type::new(Float),
3248 Type::new(Float),
3249 Type::new(Float),
3250 Type::new(Float),
3251
3252 Type::new(Float),
3253 Type::new(Float),
3254 Type::new(Float),
3255 Type::new(Float),
3256
3257 Type::new(Float),
3258 Type::new(Float),
3259 Type::new(Float),
3260 Type::new(Float),
3261 ],
3262 );
3263 declare_function(
3264 state,
3265 "transpose",
3266 None,
3267 Type::new(Mat43),
3268 vec![Type::new(Mat34)],
3269 );
3270 declare_function(
3271 state,
3272 "mat4",
3273 Some("make_mat4"),
3274 Type::new(Mat4),
3275 vec![
3276 Type::new(Vec4),
3277 Type::new(Vec4),
3278 Type::new(Vec4),
3279 Type::new(Vec4),
3280 ],
3281 );
3282 declare_function(
3283 state,
3284 "mat4",
3285 Some("make_mat4"),
3286 Type::new(Mat4),
3287 vec![
3288 Type::new(Float),
3289 Type::new(Float),
3290 Type::new(Float),
3291 Type::new(Float),
3292 Type::new(Float),
3293 Type::new(Float),
3294 Type::new(Float),
3295 Type::new(Float),
3296 Type::new(Float),
3297 Type::new(Float),
3298 Type::new(Float),
3299 Type::new(Float),
3300 Type::new(Float),
3301 Type::new(Float),
3302 Type::new(Float),
3303 Type::new(Float),
3304 ],
3305 );
3306 declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3307 declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3308 declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
3309 declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3310 declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3311 declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
3312 declare_function(
3313 state,
3314 "dot",
3315 None,
3316 Type::new(Float),
3317 vec![Type::new(Vec3), Type::new(Vec3)],
3318 );
3319 declare_function(
3320 state,
3321 "dot",
3322 None,
3323 Type::new(Float),
3324 vec![Type::new(Vec2), Type::new(Vec2)],
3325 );
3326 for t in &[Vec2, Vec3, Vec4] {
3327 declare_function(
3328 state,
3329 "min",
3330 None,
3331 Type::new(*t),
3332 vec![Type::new(*t), Type::new(Float)],
3333 );
3334 declare_function(
3335 state,
3336 "max",
3337 None,
3338 Type::new(*t),
3339 vec![Type::new(*t), Type::new(Float)],
3340 );
3341 }
3342 for t in &[Int, Float, Vec2, Vec3, Vec4] {
3343 declare_function(
3344 state,
3345 "min",
3346 None,
3347 Type::new(*t),
3348 vec![Type::new(*t), Type::new(*t)],
3349 );
3350 declare_function(
3351 state,
3352 "max",
3353 None,
3354 Type::new(*t),
3355 vec![Type::new(*t), Type::new(*t)],
3356 );
3357 }
3358
3359 declare_function(
3360 state,
3361 "mix",
3362 None,
3363 Type::new(Vec2),
3364 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3365 );
3366 declare_function(
3367 state,
3368 "mix",
3369 None,
3370 Type::new(Vec2),
3371 vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)],
3372 );
3373 declare_function(
3374 state,
3375 "mix",
3376 None,
3377 Type::new(Vec2),
3378 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
3379 );
3380 declare_function(
3381 state,
3382 "mix",
3383 None,
3384 Type::new(Vec3),
3385 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3386 );
3387 declare_function(
3388 state,
3389 "mix",
3390 None,
3391 Type::new(Vec4),
3392 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
3393 );
3394 declare_function(
3395 state,
3396 "mix",
3397 None,
3398 Type::new(Vec4),
3399 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)],
3400 );
3401 declare_function(
3402 state,
3403 "mix",
3404 None,
3405 Type::new(Vec3),
3406 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)],
3407 );
3408 declare_function(
3409 state,
3410 "mix",
3411 None,
3412 Type::new(Vec3),
3413 vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)],
3414 );
3415 declare_function(
3416 state,
3417 "mix",
3418 None,
3419 Type::new(Float),
3420 vec![Type::new(Float), Type::new(Float), Type::new(Float)],
3421 );
3422 declare_function(
3423 state,
3424 "mix",
3425 None,
3426 Type::new(Vec4),
3427 vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)],
3428 );
3429 declare_function(
3430 state,
3431 "step",
3432 None,
3433 Type::new(Float),
3434 vec![Type::new(Float), Type::new(Float)],
3435 );
3436 declare_function(
3437 state,
3438 "step",
3439 None,
3440 Type::new(Vec2),
3441 vec![Type::new(Vec2), Type::new(Vec2)],
3442 );
3443 declare_function(
3444 state,
3445 "step",
3446 None,
3447 Type::new(Vec2),
3448 vec![Type::new(Float), Type::new(Vec2)],
3449 );
3450 declare_function(
3451 state,
3452 "step",
3453 None,
3454 Type::new(Vec3),
3455 vec![Type::new(Vec3), Type::new(Vec3)],
3456 );
3457 declare_function(
3458 state,
3459 "step",
3460 None,
3461 Type::new(Vec4),
3462 vec![Type::new(Float), Type::new(Vec4)],
3463 );
3464 declare_function(
3465 state,
3466 "notEqual",
3467 None,
3468 Type::new(BVec4),
3469 vec![Type::new(IVec4), Type::new(IVec4)],
3470 );
3471
3472 declare_function_ext(
3473 state,
3474 "fwidth",
3475 None,
3476 Type::new(Vec2),
3477 vec![Type::new(Vec2)],
3478 RunClass::Scalar,
3479 );
3480 declare_function_ext(
3481 state,
3482 "dFdx",
3483 None,
3484 Type::new(Float),
3485 vec![Type::new(Float)],
3486 RunClass::Scalar,
3487 );
3488 declare_function_ext(
3489 state,
3490 "dFdx",
3491 None,
3492 Type::new(Vec2),
3493 vec![Type::new(Vec2)],
3494 RunClass::Scalar,
3495 );
3496
3497 declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
3498 declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
3499 declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
3500 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
3501 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
3502 for t in &[Vec2, Vec3, Vec4] {
3503 declare_function(
3504 state,
3505 "clamp",
3506 None,
3507 Type::new(*t),
3508 vec![Type::new(*t), Type::new(Float), Type::new(Float)],
3509 );
3510 }
3511 for t in &[Float, Vec2, Vec3, Vec4] {
3512 declare_function(
3513 state,
3514 "clamp",
3515 None,
3516 Type::new(*t),
3517 vec![Type::new(*t), Type::new(*t), Type::new(*t)],
3518 );
3519 }
3520 declare_function(
3521 state,
3522 "length",
3523 None,
3524 Type::new(Float),
3525 vec![Type::new(Vec2)],
3526 );
3527 declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3528 declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
3529 declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
3530 declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
3531 declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
3532 declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
3533 for t in &[Float, Vec2] {
3534 // recip is non-standard
3535 declare_function(
3536 state,
3537 "recip",
3538 None,
3539 Type::new(*t),
3540 vec![Type::new(*t)],
3541 );
3542 declare_function(
3543 state,
3544 "inversesqrt",
3545 None,
3546 Type::new(*t),
3547 vec![Type::new(*t)],
3548 );
3549 declare_function(
3550 state,
3551 "sqrt",
3552 None,
3553 Type::new(*t),
3554 vec![Type::new(*t)],
3555 );
3556 }
3557 declare_function(
3558 state,
3559 "distance",
3560 None,
3561 Type::new(Float),
3562 vec![Type::new(Vec2), Type::new(Vec2)],
3563 );
3564
3565 declare_function(
3566 state,
3567 "equal",
3568 None,
3569 Type::new(BVec2),
3570 vec![Type::new(Vec2), Type::new(Vec2)],
3571 );
3572 declare_function(
3573 state,
3574 "equal",
3575 None,
3576 Type::new(BVec4),
3577 vec![Type::new(Vec4), Type::new(Vec4)],
3578 );
3579 declare_function(
3580 state,
3581 "notEqual",
3582 None,
3583 Type::new(BVec2),
3584 vec![Type::new(Vec2), Type::new(Vec2)],
3585 );
3586 declare_function(
3587 state,
3588 "notEqual",
3589 None,
3590 Type::new(BVec4),
3591 vec![Type::new(Vec4), Type::new(Vec4)],
3592 );
3593 declare_function(
3594 state,
3595 "lessThanEqual",
3596 None,
3597 Type::new(BVec2),
3598 vec![Type::new(Vec2), Type::new(Vec2)],
3599 );
3600 declare_function(
3601 state,
3602 "lessThanEqual",
3603 None,
3604 Type::new(BVec3),
3605 vec![Type::new(Vec3), Type::new(Vec3)],
3606 );
3607 declare_function(
3608 state,
3609 "lessThanEqual",
3610 None,
3611 Type::new(BVec4),
3612 vec![Type::new(Vec4), Type::new(Vec4)],
3613 );
3614 declare_function(
3615 state,
3616 "lessThan",
3617 None,
3618 Type::new(BVec2),
3619 vec![Type::new(Vec2), Type::new(Vec2)],
3620 );
3621 declare_function(
3622 state,
3623 "lessThan",
3624 None,
3625 Type::new(BVec4),
3626 vec![Type::new(Vec4), Type::new(Vec4)],
3627 );
3628 declare_function(
3629 state,
3630 "greaterThan",
3631 None,
3632 Type::new(BVec2),
3633 vec![Type::new(Vec2), Type::new(Vec2)],
3634 );
3635 declare_function(
3636 state,
3637 "greaterThan",
3638 None,
3639 Type::new(BVec4),
3640 vec![Type::new(Vec4), Type::new(Vec4)],
3641 );
3642 declare_function(
3643 state,
3644 "greaterThanEqual",
3645 None,
3646 Type::new(BVec2),
3647 vec![Type::new(Vec2), Type::new(Vec2)],
3648 );
3649 declare_function(
3650 state,
3651 "greaterThanEqual",
3652 None,
3653 Type::new(BVec4),
3654 vec![Type::new(Vec4), Type::new(Vec4)],
3655 );
3656 declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
3657 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]);
3658 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]);
3659
3660 declare_function(
3661 state,
3662 "if_then_else",
3663 None,
3664 Type::new(Vec3),
3665 vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)],
3666 );
3667 declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]);
3668 declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3669 declare_function(
3670 state,
3671 "floor",
3672 None,
3673 Type::new(Float),
3674 vec![Type::new(Float)],
3675 );
3676 declare_function(
3677 state,
3678 "ceil",
3679 None,
3680 Type::new(Float),
3681 vec![Type::new(Float)],
3682 );
3683 declare_function(
3684 state,
3685 "round",
3686 None,
3687 Type::new(Float),
3688 vec![Type::new(Float)],
3689 );
3690 declare_function(
3691 state,
3692 "fract",
3693 None,
3694 Type::new(Float),
3695 vec![Type::new(Float)],
3696 );
3697 declare_function(
3698 state,
3699 "fract",
3700 None,
3701 Type::new(Vec2),
3702 vec![Type::new(Vec2)],
3703 );
3704 declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3705 declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
3706
3707 declare_function(
3708 state,
3709 "texelFetch",
3710 None,
3711 Type::new(Vec4),
3712 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3713 );
3714 declare_function(
3715 state,
3716 "texelFetch",
3717 None,
3718 Type::new(IVec4),
3719 vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
3720 );
3721 declare_function(
3722 state,
3723 "texelFetchOffset",
3724 None,
3725 Type::new(Vec4),
3726 vec![
3727 Type::new(Sampler2D),
3728 Type::new(IVec2),
3729 Type::new(Int),
3730 Type::new(IVec2),
3731 ],
3732 );
3733 declare_function(
3734 state,
3735 "texelFetchOffset",
3736 None,
3737 Type::new(IVec4),
3738 vec![
3739 Type::new(ISampler2D),
3740 Type::new(IVec2),
3741 Type::new(Int),
3742 Type::new(IVec2),
3743 ],
3744 );
3745 declare_function(
3746 state,
3747 "texture",
3748 None,
3749 Type::new(Vec4),
3750 vec![Type::new(Sampler2D), Type::new(Vec2)],
3751 );
3752 declare_function(
3753 state,
3754 "texture",
3755 None,
3756 Type::new(Vec4),
3757 vec![Type::new(Sampler2DRect), Type::new(Vec2)],
3758 );
3759 declare_function(
3760 state,
3761 "textureSize",
3762 None,
3763 Type::new(IVec2),
3764 vec![Type::new(Sampler2D), Type::new(Int)],
3765 );
3766 declare_function(
3767 state,
3768 "textureSize",
3769 None,
3770 Type::new(IVec2),
3771 vec![Type::new(Sampler2DRect), Type::new(Int)],
3772 );
3773
3774 declare_function(
3775 state,
3776 "inverse",
3777 None,
3778 Type::new(Mat2),
3779 vec![Type::new(Mat2)],
3780 );
3781 declare_function(
3782 state,
3783 "transpose",
3784 None,
3785 Type::new(Mat3),
3786 vec![Type::new(Mat3)],
3787 );
3788 declare_function(
3789 state,
3790 "normalize",
3791 None,
3792 Type::new(Vec2),
3793 vec![Type::new(Vec2)],
3794 );
3795 state.declare(
3796 "gl_FragCoord",
3797 SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector),
3798 );
3799 state.declare(
3800 "gl_FragColor",
3801 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3802 );
3803 state.declare(
3804 "gl_Position",
3805 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3806 );
3807 state.clip_dist_sym = state.declare(
3808 "gl_ClipDistance",
3809 SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
3810 );
3811
3812 state.declare(
3813 "swgl_SpanLength",
3814 SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
3815 );
3816 state.declare(
3817 "swgl_StepSize",
3818 SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
3819 );
3820
3821 for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
3822 declare_function_ext(
3823 state,
3824 "swgl_forceScalar",
3825 None,
3826 Type::new(*t),
3827 vec![Type::new(*t)],
3828 RunClass::Scalar,
3829 );
3830 }
3831
3832 // GL_ARB_shader_group_vote
3833 for (name, cxx_name) in &[("anyInvocations", "test_any"),
3834 ("allInvocations", "test_all"),
3835 ("allInvocationsEqual", "test_equal")] {
3836 declare_function_ext(
3837 state,
3838 name,
3839 Some(cxx_name),
3840 Type::new(Bool),
3841 vec![Type::new(Bool)],
3842 RunClass::Scalar,
3843 );
3844 }
3845
3846 declare_function(
3847 state,
3848 "swgl_stepInterp",
3849 None,
3850 Type::new(Void),
3851 vec![],
3852 );
3853
3854 for t in &[Float, Vec2, Vec3, Vec4] {
3855 declare_function_ext(
3856 state,
3857 "swgl_interpStep",
3858 None,
3859 Type::new(*t),
3860 vec![Type::new(*t)],
3861 RunClass::Scalar,
3862 );
3863 }
3864
3865 declare_function(
3866 state,
3867 "swgl_commitPartialSolidRGBA8",
3868 None,
3869 Type::new(Void),
3870 vec![Type::new(Int), Type::new(Vec4)],
3871 );
3872 declare_function(
3873 state,
3874 "swgl_commitPartialSolidR8",
3875 None,
3876 Type::new(Void),
3877 vec![Type::new(Int), Type::new(Float)],
3878 );
3879 declare_function(
3880 state,
3881 "swgl_commitSolidRGBA8",
3882 None,
3883 Type::new(Void),
3884 vec![Type::new(Vec4)],
3885 );
3886 declare_function(
3887 state,
3888 "swgl_commitSolidR8",
3889 None,
3890 Type::new(Void),
3891 vec![Type::new(Float)],
3892 );
3893 declare_function(
3894 state,
3895 "swgl_commitColorRGBA8",
3896 None,
3897 Type::new(Void),
3898 vec![Type::new(Vec4)],
3899 );
3900 declare_function(
3901 state,
3902 "swgl_commitColorR8",
3903 None,
3904 Type::new(Void),
3905 vec![Type::new(Float)],
3906 );
3907 declare_function(
3908 state,
3909 "swgl_blendDropShadow",
3910 None,
3911 Type::new(Void),
3912 vec![Type::new(Vec4)],
3913 );
3914 declare_function(
3915 state,
3916 "swgl_blendSubpixelText",
3917 None,
3918 Type::new(Void),
3919 vec![Type::new(Vec4)],
3920 );
3921 declare_function(
3922 state,
3923 "swgl_clipMask",
3924 None,
3925 Type::new(Void),
3926 vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3927 );
3928 declare_function(
3929 state,
3930 "swgl_antiAlias",
3931 None,
3932 Type::new(Void),
3933 vec![Type::new(Int)],
3934 );
3935 declare_function(
3936 state,
3937 "swgl_antiAlias",
3938 None,
3939 Type::new(Void),
3940 vec![Type::new(BVec4)],
3941 );
3942 declare_function_ext(
3943 state,
3944 "swgl_validateGradient",
3945 None,
3946 Type::new(Int),
3947 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3948 RunClass::Scalar,
3949 );
3950 declare_function(
3951 state,
3952 "swgl_commitLinearGradientRGBA8",
3953 None,
3954 Type::new(Void),
3955 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Float)],
3956 );
3957 declare_function(
3958 state,
3959 "swgl_commitRadialGradientRGBA8",
3960 None,
3961 Type::new(Void),
3962 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
3963 Type::new(Float)],
3964 );
3965 declare_function(
3966 state,
3967 "swgl_commitGradientRGBA8",
3968 None,
3969 Type::new(Void),
3970 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
3971 );
3972 declare_function(
3973 state,
3974 "swgl_commitGradientColorRGBA8",
3975 None,
3976 Type::new(Void),
3977 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
3978 );
3979 for s in &[Sampler2D, Sampler2DRect] {
3980 declare_function_ext(
3981 state,
3982 "swgl_isTextureLinear",
3983 None,
3984 Type::new(Bool),
3985 vec![Type::new(*s)],
3986 RunClass::Scalar,
3987 );
3988 declare_function_ext(
3989 state,
3990 "swgl_isTextureRGBA8",
3991 None,
3992 Type::new(Bool),
3993 vec![Type::new(*s)],
3994 RunClass::Scalar,
3995 );
3996 declare_function_ext(
3997 state,
3998 "swgl_isTextureR8",
3999 None,
4000 Type::new(Bool),
4001 vec![Type::new(*s)],
4002 RunClass::Scalar,
4003 );
4004 declare_function(
4005 state,
4006 "swgl_commitTextureLinearRGBA8",
4007 None,
4008 Type::new(Void),
4009 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4010 );
4011 declare_function(
4012 state,
4013 "swgl_commitTextureLinearR8",
4014 None,
4015 Type::new(Void),
4016 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4017 );
4018 declare_function(
4019 state,
4020 "swgl_commitTextureLinearR8ToRGBA8",
4021 None,
4022 Type::new(Void),
4023 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4024 );
4025 declare_function(
4026 state,
4027 "swgl_commitPartialTextureLinearR8",
4028 None,
4029 Type::new(Void),
4030 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4031 );
4032 declare_function(
4033 state,
4034 "swgl_commitPartialTextureLinearInvertR8",
4035 None,
4036 Type::new(Void),
4037 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4038 );
4039 declare_function(
4040 state,
4041 "swgl_commitTextureLinearColorRGBA8",
4042 None,
4043 Type::new(Void),
4044 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4045 );
4046 declare_function(
4047 state,
4048 "swgl_commitTextureLinearColorRGBA8",
4049 None,
4050 Type::new(Void),
4051 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4052 );
4053 declare_function(
4054 state,
4055 "swgl_commitTextureLinearColorR8",
4056 None,
4057 Type::new(Void),
4058 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4059 );
4060 declare_function(
4061 state,
4062 "swgl_commitTextureLinearColorR8ToRGBA8",
4063 None,
4064 Type::new(Void),
4065 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4066 );
4067
4068 declare_function(
4069 state,
4070 "swgl_commitTextureLinearRepeatRGBA8",
4071 None,
4072 Type::new(Void),
4073 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4074 Type::new(Vec4), Type::new(Vec4)],
4075 );
4076 declare_function(
4077 state,
4078 "swgl_commitTextureLinearRepeatColorRGBA8",
4079 None,
4080 Type::new(Void),
4081 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4082 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4083 );
4084
4085 declare_function(
4086 state,
4087 "swgl_commitTextureNearestRGBA8",
4088 None,
4089 Type::new(Void),
4090 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4091 );
4092 declare_function(
4093 state,
4094 "swgl_commitTextureNearestColorRGBA8",
4095 None,
4096 Type::new(Void),
4097 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4098 );
4099 declare_function(
4100 state,
4101 "swgl_commitTextureNearestRepeatRGBA8",
4102 None,
4103 Type::new(Void),
4104 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4105 Type::new(Vec4), Type::new(Vec4)],
4106 );
4107 declare_function(
4108 state,
4109 "swgl_commitTextureNearestRepeatColorRGBA8",
4110 None,
4111 Type::new(Void),
4112 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4113 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4114 );
4115
4116 declare_function(
4117 state,
4118 "swgl_commitTextureRGBA8",
4119 None,
4120 Type::new(Void),
4121 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4122 );
4123 declare_function(
4124 state,
4125 "swgl_commitTextureColorRGBA8",
4126 None,
4127 Type::new(Void),
4128 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4129 );
4130 declare_function(
4131 state,
4132 "swgl_commitTextureRepeatRGBA8",
4133 None,
4134 Type::new(Void),
4135 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4136 Type::new(Vec4), Type::new(Vec4)],
4137 );
4138 declare_function(
4139 state,
4140 "swgl_commitTextureRepeatColorRGBA8",
4141 None,
4142 Type::new(Void),
4143 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4144 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4145 );
4146
4147 declare_function(
4148 state,
4149 "swgl_commitGaussianBlurRGBA8",
4150 None,
4151 Type::new(Void),
4152 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4153 Type::new(Int), Type::new(Vec2)],
4154 );
4155 declare_function(
4156 state,
4157 "swgl_commitGaussianBlurR8",
4158 None,
4159 Type::new(Void),
4160 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4161 Type::new(Int), Type::new(Vec2)],
4162 );
4163 declare_function(
4164 state,
4165 "swgl_commitTextureLinearYUV",
4166 None,
4167 Type::new(Void),
4168 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4169 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4170 );
4171 declare_function(
4172 state,
4173 "swgl_commitTextureLinearYUV",
4174 None,
4175 Type::new(Void),
4176 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4177 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4178 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4179 );
4180 declare_function(
4181 state,
4182 "swgl_commitTextureLinearYUV",
4183 None,
4184 Type::new(Void),
4185 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4186 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4187 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4188 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4189 );
4190 declare_function(
4191 state,
4192 "swgl_commitTextureLinearColorYUV",
4193 None,
4194 Type::new(Void),
4195 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4196 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4197 Type::new(Float)],
4198 );
4199 declare_function(
4200 state,
4201 "swgl_commitTextureLinearColorYUV",
4202 None,
4203 Type::new(Void),
4204 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4205 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4206 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4207 Type::new(Float)],
4208 );
4209 declare_function(
4210 state,
4211 "swgl_commitTextureLinearColorYUV",
4212 None,
4213 Type::new(Void),
4214 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4215 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4216 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4217 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4218 Type::new(Float)],
4219 );
4220 }
4221
4222 TranslationUnit(tu.0.map(state, translate_external_declaration))
4223 }
4224
infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass4225 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass {
4226 match expr.kind {
4227 ExprKind::Variable(ref i) => {
4228 *assign = *i;
4229 match &state.sym(*i).decl {
4230 SymDecl::Local(_, _, ref run_class) => *run_class,
4231 SymDecl::Global(_, _, _, ref run_class) => *run_class,
4232 _ => panic!(),
4233 }
4234 }
4235 ExprKind::IntConst(_)
4236 | ExprKind::UIntConst(_)
4237 | ExprKind::BoolConst(_)
4238 | ExprKind::FloatConst(_)
4239 | ExprKind::DoubleConst(_) => RunClass::Scalar,
4240 ExprKind::Unary(_, ref e) => infer_expr(state, e),
4241 ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)),
4242 ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c)
4243 .merge(infer_expr(state, s))
4244 .merge(infer_expr(state, e)),
4245 ExprKind::Assignment(ref v, _, ref e) => {
4246 let mut sym = SymRef(!0);
4247 let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e));
4248 assert!(sym != SymRef(!0));
4249 state.merge_run_class(sym, run_class)
4250 }
4251 ExprKind::Bracket(ref e, ref indx) => {
4252 infer_expr_inner(state, e, assign).merge(infer_expr(state, indx))
4253 }
4254 ExprKind::FunCall(ref fun, ref args) => {
4255 let arg_classes: Vec<(RunClass, SymRef)> = args
4256 .iter()
4257 .map(|e| {
4258 let mut assign = SymRef(!0);
4259 let run_class = infer_expr_inner(state, e, &mut assign);
4260 (run_class, assign)
4261 })
4262 .collect();
4263 let run_class = if args.is_empty() {
4264 RunClass::Scalar
4265 } else {
4266 arg_classes
4267 .iter()
4268 .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y))
4269 };
4270 match fun {
4271 FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
4272 SymDecl::NativeFunction(_, _, ref ret_class) => {
4273 if *ret_class != RunClass::Unknown {
4274 *ret_class
4275 } else {
4276 run_class
4277 }
4278 }
4279 SymDecl::UserFunction(ref fd, ref run_class) => {
4280 for (&(mut arg_class, assign), param) in
4281 arg_classes.iter().zip(fd.prototype.parameters.iter())
4282 {
4283 if let FunctionParameterDeclaration::Named(Some(qual), p) = param {
4284 match qual {
4285 ParameterQualifier::InOut | ParameterQualifier::Out => {
4286 if let SymDecl::Local(_, _, param_class) =
4287 &state.sym(p.sym).decl
4288 {
4289 match param_class {
4290 RunClass::Unknown | RunClass::Vector => {
4291 arg_class = RunClass::Vector;
4292 }
4293 RunClass::Dependent(mask) => {
4294 for i in 0 .. 31 {
4295 if (mask & (1 << i)) != 0 {
4296 arg_class =
4297 arg_class.merge(arg_classes[i].0);
4298 }
4299 }
4300 }
4301 RunClass::Scalar => {}
4302 }
4303 }
4304 assert!(assign != SymRef(!0));
4305 state.merge_run_class(assign, arg_class);
4306 }
4307 _ => {}
4308 }
4309 }
4310 }
4311 if fd.prototype.ty.kind == TypeKind::Void {
4312 RunClass::Scalar
4313 } else {
4314 match *run_class {
4315 RunClass::Unknown | RunClass::Vector => RunClass::Vector,
4316 RunClass::Dependent(mask) => {
4317 let mut ret_class = RunClass::Unknown;
4318 for i in 0 .. 31 {
4319 if (mask & (1 << i)) != 0 {
4320 ret_class = ret_class.merge(arg_classes[i].0);
4321 }
4322 }
4323 ret_class
4324 }
4325 RunClass::Scalar => RunClass::Scalar,
4326 }
4327 }
4328 }
4329 SymDecl::Struct(..) => run_class,
4330 _ => panic!(),
4331 },
4332 FunIdentifier::Constructor(..) => run_class,
4333 }
4334 }
4335 ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign),
4336 ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign),
4337 ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign),
4338 ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign),
4339 ExprKind::Comma(ref a, ref b) => {
4340 infer_expr(state, a);
4341 infer_expr(state, b)
4342 }
4343 ExprKind::Cond(_, ref e) => infer_expr(state, e),
4344 ExprKind::CondMask => RunClass::Vector,
4345 }
4346 }
4347
infer_expr(state: &mut State, expr: &Expr) -> RunClass4348 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass {
4349 infer_expr_inner(state, expr, &mut SymRef(!0))
4350 }
4351
infer_condition(state: &mut State, c: &Condition)4352 fn infer_condition(state: &mut State, c: &Condition) {
4353 match *c {
4354 Condition::Expr(ref e) => {
4355 infer_expr(state, e);
4356 }
4357 }
4358 }
4359
infer_iteration_statement(state: &mut State, ist: &IterationStatement)4360 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) {
4361 let changed = state.run_class_changed.replace(true);
4362 match *ist {
4363 IterationStatement::While(ref cond, ref body) => {
4364 while state.run_class_changed.replace(false) {
4365 infer_condition(state, cond);
4366 infer_statement(state, body);
4367 }
4368 }
4369 IterationStatement::DoWhile(ref body, ref cond) => {
4370 while state.run_class_changed.replace(false) {
4371 infer_statement(state, body);
4372 infer_expr(state, cond);
4373 }
4374 }
4375 IterationStatement::For(ref init, ref rest, ref body) => {
4376 match *init {
4377 ForInitStatement::Expression(ref expr) => {
4378 if let Some(ref e) = *expr {
4379 infer_expr(state, e);
4380 }
4381 }
4382 ForInitStatement::Declaration(ref d) => {
4383 infer_declaration(state, d);
4384 }
4385 }
4386 while state.run_class_changed.replace(false) {
4387 if let Some(ref cond) = rest.condition {
4388 infer_condition(state, cond);
4389 }
4390 if let Some(ref e) = rest.post_expr {
4391 infer_expr(state, e);
4392 }
4393 infer_statement(state, body);
4394 }
4395 }
4396 }
4397 state.run_class_changed.set(changed);
4398 }
4399
infer_selection_statement(state: &mut State, sst: &SelectionStatement)4400 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) {
4401 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond));
4402 mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4403 let branch_declaration = state.branch_declaration;
4404 state.branch_declaration = state.last_declaration;
4405 infer_statement(state, &sst.body);
4406 if let Some(ref else_st) = sst.else_stmt {
4407 infer_statement(state, else_st);
4408 }
4409 state.branch_run_class = branch_run_class;
4410 state.branch_declaration = branch_declaration;
4411 }
4412
infer_expression_statement(state: &mut State, est: &ExprStatement)4413 fn infer_expression_statement(state: &mut State, est: &ExprStatement) {
4414 if let Some(ref e) = *est {
4415 infer_expr(state, e);
4416 }
4417 }
4418
infer_switch_statement(state: &mut State, sst: &SwitchStatement)4419 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) {
4420 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head));
4421 mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4422 let branch_declaration = state.branch_declaration;
4423 state.branch_declaration = state.last_declaration;
4424 for case in &sst.cases {
4425 for st in &case.stmts {
4426 infer_statement(state, st);
4427 }
4428 }
4429 state.branch_run_class = branch_run_class;
4430 state.branch_declaration = branch_declaration;
4431 }
4432
infer_jump_statement(state: &mut State, j: &JumpStatement)4433 fn infer_jump_statement(state: &mut State, j: &JumpStatement) {
4434 match *j {
4435 JumpStatement::Continue => {}
4436 JumpStatement::Break => {}
4437 JumpStatement::Discard => {}
4438 JumpStatement::Return(ref e) => {
4439 if let Some(e) = e {
4440 let run_class = infer_expr(state, e);
4441 state.return_run_class(run_class);
4442 }
4443 }
4444 }
4445 }
4446
infer_initializer(state: &mut State, i: &Initializer) -> RunClass4447 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass {
4448 match *i {
4449 Initializer::Simple(ref e) => infer_expr(state, e),
4450 Initializer::List(ref list) => {
4451 let mut run_class = RunClass::Unknown;
4452 for ini in list.0.iter() {
4453 run_class = run_class.merge(infer_initializer(state, ini));
4454 }
4455 run_class
4456 }
4457 }
4458 }
4459
infer_declaration(state: &mut State, d: &Declaration)4460 fn infer_declaration(state: &mut State, d: &Declaration) {
4461 match *d {
4462 Declaration::FunctionPrototype(..) => {}
4463 Declaration::InitDeclaratorList(ref list) => {
4464 state.last_declaration = list.head.name;
4465
4466 let mut run_class = RunClass::Unknown;
4467 for decl in &list.tail {
4468 if let Some(ref initializer) = decl.initializer {
4469 run_class = run_class.merge(infer_initializer(state, initializer));
4470 }
4471 }
4472 if let Some(ref initializer) = list.head.initializer {
4473 run_class = run_class.merge(infer_initializer(state, initializer));
4474 state.merge_run_class(list.head.name, run_class);
4475 }
4476 }
4477 Declaration::Precision(..) => {}
4478 Declaration::Block(..) => {}
4479 Declaration::Global(..) => {}
4480 Declaration::StructDefinition(..) => {}
4481 }
4482 }
4483
infer_simple_statement(state: &mut State, sst: &SimpleStatement)4484 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) {
4485 match *sst {
4486 SimpleStatement::Declaration(ref d) => infer_declaration(state, d),
4487 SimpleStatement::Expression(ref e) => infer_expression_statement(state, e),
4488 SimpleStatement::Selection(ref s) => infer_selection_statement(state, s),
4489 SimpleStatement::Switch(ref s) => infer_switch_statement(state, s),
4490 SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i),
4491 SimpleStatement::Jump(ref j) => infer_jump_statement(state, j),
4492 }
4493 }
4494
infer_compound_statement(state: &mut State, cst: &CompoundStatement)4495 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) {
4496 for st in &cst.statement_list {
4497 infer_statement(state, st);
4498 }
4499 }
4500
infer_statement(state: &mut State, st: &Statement)4501 fn infer_statement(state: &mut State, st: &Statement) {
4502 match *st {
4503 Statement::Compound(ref cst) => infer_compound_statement(state, cst),
4504 Statement::Simple(ref sst) => infer_simple_statement(state, sst),
4505 }
4506 }
4507
infer_function_definition(state: &mut State, fd: &FunctionDefinition)4508 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) {
4509 state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap());
4510
4511 state.run_class_changed.set(true);
4512 while state.run_class_changed.replace(false) {
4513 for st in &fd.body.statement_list {
4514 infer_statement(state, st);
4515 }
4516 }
4517
4518 state.in_function = None;
4519 }
4520
infer_external_declaration(state: &mut State, ed: &ExternalDeclaration)4521 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) {
4522 match *ed {
4523 ExternalDeclaration::Preprocessor(_) => {}
4524 ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd),
4525 ExternalDeclaration::Declaration(_) => {}
4526 }
4527 }
4528
infer_run_class(state: &mut State, tu: &TranslationUnit)4529 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) {
4530 for ed in &(tu.0).0 {
4531 infer_external_declaration(state, ed);
4532 }
4533 }
4534