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 // The field is not actively used but useful for `Debug`.
923 #[allow(dead_code)]
924 name: String,
925 names: HashMap<String, SymRef>,
926 }
927 impl Scope {
new(name: String) -> Self928 fn new(name: String) -> Self {
929 Scope {
930 name,
931 names: HashMap::new(),
932 }
933 }
934 }
935
936 #[derive(Clone, Debug, PartialEq)]
937 pub struct TexelFetchOffsets {
938 pub min_x: i32,
939 pub max_x: i32,
940 pub min_y: i32,
941 pub max_y: i32,
942 }
943
944 impl TexelFetchOffsets {
new(x: i32, y: i32) -> Self945 fn new(x: i32, y: i32) -> Self {
946 TexelFetchOffsets {
947 min_x: x,
948 max_x: x,
949 min_y: y,
950 max_y: y,
951 }
952 }
953
add_offset(&mut self, x: i32, y: i32)954 fn add_offset(&mut self, x: i32, y: i32) {
955 self.min_x = self.min_x.min(x);
956 self.max_x = self.max_x.max(x);
957 self.min_y = self.min_y.min(y);
958 self.max_y = self.max_y.max(y);
959 }
960 }
961
962 #[derive(Debug)]
963 pub struct State {
964 scopes: Vec<Scope>,
965 syms: Vec<RefCell<Symbol>>,
966 in_function: Option<SymRef>,
967 run_class_changed: Cell<bool>,
968 last_declaration: SymRef,
969 branch_run_class: RunClass,
970 branch_declaration: SymRef,
971 modified_globals: RefCell<Vec<SymRef>>,
972 pub used_globals: RefCell<Vec<SymRef>>,
973 pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
974 clip_dist_sym: SymRef,
975 pub used_clip_dist: u32,
976 }
977
978 impl State {
new() -> Self979 pub fn new() -> Self {
980 State {
981 scopes: Vec::new(),
982 syms: Vec::new(),
983 in_function: None,
984 run_class_changed: Cell::new(false),
985 last_declaration: SymRef(0),
986 branch_run_class: RunClass::Unknown,
987 branch_declaration: SymRef(0),
988 modified_globals: RefCell::new(Vec::new()),
989 used_globals: RefCell::new(Vec::new()),
990 texel_fetches: HashMap::new(),
991 clip_dist_sym: SymRef(0),
992 used_clip_dist: 0,
993 }
994 }
995
lookup(&self, name: &str) -> Option<SymRef>996 pub fn lookup(&self, name: &str) -> Option<SymRef> {
997 for s in self.scopes.iter().rev() {
998 if let Some(sym) = s.names.get(name) {
999 return Some(*sym);
1000 }
1001 }
1002 return None;
1003 }
1004
declare(&mut self, name: &str, decl: SymDecl) -> SymRef1005 fn declare(&mut self, name: &str, decl: SymDecl) -> SymRef {
1006 let s = SymRef(self.syms.len() as u32);
1007 self.syms.push(RefCell::new(Symbol {
1008 name: name.into(),
1009 decl,
1010 }));
1011 self.scopes.last_mut().unwrap().names.insert(name.into(), s);
1012 s
1013 }
1014
sym(&self, sym: SymRef) -> Ref<Symbol>1015 pub fn sym(&self, sym: SymRef) -> Ref<Symbol> {
1016 self.syms[sym.0 as usize].borrow()
1017 }
1018
sym_mut(&mut self, sym: SymRef) -> &mut Symbol1019 pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol {
1020 self.syms[sym.0 as usize].get_mut()
1021 }
1022
lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol>1023 pub fn lookup_sym_mut(&mut self, name: &str) -> Option<&mut Symbol> {
1024 self.lookup(name)
1025 .map(move |x| self.syms[x.0 as usize].get_mut())
1026 }
1027
push_scope(&mut self, name: String)1028 fn push_scope(&mut self, name: String) {
1029 self.scopes.push(Scope::new(name));
1030 }
pop_scope(&mut self)1031 fn pop_scope(&mut self) {
1032 self.scopes.pop();
1033 }
1034
return_run_class(&self, mut new_run_class: RunClass)1035 fn return_run_class(&self, mut new_run_class: RunClass) {
1036 new_run_class = self.branch_run_class.merge(new_run_class);
1037 if let Some(sym) = self.in_function {
1038 let mut b = self.syms[sym.0 as usize].borrow_mut();
1039 if let SymDecl::UserFunction(_, ref mut run_class) = b.decl {
1040 *run_class = run_class.merge(new_run_class);
1041 }
1042 }
1043 }
1044
function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)>1045 pub fn function_definition(&self, name: SymRef) -> Option<(Rc<FunctionDefinition>, RunClass)> {
1046 if let SymDecl::UserFunction(ref fd, ref run_class) = &self.sym(name).decl {
1047 Some((fd.clone(), *run_class))
1048 } else {
1049 None
1050 }
1051 }
1052
merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass1053 fn merge_run_class(&self, sym: SymRef, mut new_run_class: RunClass) -> RunClass {
1054 if sym.0 <= self.branch_declaration.0 {
1055 new_run_class = self.branch_run_class.merge(new_run_class);
1056 }
1057 let mut b = self.syms[sym.0 as usize].borrow_mut();
1058 let mut old_run_class = new_run_class;
1059 if let SymDecl::Local(_, _, ref mut run_class) = b.decl {
1060 old_run_class = *run_class;
1061 new_run_class = old_run_class.merge(new_run_class);
1062 *run_class = new_run_class;
1063 }
1064 if old_run_class != RunClass::Unknown && old_run_class != new_run_class {
1065 self.run_class_changed.set(true);
1066 }
1067 new_run_class
1068 }
1069 }
1070
1071 /// A declaration.
1072 #[derive(Clone, Debug, PartialEq)]
1073 pub enum Declaration {
1074 FunctionPrototype(FunctionPrototype),
1075 StructDefinition(SymRef),
1076 InitDeclaratorList(InitDeclaratorList),
1077 Precision(PrecisionQualifier, TypeSpecifier),
1078 Block(Block),
1079 Global(TypeQualifier, Vec<Identifier>),
1080 }
1081
1082 /// A general purpose block, containing fields and possibly a list of declared identifiers. Semantic
1083 /// is given with the storage qualifier.
1084 #[derive(Clone, Debug, PartialEq)]
1085 pub struct Block {
1086 pub qualifier: TypeQualifier,
1087 pub name: Identifier,
1088 pub fields: Vec<StructFieldSpecifier>,
1089 pub identifier: Option<ArrayedIdentifier>,
1090 }
1091
1092 /// Function identifier.
1093 #[derive(Clone, Debug, PartialEq)]
1094 pub enum FunIdentifier {
1095 Identifier(SymRef),
1096 Constructor(Type),
1097 }
1098
1099 /// Function prototype.
1100 #[derive(Clone, Debug, PartialEq)]
1101 pub struct FunctionPrototype {
1102 pub ty: Type,
1103 pub name: Identifier,
1104 pub parameters: Vec<FunctionParameterDeclaration>,
1105 }
1106
1107 impl FunctionPrototype {
has_parameter(&self, sym: SymRef) -> bool1108 pub fn has_parameter(&self, sym: SymRef) -> bool {
1109 for param in &self.parameters {
1110 match param {
1111 FunctionParameterDeclaration::Named(_, ref d) => {
1112 if d.sym == sym {
1113 return true;
1114 }
1115 }
1116 _ => {}
1117 }
1118 }
1119 false
1120 }
1121 }
1122
1123 /// Function parameter declaration.
1124 #[derive(Clone, Debug, PartialEq)]
1125 pub enum FunctionParameterDeclaration {
1126 Named(Option<ParameterQualifier>, FunctionParameterDeclarator),
1127 Unnamed(Option<ParameterQualifier>, TypeSpecifier),
1128 }
1129
1130 /// Function parameter declarator.
1131 #[derive(Clone, Debug, PartialEq)]
1132 pub struct FunctionParameterDeclarator {
1133 pub ty: Type,
1134 pub name: Identifier,
1135 pub sym: SymRef,
1136 }
1137
1138 /// Init declarator list.
1139 #[derive(Clone, Debug, PartialEq)]
1140 pub struct InitDeclaratorList {
1141 // XXX it feels like separating out the type and the names is better than
1142 // head and tail
1143 // Also, it might be nice to separate out type definitions from name definitions
1144 pub head: SingleDeclaration,
1145 pub tail: Vec<SingleDeclarationNoType>,
1146 }
1147
1148 /// Type qualifier.
1149 #[derive(Clone, Debug, PartialEq)]
1150 pub struct TypeQualifier {
1151 pub qualifiers: NonEmpty<TypeQualifierSpec>,
1152 }
1153
lift_type_qualifier_for_declaration( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<TypeQualifier>1154 fn lift_type_qualifier_for_declaration(
1155 _state: &mut State,
1156 q: &Option<syntax::TypeQualifier>,
1157 ) -> Option<TypeQualifier> {
1158 q.as_ref().and_then(|x| {
1159 NonEmpty::from_non_empty_iter(x.qualifiers.0.iter().flat_map(|x| match x {
1160 syntax::TypeQualifierSpec::Precision(_) => None,
1161 syntax::TypeQualifierSpec::Interpolation(_) => None,
1162 syntax::TypeQualifierSpec::Invariant => Some(TypeQualifierSpec::Invariant),
1163 syntax::TypeQualifierSpec::Layout(l) => Some(TypeQualifierSpec::Layout(l.clone())),
1164 syntax::TypeQualifierSpec::Precise => Some(TypeQualifierSpec::Precise),
1165 syntax::TypeQualifierSpec::Storage(_) => None,
1166 }))
1167 .map(|x| TypeQualifier { qualifiers: x })
1168 })
1169 }
1170
lift_type_qualifier_for_parameter( _state: &mut State, q: &Option<syntax::TypeQualifier>, ) -> Option<ParameterQualifier>1171 fn lift_type_qualifier_for_parameter(
1172 _state: &mut State,
1173 q: &Option<syntax::TypeQualifier>,
1174 ) -> Option<ParameterQualifier> {
1175 let mut qp: Option<ParameterQualifier> = None;
1176 if let Some(q) = q {
1177 for x in &q.qualifiers.0 {
1178 match (&qp, x) {
1179 (None, syntax::TypeQualifierSpec::Storage(s)) => match s {
1180 syntax::StorageQualifier::Const => qp = Some(ParameterQualifier::Const),
1181 syntax::StorageQualifier::In => qp = Some(ParameterQualifier::In),
1182 syntax::StorageQualifier::Out => qp = Some(ParameterQualifier::Out),
1183 syntax::StorageQualifier::InOut => qp = Some(ParameterQualifier::InOut),
1184 _ => panic!("Bad storage qualifier for parameter"),
1185 },
1186 (_, syntax::TypeQualifierSpec::Precision(_)) => {}
1187 _ => panic!("Bad parameter qualifier {:?}", x),
1188 }
1189 }
1190 }
1191 qp
1192 }
1193
1194 #[derive(Clone, Debug, PartialEq)]
1195 pub enum ParameterQualifier {
1196 Const,
1197 In,
1198 InOut,
1199 Out,
1200 }
1201
1202 #[derive(Clone, Debug, PartialEq)]
1203 pub enum MemoryQualifier {
1204 Coherent,
1205 Volatile,
1206 Restrict,
1207 ReadOnly,
1208 WriteOnly,
1209 }
1210
1211 /// Type qualifier spec.
1212 #[derive(Clone, Debug, PartialEq)]
1213 pub enum TypeQualifierSpec {
1214 Layout(syntax::LayoutQualifier),
1215 Invariant,
1216 Parameter(ParameterQualifier),
1217 Memory(MemoryQualifier),
1218 Precise,
1219 }
1220
1221 /// Single declaration.
1222 #[derive(Clone, Debug, PartialEq)]
1223 pub struct SingleDeclaration {
1224 pub ty: Type,
1225 pub ty_def: Option<SymRef>,
1226 pub qualifier: Option<TypeQualifier>,
1227 pub name: SymRef,
1228 pub initializer: Option<Initializer>,
1229 }
1230
1231 /// A single declaration with implicit, already-defined type.
1232 #[derive(Clone, Debug, PartialEq)]
1233 pub struct SingleDeclarationNoType {
1234 pub ident: ArrayedIdentifier,
1235 pub initializer: Option<Initializer>,
1236 }
1237
1238 /// Initializer.
1239 #[derive(Clone, Debug, PartialEq)]
1240 pub enum Initializer {
1241 Simple(Box<Expr>),
1242 List(NonEmpty<Initializer>),
1243 }
1244
1245 impl From<Expr> for Initializer {
from(e: Expr) -> Self1246 fn from(e: Expr) -> Self {
1247 Initializer::Simple(Box::new(e))
1248 }
1249 }
1250
1251 #[derive(Clone, Debug, PartialEq)]
1252 pub struct Expr {
1253 pub kind: ExprKind,
1254 pub ty: Type,
1255 }
1256
1257 #[derive(Copy, Clone, Debug, PartialEq)]
1258 pub enum FieldSet {
1259 Rgba,
1260 Xyzw,
1261 Stpq,
1262 }
1263
1264 #[derive(Clone, Debug, PartialEq)]
1265 pub struct SwizzleSelector {
1266 pub field_set: FieldSet,
1267 pub components: Vec<i8>,
1268 }
1269
1270 impl SwizzleSelector {
parse(s: &str) -> Self1271 fn parse(s: &str) -> Self {
1272 let mut components = Vec::new();
1273 let mut field_set = Vec::new();
1274
1275 for c in s.chars() {
1276 match c {
1277 'r' => {
1278 components.push(0);
1279 field_set.push(FieldSet::Rgba);
1280 }
1281 'x' => {
1282 components.push(0);
1283 field_set.push(FieldSet::Xyzw);
1284 }
1285 's' => {
1286 components.push(0);
1287 field_set.push(FieldSet::Stpq);
1288 }
1289
1290 'g' => {
1291 components.push(1);
1292 field_set.push(FieldSet::Rgba);
1293 }
1294 'y' => {
1295 components.push(1);
1296 field_set.push(FieldSet::Xyzw);
1297 }
1298 't' => {
1299 components.push(1);
1300 field_set.push(FieldSet::Stpq);
1301 }
1302
1303 'b' => {
1304 components.push(2);
1305 field_set.push(FieldSet::Rgba);
1306 }
1307 'z' => {
1308 components.push(2);
1309 field_set.push(FieldSet::Xyzw);
1310 }
1311 'p' => {
1312 components.push(2);
1313 field_set.push(FieldSet::Stpq);
1314 }
1315
1316 'a' => {
1317 components.push(3);
1318 field_set.push(FieldSet::Rgba);
1319 }
1320 'w' => {
1321 components.push(3);
1322 field_set.push(FieldSet::Xyzw);
1323 }
1324 'q' => {
1325 components.push(3);
1326 field_set.push(FieldSet::Stpq);
1327 }
1328 _ => panic!("bad selector"),
1329 }
1330 }
1331
1332 let first = &field_set[0];
1333 assert!(field_set.iter().all(|item| item == first));
1334 assert!(components.len() <= 4);
1335 SwizzleSelector {
1336 field_set: first.clone(),
1337 components,
1338 }
1339 }
1340
to_field_set(&self, field_set: FieldSet) -> String1341 pub fn to_field_set(&self, field_set: FieldSet) -> String {
1342 let mut s = String::new();
1343 let fs = match field_set {
1344 FieldSet::Rgba => ['r', 'g', 'b', 'a'],
1345 FieldSet::Xyzw => ['x', 'y', 'z', 'w'],
1346 FieldSet::Stpq => ['s', 't', 'p', 'q'],
1347 };
1348 for i in &self.components {
1349 s.push(fs[*i as usize])
1350 }
1351 s
1352 }
1353
to_string(&self) -> String1354 pub fn to_string(&self) -> String {
1355 self.to_field_set(self.field_set)
1356 }
1357 }
1358
1359 /// The most general form of an expression. As you can see if you read the variant list, in GLSL, an
1360 /// assignment is an expression. This is a bit silly but think of an assignment as a statement first
1361 /// then an expression which evaluates to what the statement “returns”.
1362 ///
1363 /// An expression is either an assignment or a list (comma) of assignments.
1364 #[derive(Clone, Debug, PartialEq)]
1365 pub enum ExprKind {
1366 /// A variable expression, using an identifier.
1367 Variable(SymRef),
1368 /// Integral constant expression.
1369 IntConst(i32),
1370 /// Unsigned integral constant expression.
1371 UIntConst(u32),
1372 /// Boolean constant expression.
1373 BoolConst(bool),
1374 /// Single precision floating expression.
1375 FloatConst(f32),
1376 /// Double precision floating expression.
1377 DoubleConst(f64),
1378 /// A unary expression, gathering a single expression and a unary operator.
1379 Unary(UnaryOp, Box<Expr>),
1380 /// A binary expression, gathering two expressions and a binary operator.
1381 Binary(BinaryOp, Box<Expr>, Box<Expr>),
1382 /// A ternary conditional expression, gathering three expressions.
1383 Ternary(Box<Expr>, Box<Expr>, Box<Expr>),
1384 /// An assignment is also an expression. Gathers an expression that defines what to assign to, an
1385 /// assignment operator and the value to associate with.
1386 Assignment(Box<Expr>, AssignmentOp, Box<Expr>),
1387 /// Add an array specifier to an expression.
1388 Bracket(Box<Expr>, Box<Expr>),
1389 /// A functional call. It has a function identifier and a list of expressions (arguments).
1390 FunCall(FunIdentifier, Vec<Expr>),
1391 /// An expression associated with a field selection (struct).
1392 Dot(Box<Expr>, Identifier),
1393 /// An expression associated with a component selection
1394 SwizzleSelector(Box<Expr>, SwizzleSelector),
1395 /// Post-incrementation of an expression.
1396 PostInc(Box<Expr>),
1397 /// Post-decrementation of an expression.
1398 PostDec(Box<Expr>),
1399 /// An expression that contains several, separated with comma.
1400 Comma(Box<Expr>, Box<Expr>),
1401 /// A temporary condition variable
1402 Cond(usize, Box<Expr>),
1403 CondMask,
1404 }
1405
1406 /*
1407 impl From<i32> for Expr {
1408 fn from(x: i32) -> Expr {
1409 ExprKind::IntConst(x)
1410 }
1411 }
1412
1413 impl From<u32> for Expr {
1414 fn from(x: u32) -> Expr {
1415 Expr::UIntConst(x)
1416 }
1417 }
1418
1419 impl From<bool> for Expr {
1420 fn from(x: bool) -> Expr {
1421 Expr::BoolConst(x)
1422 }
1423 }
1424
1425 impl From<f32> for Expr {
1426 fn from(x: f32) -> Expr {
1427 Expr::FloatConst(x)
1428 }
1429 }
1430
1431 impl From<f64> for Expr {
1432 fn from(x: f64) -> Expr {
1433 Expr::DoubleConst(x)
1434 }
1435 }
1436 */
1437 /// Starting rule.
1438 #[derive(Clone, Debug, PartialEq)]
1439 pub struct TranslationUnit(pub NonEmpty<ExternalDeclaration>);
1440
1441 impl TranslationUnit {
1442 /// Construct a translation unit from an iterator.
1443 ///
1444 /// # Errors
1445 ///
1446 /// `None` if the iterator yields no value.
from_iter<I>(iter: I) -> Option<Self> where I: IntoIterator<Item = ExternalDeclaration>,1447 pub fn from_iter<I>(iter: I) -> Option<Self>
1448 where
1449 I: IntoIterator<Item = ExternalDeclaration>,
1450 {
1451 NonEmpty::from_non_empty_iter(iter).map(TranslationUnit)
1452 }
1453 }
1454
1455 impl Deref for TranslationUnit {
1456 type Target = NonEmpty<ExternalDeclaration>;
1457
deref(&self) -> &Self::Target1458 fn deref(&self) -> &Self::Target {
1459 &self.0
1460 }
1461 }
1462
1463 impl DerefMut for TranslationUnit {
deref_mut(&mut self) -> &mut Self::Target1464 fn deref_mut(&mut self) -> &mut Self::Target {
1465 &mut self.0
1466 }
1467 }
1468
1469 impl IntoIterator for TranslationUnit {
1470 type IntoIter = <NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1471 type Item = ExternalDeclaration;
1472
into_iter(self) -> Self::IntoIter1473 fn into_iter(self) -> Self::IntoIter {
1474 self.0.into_iter()
1475 }
1476 }
1477
1478 impl<'a> IntoIterator for &'a TranslationUnit {
1479 type IntoIter = <&'a NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1480 type Item = &'a ExternalDeclaration;
1481
into_iter(self) -> Self::IntoIter1482 fn into_iter(self) -> Self::IntoIter {
1483 (&self.0).into_iter()
1484 }
1485 }
1486
1487 impl<'a> IntoIterator for &'a mut TranslationUnit {
1488 type IntoIter = <&'a mut NonEmpty<ExternalDeclaration> as IntoIterator>::IntoIter;
1489 type Item = &'a mut ExternalDeclaration;
1490
into_iter(self) -> Self::IntoIter1491 fn into_iter(self) -> Self::IntoIter {
1492 (&mut self.0).into_iter()
1493 }
1494 }
1495
1496 /// External declaration.
1497 #[derive(Clone, Debug, PartialEq)]
1498 pub enum ExternalDeclaration {
1499 Preprocessor(syntax::Preprocessor),
1500 FunctionDefinition(Rc<FunctionDefinition>),
1501 Declaration(Declaration),
1502 }
1503
1504 /// Function definition.
1505 #[derive(Clone, Debug, PartialEq)]
1506 pub struct FunctionDefinition {
1507 pub prototype: FunctionPrototype,
1508 pub body: CompoundStatement,
1509 pub globals: Vec<SymRef>,
1510 pub texel_fetches: HashMap<(SymRef, SymRef), TexelFetchOffsets>,
1511 }
1512
1513 /// Compound statement (with no new scope).
1514 #[derive(Clone, Debug, PartialEq)]
1515 pub struct CompoundStatement {
1516 pub statement_list: Vec<Statement>,
1517 }
1518
1519 impl CompoundStatement {
new() -> Self1520 pub fn new() -> Self {
1521 CompoundStatement {
1522 statement_list: Vec::new(),
1523 }
1524 }
1525 }
1526
1527 impl FromIterator<Statement> for CompoundStatement {
from_iter<T>(iter: T) -> Self where T: IntoIterator<Item = Statement>,1528 fn from_iter<T>(iter: T) -> Self
1529 where
1530 T: IntoIterator<Item = Statement>,
1531 {
1532 CompoundStatement {
1533 statement_list: iter.into_iter().collect(),
1534 }
1535 }
1536 }
1537
1538 /// Statement.
1539 #[derive(Clone, Debug, PartialEq)]
1540 pub enum Statement {
1541 Compound(Box<CompoundStatement>),
1542 Simple(Box<SimpleStatement>),
1543 }
1544
1545 /// Simple statement.
1546 #[derive(Clone, Debug, PartialEq)]
1547 pub enum SimpleStatement {
1548 Declaration(Declaration),
1549 Expression(ExprStatement),
1550 Selection(SelectionStatement),
1551 Switch(SwitchStatement),
1552 Iteration(IterationStatement),
1553 Jump(JumpStatement),
1554 }
1555
1556 impl SimpleStatement {
1557 /// Create a new expression statement.
new_expr<E>(expr: E) -> Self where E: Into<Expr>,1558 pub fn new_expr<E>(expr: E) -> Self
1559 where
1560 E: Into<Expr>,
1561 {
1562 SimpleStatement::Expression(Some(expr.into()))
1563 }
1564
1565 /// 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>,1566 pub fn new_if_else<If, True, False>(ife: If, truee: True, falsee: False) -> Self
1567 where
1568 If: Into<Expr>,
1569 True: Into<Statement>,
1570 False: Into<Statement>,
1571 {
1572 SimpleStatement::Selection(SelectionStatement {
1573 cond: Box::new(ife.into()),
1574 body: Box::new(truee.into()),
1575 else_stmt: Some(Box::new(falsee.into())),
1576 })
1577 }
1578
1579 /// Create a new while statement.
new_while<C, S>(cond: C, body: S) -> Self where C: Into<Condition>, S: Into<Statement>,1580 pub fn new_while<C, S>(cond: C, body: S) -> Self
1581 where
1582 C: Into<Condition>,
1583 S: Into<Statement>,
1584 {
1585 SimpleStatement::Iteration(IterationStatement::While(
1586 cond.into(),
1587 Box::new(body.into()),
1588 ))
1589 }
1590
1591 /// Create a new do-while statement.
new_do_while<C, S>(body: S, cond: C) -> Self where S: Into<Statement>, C: Into<Expr>,1592 pub fn new_do_while<C, S>(body: S, cond: C) -> Self
1593 where
1594 S: Into<Statement>,
1595 C: Into<Expr>,
1596 {
1597 SimpleStatement::Iteration(IterationStatement::DoWhile(
1598 Box::new(body.into()),
1599 Box::new(cond.into()),
1600 ))
1601 }
1602 }
1603
1604 /// Expression statement.
1605 pub type ExprStatement = Option<Expr>;
1606
1607 /// Selection statement.
1608 #[derive(Clone, Debug, PartialEq)]
1609 pub struct SelectionStatement {
1610 pub cond: Box<Expr>,
1611 pub body: Box<Statement>,
1612 // the else branch
1613 pub else_stmt: Option<Box<Statement>>,
1614 }
1615
1616 /// Condition.
1617 #[derive(Clone, Debug, PartialEq)]
1618 pub enum Condition {
1619 Expr(Box<Expr>),
1620 }
1621
1622 impl From<Expr> for Condition {
from(expr: Expr) -> Self1623 fn from(expr: Expr) -> Self {
1624 Condition::Expr(Box::new(expr))
1625 }
1626 }
1627
1628 /// Switch statement.
1629 #[derive(Clone, Debug, PartialEq)]
1630 pub struct SwitchStatement {
1631 pub head: Box<Expr>,
1632 pub cases: Vec<Case>,
1633 }
1634
1635 /// Case label statement.
1636 #[derive(Clone, Debug, PartialEq)]
1637 pub enum CaseLabel {
1638 Case(Box<Expr>),
1639 Def,
1640 }
1641
1642 /// An individual case
1643 #[derive(Clone, Debug, PartialEq)]
1644 pub struct Case {
1645 pub label: CaseLabel,
1646 pub stmts: Vec<Statement>,
1647 }
1648
1649 /// Iteration statement.
1650 #[derive(Clone, Debug, PartialEq)]
1651 pub enum IterationStatement {
1652 While(Condition, Box<Statement>),
1653 DoWhile(Box<Statement>, Box<Expr>),
1654 For(ForInitStatement, ForRestStatement, Box<Statement>),
1655 }
1656
1657 /// For init statement.
1658 #[derive(Clone, Debug, PartialEq)]
1659 pub enum ForInitStatement {
1660 Expression(Option<Expr>),
1661 Declaration(Box<Declaration>),
1662 }
1663
1664 /// For init statement.
1665 #[derive(Clone, Debug, PartialEq)]
1666 pub struct ForRestStatement {
1667 pub condition: Option<Condition>,
1668 pub post_expr: Option<Box<Expr>>,
1669 }
1670
1671 /// Jump statement.
1672 #[derive(Clone, Debug, PartialEq)]
1673 pub enum JumpStatement {
1674 Continue,
1675 Break,
1676 Return(Option<Box<Expr>>),
1677 Discard,
1678 }
1679
1680 trait NonEmptyExt<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>1681 fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>;
new(x: T) -> NonEmpty<T>1682 fn new(x: T) -> NonEmpty<T>;
1683 }
1684
1685 impl<T> NonEmptyExt<T> for NonEmpty<T> {
map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U>1686 fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, mut f: F) -> NonEmpty<U> {
1687 NonEmpty::from_non_empty_iter(self.into_iter().map(|x| f(s, &x))).unwrap()
1688 }
new(x: T) -> NonEmpty<T>1689 fn new(x: T) -> NonEmpty<T> {
1690 NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap()
1691 }
1692 }
1693
translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer1694 fn translate_initializater(state: &mut State, i: &syntax::Initializer) -> Initializer {
1695 match i {
1696 syntax::Initializer::Simple(i) => {
1697 Initializer::Simple(Box::new(translate_expression(state, i)))
1698 }
1699 _ => panic!(),
1700 }
1701 }
1702
translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration1703 fn translate_struct_declaration(state: &mut State, d: &syntax::SingleDeclaration) -> Declaration {
1704 let ty = d.ty.clone();
1705 let ty_def = match &ty.ty.ty {
1706 TypeSpecifierNonArray::Struct(s) => {
1707 let decl = SymDecl::Struct(lift(state, s));
1708 Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1709 }
1710 _ => None,
1711 };
1712
1713 let ty_def = ty_def.expect("Must be type definition");
1714
1715 Declaration::StructDefinition(ty_def)
1716 }
1717
get_expr_index(e: &syntax::Expr) -> i321718 fn get_expr_index(e: &syntax::Expr) -> i32 {
1719 match e {
1720 syntax::Expr::IntConst(i) => *i,
1721 syntax::Expr::UIntConst(u) => *u as i32,
1722 syntax::Expr::FloatConst(f) => *f as i32,
1723 syntax::Expr::DoubleConst(f) => *f as i32,
1724 _ => panic!(),
1725 }
1726 }
1727
translate_variable_declaration( state: &mut State, d: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1728 fn translate_variable_declaration(
1729 state: &mut State,
1730 d: &syntax::InitDeclaratorList,
1731 default_run_class: RunClass,
1732 ) -> Declaration {
1733 let mut ty = d.head.ty.clone();
1734 ty.ty.array_specifier = d.head.array_specifier.clone();
1735 let ty_def = match &ty.ty.ty {
1736 TypeSpecifierNonArray::Struct(s) => {
1737 let decl = SymDecl::Struct(lift(state, s));
1738 Some(state.declare(s.name.as_ref().unwrap().as_str(), decl))
1739 }
1740 _ => None,
1741 };
1742
1743 let mut ty: Type = lift(state, &d.head.ty);
1744 if let Some(array) = &d.head.array_specifier {
1745 ty.array_sizes = Some(Box::new(lift(state, array)))
1746 }
1747
1748 let (sym, decl) = match d.head.name.as_ref() {
1749 Some(name) => {
1750 let mut storage = StorageClass::None;
1751 let mut interpolation = None;
1752 for qual in d
1753 .head
1754 .ty
1755 .qualifier
1756 .iter()
1757 .flat_map(|x| x.qualifiers.0.iter())
1758 {
1759 match qual {
1760 syntax::TypeQualifierSpec::Storage(s) => match (&storage, s) {
1761 (StorageClass::FragColor(..), syntax::StorageQualifier::Out) => {}
1762 (StorageClass::Sampler(..), syntax::StorageQualifier::Uniform) => {}
1763 (StorageClass::None, syntax::StorageQualifier::Out) => {
1764 storage = StorageClass::Out;
1765 }
1766 (StorageClass::None, syntax::StorageQualifier::In) => {
1767 storage = StorageClass::In;
1768 }
1769 (StorageClass::None, syntax::StorageQualifier::Uniform) => {
1770 if ty.kind.is_sampler() {
1771 storage = StorageClass::Sampler(SamplerFormat::Unknown);
1772 } else {
1773 storage = StorageClass::Uniform;
1774 }
1775 }
1776 (StorageClass::None, syntax::StorageQualifier::Const) => {
1777 storage = StorageClass::Const;
1778 }
1779 _ => panic!("bad storage {:?}", (storage, s)),
1780 },
1781 syntax::TypeQualifierSpec::Interpolation(i) => match (&interpolation, i) {
1782 (None, i) => interpolation = Some(i.clone()),
1783 _ => panic!("multiple interpolation"),
1784 },
1785 syntax::TypeQualifierSpec::Layout(l) => {
1786 let mut loc = -1;
1787 let mut index = -1;
1788 for id in &l.ids {
1789 match id {
1790 syntax::LayoutQualifierSpec::Identifier(ref key, None) => {
1791 match key.as_str() {
1792 "rgba8" => {
1793 storage = StorageClass::Sampler(SamplerFormat::RGBA8);
1794 }
1795 "rgba32f" => {
1796 storage = StorageClass::Sampler(SamplerFormat::RGBA32F);
1797 }
1798 "rgba32i" => {
1799 storage = StorageClass::Sampler(SamplerFormat::RGBA32I);
1800 }
1801 "r8" => {
1802 storage = StorageClass::Sampler(SamplerFormat::R8);
1803 }
1804 "rg8" => {
1805 storage = StorageClass::Sampler(SamplerFormat::RG8);
1806 }
1807 _ => {}
1808 }
1809 }
1810 syntax::LayoutQualifierSpec::Identifier(ref key, Some(ref e)) => {
1811 match key.as_str() {
1812 "location" => {
1813 loc = get_expr_index(e);
1814 }
1815 "index" => {
1816 index = get_expr_index(e);
1817 }
1818 _ => {}
1819 }
1820 }
1821 _ => {}
1822 }
1823 }
1824 if index >= 0 {
1825 assert!(loc == 0);
1826 assert!(index <= 1);
1827 assert!(storage == StorageClass::None);
1828 storage = StorageClass::FragColor(index);
1829 }
1830 }
1831 _ => {}
1832 }
1833 }
1834 let decl = if state.in_function.is_some() {
1835 let run_class = match storage {
1836 StorageClass::Const => RunClass::Scalar,
1837 StorageClass::None => default_run_class,
1838 _ => panic!("bad local storage {:?}", storage),
1839 };
1840 SymDecl::Local(storage, ty.clone(), run_class)
1841 } else {
1842 let run_class = match storage {
1843 StorageClass::Const | StorageClass::Uniform | StorageClass::Sampler(..) => {
1844 RunClass::Scalar
1845 }
1846 StorageClass::In | StorageClass::Out | StorageClass::FragColor(..)
1847 if interpolation == Some(syntax::InterpolationQualifier::Flat) =>
1848 {
1849 RunClass::Scalar
1850 }
1851 _ => RunClass::Vector,
1852 };
1853 SymDecl::Global(storage, interpolation, ty.clone(), run_class)
1854 };
1855 (state.declare(name.as_str(), decl.clone()), decl)
1856 }
1857 None => panic!(),
1858 };
1859
1860 let head = SingleDeclaration {
1861 qualifier: lift_type_qualifier_for_declaration(state, &d.head.ty.qualifier),
1862 name: sym,
1863 ty,
1864 ty_def,
1865 initializer: d
1866 .head
1867 .initializer
1868 .as_ref()
1869 .map(|x| translate_initializater(state, x)),
1870 };
1871
1872 let tail = d
1873 .tail
1874 .iter()
1875 .map(|d| {
1876 if let Some(_array) = &d.ident.array_spec {
1877 panic!("unhandled array")
1878 }
1879 state.declare(d.ident.ident.as_str(), decl.clone());
1880 SingleDeclarationNoType {
1881 ident: d.ident.clone(),
1882 initializer: d
1883 .initializer
1884 .as_ref()
1885 .map(|x| translate_initializater(state, x)),
1886 }
1887 })
1888 .collect();
1889 Declaration::InitDeclaratorList(InitDeclaratorList { head, tail })
1890 }
1891
translate_init_declarator_list( state: &mut State, l: &syntax::InitDeclaratorList, default_run_class: RunClass, ) -> Declaration1892 fn translate_init_declarator_list(
1893 state: &mut State,
1894 l: &syntax::InitDeclaratorList,
1895 default_run_class: RunClass,
1896 ) -> Declaration {
1897 match &l.head.name {
1898 Some(_name) => translate_variable_declaration(state, l, default_run_class),
1899 None => translate_struct_declaration(state, &l.head),
1900 }
1901 }
1902
translate_declaration( state: &mut State, d: &syntax::Declaration, default_run_class: RunClass, ) -> Declaration1903 fn translate_declaration(
1904 state: &mut State,
1905 d: &syntax::Declaration,
1906 default_run_class: RunClass,
1907 ) -> Declaration {
1908 match d {
1909 syntax::Declaration::Block(_) => panic!(), //Declaration::Block(..),
1910 syntax::Declaration::FunctionPrototype(p) => {
1911 Declaration::FunctionPrototype(translate_function_prototype(state, p))
1912 }
1913 syntax::Declaration::Global(ty, ids) => {
1914 // glsl non-es supports requalifying variables, but we don't yet.
1915 // However, we still want to allow global layout qualifiers for
1916 // KHR_advanced_blend_equation.
1917 if !ids.is_empty() {
1918 panic!();
1919 }
1920 let _ = for qual in &ty.qualifiers {
1921 match qual {
1922 syntax::TypeQualifierSpec::Layout(l) => {
1923 for id in &l.ids {
1924 match id {
1925 syntax::LayoutQualifierSpec::Identifier(key, _) => {
1926 match key.as_str() {
1927 "blend_support_all_equations" => (),
1928 _ => panic!(),
1929 }
1930 }
1931 _ => panic!(),
1932 }
1933 }
1934 }
1935 syntax::TypeQualifierSpec::Storage(syntax::StorageQualifier::Out) => (),
1936 _ => panic!(),
1937 }
1938 };
1939 Declaration::Global(lift_type_qualifier_for_declaration(state, &Some(ty.clone())).unwrap(), ids.clone())
1940 }
1941 syntax::Declaration::InitDeclaratorList(dl) => {
1942 translate_init_declarator_list(state, dl, default_run_class)
1943 }
1944 syntax::Declaration::Precision(p, ts) => Declaration::Precision(p.clone(), ts.clone()),
1945 }
1946 }
1947
is_vector(ty: &Type) -> bool1948 fn is_vector(ty: &Type) -> bool {
1949 match ty.kind {
1950 TypeKind::Vec2
1951 | TypeKind::Vec3
1952 | TypeKind::Vec4
1953 | TypeKind::BVec2
1954 | TypeKind::BVec3
1955 | TypeKind::BVec4
1956 | TypeKind::IVec2
1957 | TypeKind::IVec3
1958 | TypeKind::IVec4 => ty.array_sizes == None,
1959 _ => false,
1960 }
1961 }
1962
index_vector(ty: &Type) -> Option<TypeKind>1963 fn index_vector(ty: &Type) -> Option<TypeKind> {
1964 use TypeKind::*;
1965 if ty.array_sizes != None {
1966 return None;
1967 }
1968 Some(match ty.kind {
1969 Vec2 => Float,
1970 Vec3 => Float,
1971 Vec4 => Float,
1972 DVec2 => Double,
1973 DVec3 => Double,
1974 DVec4 => Double,
1975 BVec2 => Bool,
1976 BVec3 => Bool,
1977 BVec4 => Bool,
1978 IVec2 => Int,
1979 IVec3 => Int,
1980 IVec4 => Int,
1981 UVec2 => UInt,
1982 UVec3 => UInt,
1983 UVec4 => UInt,
1984 _ => return None,
1985 })
1986
1987 }
1988
index_matrix(ty: &Type) -> Option<TypeKind>1989 fn index_matrix(ty: &Type) -> Option<TypeKind> {
1990 use TypeKind::*;
1991 if ty.array_sizes != None {
1992 return None;
1993 }
1994 Some(match ty.kind {
1995 Mat2 => Vec2,
1996 Mat3 => Vec3,
1997 Mat4 => Vec4,
1998 Mat23 => Vec3,
1999 Mat24 => Vec4,
2000 Mat32 => Vec2,
2001 Mat34 => Vec4,
2002 Mat42 => Vec2,
2003 Mat43 => Vec3,
2004 DMat2 => DVec2,
2005 DMat3 => DVec3,
2006 DMat4 => DVec4,
2007 DMat23 => DVec3,
2008 DMat24 => DVec4,
2009 DMat32 => DVec2,
2010 DMat34 => DVec4,
2011 DMat42 => DVec2,
2012 DMat43 => DVec3,
2013 _ => return None,
2014 })
2015 }
2016
is_ivec(ty: &Type) -> bool2017 fn is_ivec(ty: &Type) -> bool {
2018 match ty.kind {
2019 TypeKind::IVec2 | TypeKind::IVec3 | TypeKind::IVec4 => ty.array_sizes == None,
2020 _ => false,
2021 }
2022 }
2023
can_implicitly_convert_to(src: &Type, dst: &Type) -> bool2024 fn can_implicitly_convert_to(src: &Type, dst: &Type) -> bool {
2025 // XXX: use an underlying type helper
2026 if src == &Type::new(TypeKind::Double) && dst == &Type::new(TypeKind::Float) {
2027 // We're not supposed to implicitly convert from double to float but glsl 4 has a bug
2028 // where it parses unannotated float constants as double.
2029 true
2030 } else if dst == &Type::new(TypeKind::Double) && src == &Type::new(TypeKind::Float) {
2031 true
2032 } else if (dst == &Type::new(TypeKind::Float) || dst == &Type::new(TypeKind::Double)) &&
2033 src == &Type::new(TypeKind::Int)
2034 {
2035 true
2036 } else if (dst == &Type::new(TypeKind::Vec2) || dst == &Type::new(TypeKind::DVec2)) &&
2037 src == &Type::new(TypeKind::IVec2)
2038 {
2039 true
2040 } else if dst == &Type::new(TypeKind::IVec2) &&
2041 (src == &Type::new(TypeKind::Vec2) || src == &Type::new(TypeKind::DVec2))
2042 {
2043 true
2044 } else {
2045 src.kind == dst.kind && src.array_sizes == dst.array_sizes
2046 }
2047 }
2048
promoted_type(lhs: &Type, rhs: &Type) -> Type2049 fn promoted_type(lhs: &Type, rhs: &Type) -> Type {
2050 if lhs == &Type::new(TypeKind::Double) && rhs == &Type::new(TypeKind::Float) {
2051 Type::new(TypeKind::Double)
2052 } else if lhs == &Type::new(TypeKind::Float) && rhs == &Type::new(TypeKind::Double) {
2053 Type::new(TypeKind::Double)
2054 } else if lhs == &Type::new(TypeKind::Int) && rhs == &Type::new(TypeKind::Double) {
2055 Type::new(TypeKind::Double)
2056 } else if is_vector(&lhs) &&
2057 (rhs == &Type::new(TypeKind::Float) ||
2058 rhs == &Type::new(TypeKind::Double) ||
2059 rhs == &Type::new(TypeKind::Int))
2060 {
2061 // scalars promote to vectors
2062 lhs.clone()
2063 } else if is_vector(&rhs) &&
2064 (lhs == &Type::new(TypeKind::Float) ||
2065 lhs == &Type::new(TypeKind::Double) ||
2066 lhs == &Type::new(TypeKind::Int))
2067 {
2068 // scalars promote to vectors
2069 rhs.clone()
2070 } else if lhs == rhs {
2071 lhs.clone()
2072 } else if lhs.kind == rhs.kind {
2073 if lhs.array_sizes == rhs.array_sizes {
2074 // XXX: we need to be able to query the default precision here
2075 match (&lhs.precision, &rhs.precision) {
2076 (Some(PrecisionQualifier::High), _) => lhs.clone(),
2077 (_, Some(PrecisionQualifier::High)) => rhs.clone(),
2078 (None, _) => lhs.clone(),
2079 (_, None) => rhs.clone(),
2080 _ => panic!("precision mismatch {:?} {:?}", lhs.precision, rhs.precision),
2081 }
2082 } else {
2083 panic!("array size mismatch")
2084 }
2085 } else {
2086 assert_eq!(lhs, rhs);
2087 lhs.clone()
2088 }
2089 }
2090
is_output(expr: &Expr, state: &State) -> Option<SymRef>2091 pub fn is_output(expr: &Expr, state: &State) -> Option<SymRef> {
2092 match &expr.kind {
2093 ExprKind::Variable(i) => match state.sym(*i).decl {
2094 SymDecl::Global(storage, ..) => match storage {
2095 StorageClass::In | StorageClass::Out => return Some(*i),
2096 _ => {}
2097 },
2098 SymDecl::Local(..) => {}
2099 _ => panic!("should be variable"),
2100 },
2101 ExprKind::SwizzleSelector(e, ..) => {
2102 return is_output(e, state);
2103 }
2104 ExprKind::Bracket(e, ..) => {
2105 return is_output(e, state);
2106 }
2107 ExprKind::Dot(e, ..) => {
2108 return is_output(e, state);
2109 }
2110 _ => {}
2111 };
2112 None
2113 }
2114
get_texel_fetch_offset( state: &State, sampler_expr: &Expr, uv_expr: &Expr, offset_expr: &Expr, ) -> Option<(SymRef, SymRef, i32, i32)>2115 pub fn get_texel_fetch_offset(
2116 state: &State,
2117 sampler_expr: &Expr,
2118 uv_expr: &Expr,
2119 offset_expr: &Expr,
2120 ) -> Option<(SymRef, SymRef, i32, i32)> {
2121 if let ExprKind::Variable(ref sampler) = &sampler_expr.kind {
2122 //if let ExprKind::Binary(BinaryOp::Add, ref lhs, ref rhs) = &uv_expr.kind {
2123 if let ExprKind::Variable(ref base) = &uv_expr.kind {
2124 if let ExprKind::FunCall(ref fun, ref args) = &offset_expr.kind {
2125 if let FunIdentifier::Identifier(ref offset) = fun {
2126 if state.sym(*offset).name == "ivec2" {
2127 if let ExprKind::IntConst(ref x) = &args[0].kind {
2128 if let ExprKind::IntConst(ref y) = &args[1].kind {
2129 return Some((*sampler, *base, *x, *y));
2130 }
2131 }
2132 }
2133 }
2134 }
2135 }
2136 //}
2137 }
2138 None
2139 }
2140
make_const(t: TypeKind, v: i32) -> Expr2141 fn make_const(t: TypeKind, v: i32) -> Expr {
2142 Expr {
2143 kind: match t {
2144 TypeKind::Int => ExprKind::IntConst(v as _),
2145 TypeKind::UInt => ExprKind::UIntConst(v as _),
2146 TypeKind::Bool => ExprKind::BoolConst(v != 0),
2147 TypeKind::Float => ExprKind::FloatConst(v as _),
2148 TypeKind::Double => ExprKind::DoubleConst(v as _),
2149 _ => panic!("bad constant type"),
2150 },
2151 ty: Type::new(t),
2152 }
2153 }
2154
2155 // Any parameters needing to convert to bool should just compare via != 0.
2156 // This ensures they get the proper all-1s pattern for C++ OpenCL vectors.
force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>)2157 fn force_params_to_bool(_state: &mut State, params: &mut Vec<Expr>) {
2158 for e in params {
2159 if !e.ty.kind.is_bool() {
2160 let k = e.ty.kind;
2161 *e = Expr {
2162 kind: ExprKind::Binary(
2163 BinaryOp::NonEqual,
2164 Box::new(e.clone()),
2165 Box::new(make_const(k.to_scalar(), 0)),
2166 ),
2167 ty: Type::new(k.to_bool()),
2168 };
2169 }
2170 }
2171 }
2172
2173 // Transform bool params to int, then mask off the low bit so they become 0 or 1.
2174 // C++ OpenCL vectors represent bool as all-1s patterns, which will erroneously
2175 // convert to -1 otherwise.
force_params_from_bool(state: &mut State, params: &mut Vec<Expr>)2176 fn force_params_from_bool(state: &mut State, params: &mut Vec<Expr>) {
2177 for e in params {
2178 if e.ty.kind.is_bool() {
2179 let k = e.ty.kind.to_int();
2180 let sym = state.lookup(k.glsl_primitive_type_name().unwrap()).unwrap();
2181 *e = Expr {
2182 kind: ExprKind::Binary(
2183 BinaryOp::BitAnd,
2184 Box::new(Expr {
2185 kind: ExprKind::FunCall(
2186 FunIdentifier::Identifier(sym),
2187 vec![e.clone()],
2188 ),
2189 ty: Type::new(k),
2190 }),
2191 Box::new(make_const(TypeKind::Int, 1)),
2192 ),
2193 ty: Type::new(k),
2194 };
2195 }
2196 }
2197 }
2198
translate_expression(state: &mut State, e: &syntax::Expr) -> Expr2199 fn translate_expression(state: &mut State, e: &syntax::Expr) -> Expr {
2200 match e {
2201 syntax::Expr::Variable(i) => {
2202 let sym = match state.lookup(i.as_str()) {
2203 Some(sym) => sym,
2204 None => panic!("missing declaration {}", i.as_str()),
2205 };
2206 let ty = match &state.sym(sym).decl {
2207 SymDecl::Global(_, _, ty, _) => {
2208 let mut globals = state.used_globals.borrow_mut();
2209 if !globals.contains(&sym) {
2210 globals.push(sym);
2211 }
2212 ty.clone()
2213 }
2214 SymDecl::Local(_, ty, _) => ty.clone(),
2215 _ => panic!("bad variable type"),
2216 };
2217 Expr {
2218 kind: ExprKind::Variable(sym),
2219 ty,
2220 }
2221 }
2222 syntax::Expr::Assignment(lhs, op, rhs) => {
2223 let lhs = Box::new(translate_expression(state, lhs));
2224 let rhs = Box::new(translate_expression(state, rhs));
2225 let ty = if op == &AssignmentOp::Mult {
2226 if lhs.ty.kind == TypeKind::Vec4 && rhs.ty.kind == TypeKind::Float {
2227 lhs.ty.clone()
2228 } else {
2229 promoted_type(&lhs.ty, &rhs.ty)
2230 }
2231 } else {
2232 promoted_type(&lhs.ty, &rhs.ty)
2233 };
2234 if let Some(global) = is_output(&lhs, state) {
2235 let mut globals = state.modified_globals.borrow_mut();
2236 if !globals.contains(&global) {
2237 globals.push(global);
2238 }
2239 if global == state.clip_dist_sym {
2240 if let ExprKind::Bracket(_, idx) = &lhs.kind {
2241 // Get the constant array index used for gl_ClipDistance and add it to the used mask.
2242 let idx = match idx.kind {
2243 ExprKind::IntConst(idx) => idx,
2244 ExprKind::UIntConst(idx) => idx as i32,
2245 _ => panic!("bad index for gl_ClipDistance"),
2246 };
2247 assert!(idx >= 0 && idx < 4);
2248 state.used_clip_dist |= 1 << idx;
2249 }
2250 }
2251 }
2252 Expr {
2253 kind: ExprKind::Assignment(lhs, op.clone(), rhs),
2254 ty,
2255 }
2256 }
2257 syntax::Expr::Binary(op, lhs, rhs) => {
2258 let lhs = Box::new(translate_expression(state, lhs));
2259 let rhs = Box::new(translate_expression(state, rhs));
2260 let ty = match op {
2261 BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => {
2262 // comparison operators have a bool result
2263 Type::new(TypeKind::Bool)
2264 }
2265 BinaryOp::Mult => {
2266 match (lhs.ty.kind, rhs.ty.kind) {
2267 (TypeKind::Mat2, TypeKind::Vec2) |
2268 (TypeKind::Mat3, TypeKind::Vec3) |
2269 (TypeKind::Mat3, TypeKind::Mat3) |
2270 (TypeKind::Mat3, TypeKind::Mat43) |
2271 (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(),
2272 (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3),
2273 (TypeKind::Mat2, TypeKind::Float) |
2274 (TypeKind::Mat3, TypeKind::Float) |
2275 (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(),
2276 _ => promoted_type(&lhs.ty, &rhs.ty),
2277 }
2278 }
2279 _ => promoted_type(&lhs.ty, &rhs.ty),
2280 };
2281
2282 Expr {
2283 kind: ExprKind::Binary(op.clone(), lhs, rhs),
2284 ty,
2285 }
2286 }
2287 syntax::Expr::Unary(op, e) => {
2288 let e = Box::new(translate_expression(state, e));
2289 let ty = e.ty.clone();
2290 Expr {
2291 kind: ExprKind::Unary(op.clone(), e),
2292 ty,
2293 }
2294 }
2295 syntax::Expr::BoolConst(b) => Expr {
2296 kind: ExprKind::BoolConst(*b),
2297 ty: Type::new(TypeKind::Bool),
2298 },
2299 syntax::Expr::Comma(lhs, rhs) => {
2300 let lhs = Box::new(translate_expression(state, lhs));
2301 let rhs = Box::new(translate_expression(state, rhs));
2302 assert_eq!(lhs.ty, rhs.ty);
2303 let ty = lhs.ty.clone();
2304 Expr {
2305 kind: ExprKind::Comma(lhs, rhs),
2306 ty,
2307 }
2308 }
2309 syntax::Expr::DoubleConst(d) => Expr {
2310 kind: ExprKind::DoubleConst(*d),
2311 ty: Type::new(TypeKind::Double),
2312 },
2313 syntax::Expr::FloatConst(f) => Expr {
2314 kind: ExprKind::FloatConst(*f),
2315 ty: Type::new(TypeKind::Float),
2316 },
2317 syntax::Expr::FunCall(fun, params) => {
2318 let ret_ty: Type;
2319 let mut params: Vec<Expr> = params
2320 .iter()
2321 .map(|x| translate_expression(state, x))
2322 .collect();
2323 Expr {
2324 kind: ExprKind::FunCall(
2325 match fun {
2326 syntax::FunIdentifier::Identifier(i) => {
2327 let name = i.as_str();
2328 if name == "texelFetchOffset" && params.len() >= 4 {
2329 if let Some((sampler, base, x, y)) = get_texel_fetch_offset(
2330 state, ¶ms[0], ¶ms[1], ¶ms[3],
2331 ) {
2332 if let Some(offsets) =
2333 state.texel_fetches.get_mut(&(sampler, base))
2334 {
2335 offsets.add_offset(x, y);
2336 } else {
2337 state
2338 .texel_fetches
2339 .insert((sampler, base), TexelFetchOffsets::new(x, y));
2340 }
2341 }
2342 } else if name == "swgl_stepInterp" {
2343 let mut globals = state.modified_globals.borrow_mut();
2344 for (i, sym) in state.syms.iter().enumerate() {
2345 match &sym.borrow().decl {
2346 SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => {
2347 let symref = SymRef(i as u32);
2348 if !globals.contains(&symref) {
2349 globals.push(symref);
2350 }
2351 }
2352 _ => {}
2353 }
2354 }
2355 }
2356 let sym = match state.lookup(name) {
2357 Some(s) => s,
2358 None => panic!("missing symbol {}", name),
2359 };
2360 // Force any boolean basic type constructors to generate correct
2361 // bit patterns.
2362 if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) {
2363 if t.is_bool() {
2364 force_params_to_bool(state, &mut params);
2365 } else {
2366 force_params_from_bool(state, &mut params);
2367 }
2368 }
2369 match &state.sym(sym).decl {
2370 SymDecl::NativeFunction(fn_ty, _, _) => {
2371 // Search for a signature where all parameter types are
2372 // compatible. If there are many compatible signatures,
2373 // then choose the one with the most exact matches.
2374 // This is an approximation of the algorith described in
2375 // the "Function Definitions" section of the spec.
2376 let mut ret = None;
2377 let mut best_score = 0;
2378 'next_sig: for sig in &fn_ty.signatures {
2379 let mut score = 0;
2380 for (e, p) in params.iter().zip(sig.params.iter()) {
2381 if e.ty == *p {
2382 score += 1;
2383 } else if !can_implicitly_convert_to(&e.ty, p) {
2384 continue 'next_sig;
2385 }
2386 }
2387 if score >= best_score {
2388 ret = Some(sig.ret.clone());
2389 best_score = score;
2390 // If all parameters match exactly, then there
2391 // is no need to search for other matches.
2392 if best_score >= params.len() {
2393 break;
2394 }
2395 }
2396 }
2397 ret_ty = match ret {
2398 Some(t) => t,
2399 None => {
2400 dbg!(&fn_ty.signatures);
2401 dbg!(params.iter().map(|p| p).collect::<Vec<_>>());
2402 panic!("no matching func {}", i.as_str())
2403 }
2404 };
2405 }
2406 SymDecl::UserFunction(fd, _) => {
2407 let mut globals = state.modified_globals.borrow_mut();
2408 for global in &fd.globals {
2409 if !globals.contains(global) {
2410 globals.push(*global);
2411 }
2412 }
2413 let mut matching = true;
2414 for (e, p) in params.iter().zip(fd.prototype.parameters.iter())
2415 {
2416 matching &= match p {
2417 FunctionParameterDeclaration::Named(q, d) => {
2418 match q {
2419 Some(ParameterQualifier::InOut)
2420 | Some(ParameterQualifier::Out) => {
2421 if let Some(global) = is_output(e, state) {
2422 if !globals.contains(&global) {
2423 globals.push(global);
2424 }
2425 }
2426 }
2427 _ => {}
2428 }
2429 can_implicitly_convert_to(&e.ty, &d.ty)
2430 }
2431 FunctionParameterDeclaration::Unnamed(..) => panic!(),
2432 };
2433 }
2434 assert!(matching);
2435 ret_ty = fd.prototype.ty.clone();
2436 }
2437 SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)),
2438 _ => panic!("can only call functions"),
2439 };
2440 FunIdentifier::Identifier(sym)
2441 }
2442 // array constructor
2443 syntax::FunIdentifier::Expr(e) => {
2444 let ty = match &**e {
2445 syntax::Expr::Bracket(i, array) => {
2446 let kind = match &**i {
2447 syntax::Expr::Variable(i) => match i.as_str() {
2448 "vec4" => TypeKind::Vec4,
2449 "vec2" => TypeKind::Vec2,
2450 "int" => TypeKind::Int,
2451 _ => panic!("unexpected type constructor {:?}", i),
2452 },
2453 _ => panic!(),
2454 };
2455
2456 Type {
2457 kind,
2458 precision: None,
2459 array_sizes: Some(Box::new(lift(state, array))),
2460 }
2461 }
2462 _ => panic!(),
2463 };
2464 ret_ty = ty.clone();
2465
2466 FunIdentifier::Constructor(ty)
2467 }
2468 },
2469 params,
2470 ),
2471 ty: ret_ty,
2472 }
2473 }
2474 syntax::Expr::IntConst(i) => Expr {
2475 kind: ExprKind::IntConst(*i),
2476 ty: Type::new(TypeKind::Int),
2477 },
2478 syntax::Expr::UIntConst(u) => Expr {
2479 kind: ExprKind::UIntConst(*u),
2480 ty: Type::new(TypeKind::UInt),
2481 },
2482 syntax::Expr::PostDec(e) => {
2483 let e = Box::new(translate_expression(state, e));
2484 let ty = e.ty.clone();
2485 Expr {
2486 kind: ExprKind::PostDec(e),
2487 ty,
2488 }
2489 }
2490 syntax::Expr::PostInc(e) => {
2491 let e = Box::new(translate_expression(state, e));
2492 let ty = e.ty.clone();
2493 Expr {
2494 kind: ExprKind::PostInc(e),
2495 ty,
2496 }
2497 }
2498 syntax::Expr::Ternary(cond, lhs, rhs) => {
2499 let cond = Box::new(translate_expression(state, cond));
2500 let lhs = Box::new(translate_expression(state, lhs));
2501 let rhs = Box::new(translate_expression(state, rhs));
2502 let ty = promoted_type(&lhs.ty, &rhs.ty);
2503 Expr {
2504 kind: ExprKind::Ternary(cond, lhs, rhs),
2505 ty,
2506 }
2507 }
2508 syntax::Expr::Dot(e, i) => {
2509 let e = Box::new(translate_expression(state, e));
2510 let ty = e.ty.clone();
2511 let ivec = is_ivec(&ty);
2512 if is_vector(&ty) {
2513 let ty = Type::new(match i.as_str().len() {
2514 1 => {
2515 if ivec {
2516 TypeKind::Int
2517 } else {
2518 TypeKind::Float
2519 }
2520 }
2521 2 => {
2522 if ivec {
2523 TypeKind::IVec2
2524 } else {
2525 TypeKind::Vec2
2526 }
2527 }
2528 3 => {
2529 if ivec {
2530 TypeKind::IVec3
2531 } else {
2532 TypeKind::Vec3
2533 }
2534 }
2535 4 => {
2536 if ivec {
2537 TypeKind::IVec4
2538 } else {
2539 TypeKind::Vec4
2540 }
2541 }
2542 _ => panic!(),
2543 });
2544
2545 let sel = SwizzleSelector::parse(i.as_str());
2546
2547 Expr {
2548 kind: ExprKind::SwizzleSelector(e, sel),
2549 ty,
2550 }
2551 } else {
2552 match ty.kind {
2553 TypeKind::Struct(s) => {
2554 let sym = state.sym(s);
2555 let fields = match &sym.decl {
2556 SymDecl::Struct(fields) => fields,
2557 _ => panic!("expected struct"),
2558 };
2559 let field = fields
2560 .fields
2561 .iter()
2562 .find(|x| &x.name == i)
2563 .expect(&format!("missing field `{}` in `{}`", i, sym.name));
2564 Expr {
2565 kind: ExprKind::Dot(e, i.clone()),
2566 ty: field.ty.clone(),
2567 }
2568 }
2569 _ => panic!("expected struct found {:#?} {:#?}", e, ty),
2570 }
2571 }
2572 }
2573 syntax::Expr::Bracket(e, specifier) => {
2574 let e = Box::new(translate_expression(state, e));
2575 let ty = if let Some(ty) = index_vector(&e.ty) {
2576 Type::new(ty)
2577 } else if let Some(ty) = index_matrix(&e.ty) {
2578 Type::new(ty)
2579 } else {
2580 let a = match &e.ty.array_sizes {
2581 Some(a) => {
2582 let mut a = *a.clone();
2583 a.sizes.pop();
2584 if a.sizes.len() == 0 {
2585 None
2586 } else {
2587 Some(Box::new(a))
2588 }
2589 }
2590 _ => panic!("{:#?}", e),
2591 };
2592 Type {
2593 kind: e.ty.kind.clone(),
2594 precision: e.ty.precision.clone(),
2595 array_sizes: a,
2596 }
2597 };
2598 let indx = match specifier {
2599 ArraySpecifier::Unsized => panic!("need expression"),
2600 ArraySpecifier::ExplicitlySized(e) => translate_expression(state, e),
2601 };
2602 Expr {
2603 kind: ExprKind::Bracket(e, Box::new(indx)),
2604 ty,
2605 }
2606 }
2607 }
2608 }
2609
translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement2610 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement {
2611 let mut cases = Vec::new();
2612
2613 let mut case = None;
2614 for stmt in &s.body {
2615 match stmt {
2616 syntax::Statement::Simple(s) => match &**s {
2617 syntax::SimpleStatement::CaseLabel(label) => {
2618 match case.take() {
2619 Some(case) => cases.push(case),
2620 _ => {}
2621 }
2622 case = Some(Case {
2623 label: translate_case(state, &label),
2624 stmts: Vec::new(),
2625 })
2626 }
2627 _ => match case {
2628 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2629 _ => panic!("switch must start with case"),
2630 },
2631 },
2632 _ => match case {
2633 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)),
2634 _ => panic!("switch must start with case"),
2635 },
2636 }
2637 }
2638 match case.take() {
2639 Some(case) => cases.push(case),
2640 _ => {}
2641 }
2642 SwitchStatement {
2643 head: Box::new(translate_expression(state, &s.head)),
2644 cases,
2645 }
2646 }
2647
translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement2648 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement {
2649 match s {
2650 syntax::JumpStatement::Break => JumpStatement::Break,
2651 syntax::JumpStatement::Continue => JumpStatement::Continue,
2652 syntax::JumpStatement::Discard => JumpStatement::Discard,
2653 syntax::JumpStatement::Return(e) => {
2654 JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e))))
2655 }
2656 }
2657 }
2658
translate_condition(state: &mut State, c: &syntax::Condition) -> Condition2659 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition {
2660 match c {
2661 syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))),
2662 _ => panic!(),
2663 }
2664 }
2665
translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement2666 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement {
2667 match s {
2668 syntax::ForInitStatement::Expression(e) => {
2669 ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2670 }
2671 syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new(
2672 translate_declaration(state, d, RunClass::Scalar),
2673 )),
2674 }
2675 }
2676
translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement2677 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement {
2678 ForRestStatement {
2679 condition: s.condition.as_ref().map(|c| translate_condition(state, c)),
2680 post_expr: s
2681 .post_expr
2682 .as_ref()
2683 .map(|e| Box::new(translate_expression(state, e))),
2684 }
2685 }
2686
translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement2687 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement {
2688 match s {
2689 syntax::IterationStatement::While(cond, s) => IterationStatement::While(
2690 translate_condition(state, cond),
2691 Box::new(translate_statement(state, s)),
2692 ),
2693 syntax::IterationStatement::For(init, rest, s) => IterationStatement::For(
2694 translate_for_init(state, init),
2695 translate_for_rest(state, rest),
2696 Box::new(translate_statement(state, s)),
2697 ),
2698 syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile(
2699 Box::new(translate_statement(state, s)),
2700 Box::new(translate_expression(state, e)),
2701 ),
2702 }
2703 }
2704
translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel2705 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel {
2706 match c {
2707 syntax::CaseLabel::Def => CaseLabel::Def,
2708 syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))),
2709 }
2710 }
2711
translate_selection_rest( state: &mut State, s: &syntax::SelectionRestStatement, ) -> (Box<Statement>, Option<Box<Statement>>)2712 fn translate_selection_rest(
2713 state: &mut State,
2714 s: &syntax::SelectionRestStatement,
2715 ) -> (Box<Statement>, Option<Box<Statement>>) {
2716 match s {
2717 syntax::SelectionRestStatement::Statement(s) => {
2718 (Box::new(translate_statement(state, s)), None)
2719 }
2720 syntax::SelectionRestStatement::Else(if_body, rest) => (
2721 Box::new(translate_statement(state, if_body)),
2722 Some(Box::new(translate_statement(state, rest))),
2723 ),
2724 }
2725 }
2726
translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement2727 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement {
2728 let cond = Box::new(translate_expression(state, &s.cond));
2729 let (body, else_stmt) = translate_selection_rest(state, &s.rest);
2730 SelectionStatement {
2731 cond,
2732 body,
2733 else_stmt,
2734 }
2735 }
2736
translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement2737 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement {
2738 match s {
2739 syntax::SimpleStatement::Declaration(d) => {
2740 SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown))
2741 }
2742 syntax::SimpleStatement::Expression(e) => {
2743 SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e)))
2744 }
2745 syntax::SimpleStatement::Iteration(i) => {
2746 SimpleStatement::Iteration(translate_iteration(state, i))
2747 }
2748 syntax::SimpleStatement::Selection(s) => {
2749 SimpleStatement::Selection(translate_selection(state, s))
2750 }
2751 syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)),
2752 syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)),
2753 syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"),
2754 }
2755 }
2756
translate_statement(state: &mut State, s: &syntax::Statement) -> Statement2757 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement {
2758 match s {
2759 syntax::Statement::Compound(s) => {
2760 Statement::Compound(Box::new(translate_compound_statement(state, s)))
2761 }
2762 syntax::Statement::Simple(s) => {
2763 Statement::Simple(Box::new(translate_simple_statement(state, s)))
2764 }
2765 }
2766 }
2767
translate_compound_statement( state: &mut State, cs: &syntax::CompoundStatement, ) -> CompoundStatement2768 fn translate_compound_statement(
2769 state: &mut State,
2770 cs: &syntax::CompoundStatement,
2771 ) -> CompoundStatement {
2772 CompoundStatement {
2773 statement_list: cs
2774 .statement_list
2775 .iter()
2776 .map(|x| translate_statement(state, x))
2777 .collect(),
2778 }
2779 }
2780
translate_function_parameter_declaration( state: &mut State, p: &syntax::FunctionParameterDeclaration, index: usize, ) -> FunctionParameterDeclaration2781 fn translate_function_parameter_declaration(
2782 state: &mut State,
2783 p: &syntax::FunctionParameterDeclaration,
2784 index: usize,
2785 ) -> FunctionParameterDeclaration {
2786 match p {
2787 syntax::FunctionParameterDeclaration::Named(qual, p) => {
2788 let mut ty: Type = lift(state, &p.ty);
2789 if let Some(a) = &p.ident.array_spec {
2790 ty.array_sizes = Some(Box::new(lift(state, a)));
2791 }
2792
2793 ty.precision = get_precision(qual);
2794
2795 let decl = SymDecl::Local(
2796 StorageClass::None,
2797 ty.clone(),
2798 RunClass::Dependent(1 << index),
2799 );
2800 let d = FunctionParameterDeclarator {
2801 ty,
2802 name: p.ident.ident.clone(),
2803 sym: state.declare(p.ident.ident.as_str(), decl),
2804 };
2805 FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d)
2806 }
2807 syntax::FunctionParameterDeclaration::Unnamed(qual, p) => {
2808 FunctionParameterDeclaration::Unnamed(
2809 lift_type_qualifier_for_parameter(state, qual),
2810 p.clone(),
2811 )
2812 }
2813 }
2814 }
2815
translate_prototype( state: &mut State, cs: &syntax::FunctionPrototype, ) -> (FunctionPrototype, SymRef)2816 fn translate_prototype(
2817 state: &mut State,
2818 cs: &syntax::FunctionPrototype,
2819 ) -> (FunctionPrototype, SymRef) {
2820 let prototype = FunctionPrototype {
2821 ty: lift(state, &cs.ty),
2822 name: cs.name.clone(),
2823 parameters: cs
2824 .parameters
2825 .iter()
2826 .enumerate()
2827 .map(|(i, x)| translate_function_parameter_declaration(state, x, i))
2828 .collect(),
2829 };
2830 let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) {
2831 match &state.sym(sym).decl {
2832 SymDecl::UserFunction(..) => {}
2833 _ => panic!(
2834 "prototype conflicts with existing symbol: {}",
2835 prototype.name.as_str()
2836 ),
2837 }
2838 sym
2839 } else {
2840 let pfd = Rc::new(FunctionDefinition {
2841 prototype: prototype.clone(),
2842 body: CompoundStatement::new(),
2843 globals: Vec::new(),
2844 texel_fetches: HashMap::new(),
2845 });
2846 state.declare(
2847 prototype.name.as_str(),
2848 SymDecl::UserFunction(pfd, RunClass::Unknown),
2849 )
2850 };
2851 (prototype, sym)
2852 }
2853
translate_function_prototype( state: &mut State, prototype: &syntax::FunctionPrototype, ) -> FunctionPrototype2854 fn translate_function_prototype(
2855 state: &mut State,
2856 prototype: &syntax::FunctionPrototype,
2857 ) -> FunctionPrototype {
2858 let (prototype, _) = translate_prototype(state, prototype);
2859 prototype
2860 }
2861
translate_function_definition( state: &mut State, sfd: &syntax::FunctionDefinition, ) -> Rc<FunctionDefinition>2862 fn translate_function_definition(
2863 state: &mut State,
2864 sfd: &syntax::FunctionDefinition,
2865 ) -> Rc<FunctionDefinition> {
2866 let (prototype, sym) = translate_prototype(state, &sfd.prototype);
2867
2868 state.push_scope(prototype.name.as_str().into());
2869 state.in_function = Some(sym);
2870 state.modified_globals.get_mut().clear();
2871 state.texel_fetches.clear();
2872 let body = translate_compound_statement(state, &sfd.statement);
2873 let mut globals = Vec::new();
2874 mem::swap(&mut globals, state.modified_globals.get_mut());
2875 let mut texel_fetches = HashMap::new();
2876 mem::swap(&mut texel_fetches, &mut state.texel_fetches);
2877 state.in_function = None;
2878 state.pop_scope();
2879
2880 let fd = Rc::new(FunctionDefinition {
2881 prototype,
2882 body,
2883 globals,
2884 texel_fetches,
2885 });
2886 state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown);
2887 fd
2888 }
2889
translate_external_declaration( state: &mut State, ed: &syntax::ExternalDeclaration, ) -> ExternalDeclaration2890 fn translate_external_declaration(
2891 state: &mut State,
2892 ed: &syntax::ExternalDeclaration,
2893 ) -> ExternalDeclaration {
2894 match ed {
2895 syntax::ExternalDeclaration::Declaration(d) => {
2896 ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown))
2897 }
2898 syntax::ExternalDeclaration::FunctionDefinition(fd) => {
2899 ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd))
2900 }
2901 syntax::ExternalDeclaration::Preprocessor(p) => {
2902 ExternalDeclaration::Preprocessor(p.clone())
2903 }
2904 }
2905 }
2906
declare_function_ext( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, run_class: RunClass, )2907 fn declare_function_ext(
2908 state: &mut State,
2909 name: &str,
2910 cxx_name: Option<&'static str>,
2911 ret: Type,
2912 params: Vec<Type>,
2913 run_class: RunClass,
2914 ) {
2915 let sig = FunctionSignature { ret, params };
2916 match state.lookup_sym_mut(name) {
2917 Some(Symbol {
2918 decl: SymDecl::NativeFunction(f, ..),
2919 ..
2920 }) => f.signatures.push(sig),
2921 None => {
2922 state.declare(
2923 name,
2924 SymDecl::NativeFunction(
2925 FunctionType {
2926 signatures: NonEmpty::new(sig),
2927 },
2928 cxx_name,
2929 run_class,
2930 ),
2931 );
2932 }
2933 _ => panic!("overloaded function name {}", name),
2934 }
2935 //state.declare(name, Type::Function(FunctionType{ v}))
2936 }
2937
declare_function( state: &mut State, name: &str, cxx_name: Option<&'static str>, ret: Type, params: Vec<Type>, )2938 fn declare_function(
2939 state: &mut State,
2940 name: &str,
2941 cxx_name: Option<&'static str>,
2942 ret: Type,
2943 params: Vec<Type>,
2944 ) {
2945 declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown)
2946 }
2947
ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit2948 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit {
2949 // global scope
2950 state.push_scope("global".into());
2951 use TypeKind::*;
2952 declare_function(
2953 state,
2954 "vec2",
2955 Some("make_vec2"),
2956 Type::new(Vec2),
2957 vec![Type::new(Float)],
2958 );
2959 declare_function(
2960 state,
2961 "vec2",
2962 Some("make_vec2"),
2963 Type::new(Vec2),
2964 vec![Type::new(Float), Type::new(Float)],
2965 );
2966 declare_function(
2967 state,
2968 "vec2",
2969 Some("make_vec2"),
2970 Type::new(Vec2),
2971 vec![Type::new(IVec2)],
2972 );
2973 declare_function(
2974 state,
2975 "vec2",
2976 Some("make_vec2"),
2977 Type::new(Vec2),
2978 vec![Type::new(IVec3)],
2979 );
2980 declare_function(
2981 state,
2982 "vec3",
2983 Some("make_vec3"),
2984 Type::new(Vec3),
2985 vec![Type::new(Float), Type::new(Float), Type::new(Float)],
2986 );
2987 declare_function(
2988 state,
2989 "vec3",
2990 Some("make_vec3"),
2991 Type::new(Vec3),
2992 vec![Type::new(Float)],
2993 );
2994 declare_function(
2995 state,
2996 "vec3",
2997 Some("make_vec3"),
2998 Type::new(Vec3),
2999 vec![Type::new(Vec2), Type::new(Float)],
3000 );
3001 declare_function(
3002 state,
3003 "vec4",
3004 Some("make_vec4"),
3005 Type::new(Vec4),
3006 vec![Type::new(Float)],
3007 );
3008 declare_function(
3009 state,
3010 "vec4",
3011 Some("make_vec4"),
3012 Type::new(Vec4),
3013 vec![Type::new(Vec3), Type::new(Float)],
3014 );
3015 declare_function(
3016 state,
3017 "vec4",
3018 Some("make_vec4"),
3019 Type::new(Vec4),
3020 vec![
3021 Type::new(Float),
3022 Type::new(Float),
3023 Type::new(Float),
3024 Type::new(Float),
3025 ],
3026 );
3027 declare_function(
3028 state,
3029 "vec4",
3030 Some("make_vec4"),
3031 Type::new(Vec4),
3032 vec![Type::new(Vec2), Type::new(Float), Type::new(Float)],
3033 );
3034 declare_function(
3035 state,
3036 "vec4",
3037 Some("make_vec4"),
3038 Type::new(Vec4),
3039 vec![Type::new(Vec2), Type::new(Vec2)],
3040 );
3041 declare_function(
3042 state,
3043 "vec4",
3044 Some("make_vec4"),
3045 Type::new(Vec4),
3046 vec![Type::new(Float), Type::new(Float), Type::new(Vec2)],
3047 );
3048 declare_function(
3049 state,
3050 "vec4",
3051 Some("make_vec4"),
3052 Type::new(Vec4),
3053 vec![Type::new(Vec4)],
3054 );
3055 declare_function(
3056 state,
3057 "vec4",
3058 Some("make_vec4"),
3059 Type::new(Vec4),
3060 vec![Type::new(IVec4)],
3061 );
3062
3063 declare_function(
3064 state,
3065 "bvec2",
3066 Some("make_bvec2"),
3067 Type::new(BVec2),
3068 vec![Type::new(Bool)],
3069 );
3070 declare_function(
3071 state,
3072 "bvec3",
3073 Some("make_bvec3"),
3074 Type::new(BVec3),
3075 vec![Type::new(Bool)],
3076 );
3077 declare_function(
3078 state,
3079 "bvec4",
3080 Some("make_bvec4"),
3081 Type::new(BVec4),
3082 vec![Type::new(Bool)],
3083 );
3084 declare_function(
3085 state,
3086 "bvec4",
3087 Some("make_bvec4"),
3088 Type::new(BVec4),
3089 vec![Type::new(BVec2), Type::new(BVec2)],
3090 );
3091 declare_function(
3092 state,
3093 "bvec4",
3094 Some("make_bvec4"),
3095 Type::new(BVec4),
3096 vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)],
3097 );
3098 declare_function(
3099 state,
3100 "int",
3101 Some("make_int"),
3102 Type::new(Int),
3103 vec![Type::new(Float)],
3104 );
3105 declare_function(
3106 state,
3107 "float",
3108 Some("make_float"),
3109 Type::new(Float),
3110 vec![Type::new(Float)],
3111 );
3112 declare_function(
3113 state,
3114 "float",
3115 Some("make_float"),
3116 Type::new(Float),
3117 vec![Type::new(Int)],
3118 );
3119 declare_function(
3120 state,
3121 "int",
3122 Some("make_int"),
3123 Type::new(Int),
3124 vec![Type::new(UInt)],
3125 );
3126 declare_function(
3127 state,
3128 "uint",
3129 Some("make_uint"),
3130 Type::new(UInt),
3131 vec![Type::new(Float)],
3132 );
3133 declare_function(
3134 state,
3135 "uint",
3136 Some("make_uint"),
3137 Type::new(UInt),
3138 vec![Type::new(Int)],
3139 );
3140 declare_function(
3141 state,
3142 "ivec2",
3143 Some("make_ivec2"),
3144 Type::new(IVec2),
3145 vec![Type::new(UInt), Type::new(UInt)],
3146 );
3147 declare_function(
3148 state,
3149 "ivec2",
3150 Some("make_ivec2"),
3151 Type::new(IVec2),
3152 vec![Type::new(Int), Type::new(Int)],
3153 );
3154 declare_function(
3155 state,
3156 "ivec2",
3157 Some("make_ivec2"),
3158 Type::new(IVec2),
3159 vec![Type::new(Vec2)],
3160 );
3161 declare_function(
3162 state,
3163 "ivec3",
3164 Some("make_ivec3"),
3165 Type::new(IVec3),
3166 vec![Type::new(IVec2), Type::new(Int)],
3167 );
3168 declare_function(
3169 state,
3170 "ivec4",
3171 Some("make_ivec4"),
3172 Type::new(IVec4),
3173 vec![
3174 Type::new(Int),
3175 Type::new(Int),
3176 Type::new(Int),
3177 Type::new(Int),
3178 ],
3179 );
3180 declare_function(
3181 state,
3182 "ivec4",
3183 Some("make_ivec4"),
3184 Type::new(IVec4),
3185 vec![Type::new(Vec4)],
3186 );
3187 declare_function(
3188 state,
3189 "ivec4",
3190 Some("make_ivec4"),
3191 Type::new(IVec4),
3192 vec![Type::new(IVec2), Type::new(Int), Type::new(Int)],
3193 );
3194
3195 declare_function(
3196 state,
3197 "mat2",
3198 Some("make_mat2"),
3199 Type::new(Mat2),
3200 vec![Type::new(Vec2), Type::new(Vec2)],
3201 );
3202 declare_function(
3203 state,
3204 "mat2",
3205 Some("make_mat2"),
3206 Type::new(Mat2),
3207 vec![Type::new(Float)],
3208 );
3209 declare_function(
3210 state,
3211 "mat2",
3212 Some("make_mat2"),
3213 Type::new(Mat2),
3214 vec![Type::new(Mat4)],
3215 );
3216 declare_function(
3217 state,
3218 "mat3",
3219 Some("make_mat3"),
3220 Type::new(Mat3),
3221 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3222 );
3223 declare_function(
3224 state,
3225 "mat3",
3226 Some("make_mat3"),
3227 Type::new(Mat3),
3228 vec![Type::new(Mat4)],
3229 );
3230 declare_function(
3231 state,
3232 "mat3",
3233 Some("make_mat3"),
3234 Type::new(Mat3),
3235 vec![
3236 Type::new(Float),
3237 Type::new(Float),
3238 Type::new(Float),
3239 Type::new(Float),
3240 Type::new(Float),
3241 Type::new(Float),
3242 Type::new(Float),
3243 Type::new(Float),
3244 Type::new(Float),
3245 ],
3246 );
3247 declare_function(
3248 state,
3249 "mat3x4",
3250 Some("make_mat3x4"),
3251 Type::new(Mat34),
3252 vec![
3253 Type::new(Float),
3254 Type::new(Float),
3255 Type::new(Float),
3256 Type::new(Float),
3257
3258 Type::new(Float),
3259 Type::new(Float),
3260 Type::new(Float),
3261 Type::new(Float),
3262
3263 Type::new(Float),
3264 Type::new(Float),
3265 Type::new(Float),
3266 Type::new(Float),
3267 ],
3268 );
3269 declare_function(
3270 state,
3271 "transpose",
3272 None,
3273 Type::new(Mat43),
3274 vec![Type::new(Mat34)],
3275 );
3276 declare_function(
3277 state,
3278 "mat4",
3279 Some("make_mat4"),
3280 Type::new(Mat4),
3281 vec![
3282 Type::new(Vec4),
3283 Type::new(Vec4),
3284 Type::new(Vec4),
3285 Type::new(Vec4),
3286 ],
3287 );
3288 declare_function(
3289 state,
3290 "mat4",
3291 Some("make_mat4"),
3292 Type::new(Mat4),
3293 vec![
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 Type::new(Float),
3305 Type::new(Float),
3306 Type::new(Float),
3307 Type::new(Float),
3308 Type::new(Float),
3309 Type::new(Float),
3310 ],
3311 );
3312 declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3313 declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3314 declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]);
3315 declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3316 declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3317 declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]);
3318 declare_function(
3319 state,
3320 "dot",
3321 None,
3322 Type::new(Float),
3323 vec![Type::new(Vec3), Type::new(Vec3)],
3324 );
3325 declare_function(
3326 state,
3327 "dot",
3328 None,
3329 Type::new(Float),
3330 vec![Type::new(Vec2), Type::new(Vec2)],
3331 );
3332 for t in &[Vec2, Vec3, Vec4] {
3333 declare_function(
3334 state,
3335 "min",
3336 None,
3337 Type::new(*t),
3338 vec![Type::new(*t), Type::new(Float)],
3339 );
3340 declare_function(
3341 state,
3342 "max",
3343 None,
3344 Type::new(*t),
3345 vec![Type::new(*t), Type::new(Float)],
3346 );
3347 }
3348 for t in &[Int, Float, Vec2, Vec3, Vec4] {
3349 declare_function(
3350 state,
3351 "min",
3352 None,
3353 Type::new(*t),
3354 vec![Type::new(*t), Type::new(*t)],
3355 );
3356 declare_function(
3357 state,
3358 "max",
3359 None,
3360 Type::new(*t),
3361 vec![Type::new(*t), Type::new(*t)],
3362 );
3363 }
3364
3365 declare_function(
3366 state,
3367 "mix",
3368 None,
3369 Type::new(Vec2),
3370 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3371 );
3372 declare_function(
3373 state,
3374 "mix",
3375 None,
3376 Type::new(Vec2),
3377 vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)],
3378 );
3379 declare_function(
3380 state,
3381 "mix",
3382 None,
3383 Type::new(Vec2),
3384 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)],
3385 );
3386 declare_function(
3387 state,
3388 "mix",
3389 None,
3390 Type::new(Vec3),
3391 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)],
3392 );
3393 declare_function(
3394 state,
3395 "mix",
3396 None,
3397 Type::new(Vec4),
3398 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
3399 );
3400 declare_function(
3401 state,
3402 "mix",
3403 None,
3404 Type::new(Vec4),
3405 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)],
3406 );
3407 declare_function(
3408 state,
3409 "mix",
3410 None,
3411 Type::new(Vec3),
3412 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)],
3413 );
3414 declare_function(
3415 state,
3416 "mix",
3417 None,
3418 Type::new(Vec3),
3419 vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)],
3420 );
3421 declare_function(
3422 state,
3423 "mix",
3424 None,
3425 Type::new(Float),
3426 vec![Type::new(Float), Type::new(Float), Type::new(Float)],
3427 );
3428 declare_function(
3429 state,
3430 "mix",
3431 None,
3432 Type::new(Vec4),
3433 vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)],
3434 );
3435 declare_function(
3436 state,
3437 "step",
3438 None,
3439 Type::new(Float),
3440 vec![Type::new(Float), Type::new(Float)],
3441 );
3442 declare_function(
3443 state,
3444 "step",
3445 None,
3446 Type::new(Vec2),
3447 vec![Type::new(Vec2), Type::new(Vec2)],
3448 );
3449 declare_function(
3450 state,
3451 "step",
3452 None,
3453 Type::new(Vec2),
3454 vec![Type::new(Float), Type::new(Vec2)],
3455 );
3456 declare_function(
3457 state,
3458 "step",
3459 None,
3460 Type::new(Vec3),
3461 vec![Type::new(Vec3), Type::new(Vec3)],
3462 );
3463 declare_function(
3464 state,
3465 "step",
3466 None,
3467 Type::new(Vec4),
3468 vec![Type::new(Float), Type::new(Vec4)],
3469 );
3470 declare_function(
3471 state,
3472 "notEqual",
3473 None,
3474 Type::new(BVec4),
3475 vec![Type::new(IVec4), Type::new(IVec4)],
3476 );
3477
3478 declare_function_ext(
3479 state,
3480 "fwidth",
3481 None,
3482 Type::new(Vec2),
3483 vec![Type::new(Vec2)],
3484 RunClass::Scalar,
3485 );
3486 declare_function_ext(
3487 state,
3488 "dFdx",
3489 None,
3490 Type::new(Float),
3491 vec![Type::new(Float)],
3492 RunClass::Scalar,
3493 );
3494 declare_function_ext(
3495 state,
3496 "dFdx",
3497 None,
3498 Type::new(Vec2),
3499 vec![Type::new(Vec2)],
3500 RunClass::Scalar,
3501 );
3502
3503 declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]);
3504 declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]);
3505 declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]);
3506 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]);
3507 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]);
3508 for t in &[Vec2, Vec3, Vec4] {
3509 declare_function(
3510 state,
3511 "clamp",
3512 None,
3513 Type::new(*t),
3514 vec![Type::new(*t), Type::new(Float), Type::new(Float)],
3515 );
3516 }
3517 for t in &[Float, Vec2, Vec3, Vec4] {
3518 declare_function(
3519 state,
3520 "clamp",
3521 None,
3522 Type::new(*t),
3523 vec![Type::new(*t), Type::new(*t), Type::new(*t)],
3524 );
3525 }
3526 declare_function(
3527 state,
3528 "length",
3529 None,
3530 Type::new(Float),
3531 vec![Type::new(Vec2)],
3532 );
3533 declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]);
3534 declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]);
3535 declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]);
3536 declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]);
3537 declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]);
3538 declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]);
3539 for t in &[Float, Vec2] {
3540 // recip is non-standard
3541 declare_function(
3542 state,
3543 "recip",
3544 None,
3545 Type::new(*t),
3546 vec![Type::new(*t)],
3547 );
3548 declare_function(
3549 state,
3550 "inversesqrt",
3551 None,
3552 Type::new(*t),
3553 vec![Type::new(*t)],
3554 );
3555 declare_function(
3556 state,
3557 "sqrt",
3558 None,
3559 Type::new(*t),
3560 vec![Type::new(*t)],
3561 );
3562 }
3563 declare_function(
3564 state,
3565 "distance",
3566 None,
3567 Type::new(Float),
3568 vec![Type::new(Vec2), Type::new(Vec2)],
3569 );
3570
3571 declare_function(
3572 state,
3573 "equal",
3574 None,
3575 Type::new(BVec2),
3576 vec![Type::new(Vec2), Type::new(Vec2)],
3577 );
3578 declare_function(
3579 state,
3580 "equal",
3581 None,
3582 Type::new(BVec4),
3583 vec![Type::new(Vec4), Type::new(Vec4)],
3584 );
3585 declare_function(
3586 state,
3587 "notEqual",
3588 None,
3589 Type::new(BVec2),
3590 vec![Type::new(Vec2), Type::new(Vec2)],
3591 );
3592 declare_function(
3593 state,
3594 "notEqual",
3595 None,
3596 Type::new(BVec4),
3597 vec![Type::new(Vec4), Type::new(Vec4)],
3598 );
3599 declare_function(
3600 state,
3601 "lessThanEqual",
3602 None,
3603 Type::new(BVec2),
3604 vec![Type::new(Vec2), Type::new(Vec2)],
3605 );
3606 declare_function(
3607 state,
3608 "lessThanEqual",
3609 None,
3610 Type::new(BVec3),
3611 vec![Type::new(Vec3), Type::new(Vec3)],
3612 );
3613 declare_function(
3614 state,
3615 "lessThanEqual",
3616 None,
3617 Type::new(BVec4),
3618 vec![Type::new(Vec4), Type::new(Vec4)],
3619 );
3620 declare_function(
3621 state,
3622 "lessThan",
3623 None,
3624 Type::new(BVec2),
3625 vec![Type::new(Vec2), Type::new(Vec2)],
3626 );
3627 declare_function(
3628 state,
3629 "lessThan",
3630 None,
3631 Type::new(BVec4),
3632 vec![Type::new(Vec4), Type::new(Vec4)],
3633 );
3634 declare_function(
3635 state,
3636 "greaterThan",
3637 None,
3638 Type::new(BVec2),
3639 vec![Type::new(Vec2), Type::new(Vec2)],
3640 );
3641 declare_function(
3642 state,
3643 "greaterThan",
3644 None,
3645 Type::new(BVec4),
3646 vec![Type::new(Vec4), Type::new(Vec4)],
3647 );
3648 declare_function(
3649 state,
3650 "greaterThanEqual",
3651 None,
3652 Type::new(BVec2),
3653 vec![Type::new(Vec2), Type::new(Vec2)],
3654 );
3655 declare_function(
3656 state,
3657 "greaterThanEqual",
3658 None,
3659 Type::new(BVec4),
3660 vec![Type::new(Vec4), Type::new(Vec4)],
3661 );
3662 declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]);
3663 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]);
3664 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]);
3665
3666 declare_function(
3667 state,
3668 "if_then_else",
3669 None,
3670 Type::new(Vec3),
3671 vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)],
3672 );
3673 declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]);
3674 declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3675 declare_function(
3676 state,
3677 "floor",
3678 None,
3679 Type::new(Float),
3680 vec![Type::new(Float)],
3681 );
3682 declare_function(
3683 state,
3684 "ceil",
3685 None,
3686 Type::new(Float),
3687 vec![Type::new(Float)],
3688 );
3689 declare_function(
3690 state,
3691 "round",
3692 None,
3693 Type::new(Float),
3694 vec![Type::new(Float)],
3695 );
3696 declare_function(
3697 state,
3698 "fract",
3699 None,
3700 Type::new(Float),
3701 vec![Type::new(Float)],
3702 );
3703 declare_function(
3704 state,
3705 "fract",
3706 None,
3707 Type::new(Vec2),
3708 vec![Type::new(Vec2)],
3709 );
3710 declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]);
3711 declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]);
3712
3713 declare_function(
3714 state,
3715 "texelFetch",
3716 None,
3717 Type::new(Vec4),
3718 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3719 );
3720 declare_function(
3721 state,
3722 "texelFetch",
3723 None,
3724 Type::new(IVec4),
3725 vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)],
3726 );
3727 declare_function(
3728 state,
3729 "texelFetchOffset",
3730 None,
3731 Type::new(Vec4),
3732 vec![
3733 Type::new(Sampler2D),
3734 Type::new(IVec2),
3735 Type::new(Int),
3736 Type::new(IVec2),
3737 ],
3738 );
3739 declare_function(
3740 state,
3741 "texelFetchOffset",
3742 None,
3743 Type::new(IVec4),
3744 vec![
3745 Type::new(ISampler2D),
3746 Type::new(IVec2),
3747 Type::new(Int),
3748 Type::new(IVec2),
3749 ],
3750 );
3751 declare_function(
3752 state,
3753 "texture",
3754 None,
3755 Type::new(Vec4),
3756 vec![Type::new(Sampler2D), Type::new(Vec2)],
3757 );
3758 declare_function(
3759 state,
3760 "texture",
3761 None,
3762 Type::new(Vec4),
3763 vec![Type::new(Sampler2DRect), Type::new(Vec2)],
3764 );
3765 declare_function(
3766 state,
3767 "textureSize",
3768 None,
3769 Type::new(IVec2),
3770 vec![Type::new(Sampler2D), Type::new(Int)],
3771 );
3772 declare_function(
3773 state,
3774 "textureSize",
3775 None,
3776 Type::new(IVec2),
3777 vec![Type::new(Sampler2DRect), Type::new(Int)],
3778 );
3779
3780 declare_function(
3781 state,
3782 "inverse",
3783 None,
3784 Type::new(Mat2),
3785 vec![Type::new(Mat2)],
3786 );
3787 declare_function(
3788 state,
3789 "transpose",
3790 None,
3791 Type::new(Mat3),
3792 vec![Type::new(Mat3)],
3793 );
3794 declare_function(
3795 state,
3796 "normalize",
3797 None,
3798 Type::new(Vec2),
3799 vec![Type::new(Vec2)],
3800 );
3801 state.declare(
3802 "gl_FragCoord",
3803 SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector),
3804 );
3805 state.declare(
3806 "gl_FragColor",
3807 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3808 );
3809 state.declare(
3810 "gl_Position",
3811 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector),
3812 );
3813 state.clip_dist_sym = state.declare(
3814 "gl_ClipDistance",
3815 SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector),
3816 );
3817
3818 state.declare(
3819 "swgl_SpanLength",
3820 SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar),
3821 );
3822 state.declare(
3823 "swgl_StepSize",
3824 SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar),
3825 );
3826
3827 for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] {
3828 declare_function_ext(
3829 state,
3830 "swgl_forceScalar",
3831 None,
3832 Type::new(*t),
3833 vec![Type::new(*t)],
3834 RunClass::Scalar,
3835 );
3836 }
3837
3838 // GL_ARB_shader_group_vote
3839 for (name, cxx_name) in &[("anyInvocations", "test_any"),
3840 ("allInvocations", "test_all"),
3841 ("allInvocationsEqual", "test_equal")] {
3842 declare_function_ext(
3843 state,
3844 name,
3845 Some(cxx_name),
3846 Type::new(Bool),
3847 vec![Type::new(Bool)],
3848 RunClass::Scalar,
3849 );
3850 }
3851
3852 declare_function(
3853 state,
3854 "swgl_stepInterp",
3855 None,
3856 Type::new(Void),
3857 vec![],
3858 );
3859
3860 for t in &[Float, Vec2, Vec3, Vec4] {
3861 declare_function_ext(
3862 state,
3863 "swgl_interpStep",
3864 None,
3865 Type::new(*t),
3866 vec![Type::new(*t)],
3867 RunClass::Scalar,
3868 );
3869 }
3870
3871 declare_function(
3872 state,
3873 "swgl_commitPartialSolidRGBA8",
3874 None,
3875 Type::new(Void),
3876 vec![Type::new(Int), Type::new(Vec4)],
3877 );
3878 declare_function(
3879 state,
3880 "swgl_commitPartialSolidR8",
3881 None,
3882 Type::new(Void),
3883 vec![Type::new(Int), Type::new(Float)],
3884 );
3885 declare_function(
3886 state,
3887 "swgl_commitSolidRGBA8",
3888 None,
3889 Type::new(Void),
3890 vec![Type::new(Vec4)],
3891 );
3892 declare_function(
3893 state,
3894 "swgl_commitSolidR8",
3895 None,
3896 Type::new(Void),
3897 vec![Type::new(Float)],
3898 );
3899 declare_function(
3900 state,
3901 "swgl_commitColorRGBA8",
3902 None,
3903 Type::new(Void),
3904 vec![Type::new(Vec4)],
3905 );
3906 declare_function(
3907 state,
3908 "swgl_commitColorR8",
3909 None,
3910 Type::new(Void),
3911 vec![Type::new(Float)],
3912 );
3913 declare_function(
3914 state,
3915 "swgl_blendDropShadow",
3916 None,
3917 Type::new(Void),
3918 vec![Type::new(Vec4)],
3919 );
3920 declare_function(
3921 state,
3922 "swgl_blendSubpixelText",
3923 None,
3924 Type::new(Void),
3925 vec![Type::new(Vec4)],
3926 );
3927 declare_function(
3928 state,
3929 "swgl_clipMask",
3930 None,
3931 Type::new(Void),
3932 vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)],
3933 );
3934 declare_function(
3935 state,
3936 "swgl_antiAlias",
3937 None,
3938 Type::new(Void),
3939 vec![Type::new(Int)],
3940 );
3941 declare_function(
3942 state,
3943 "swgl_antiAlias",
3944 None,
3945 Type::new(Void),
3946 vec![Type::new(BVec4)],
3947 );
3948 declare_function_ext(
3949 state,
3950 "swgl_validateGradient",
3951 None,
3952 Type::new(Int),
3953 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)],
3954 RunClass::Scalar,
3955 );
3956 declare_function(
3957 state,
3958 "swgl_commitLinearGradientRGBA8",
3959 None,
3960 Type::new(Void),
3961 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Float)],
3962 );
3963 declare_function(
3964 state,
3965 "swgl_commitRadialGradientRGBA8",
3966 None,
3967 Type::new(Void),
3968 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2),
3969 Type::new(Float)],
3970 );
3971 declare_function(
3972 state,
3973 "swgl_commitGradientRGBA8",
3974 None,
3975 Type::new(Void),
3976 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)],
3977 );
3978 declare_function(
3979 state,
3980 "swgl_commitGradientColorRGBA8",
3981 None,
3982 Type::new(Void),
3983 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)],
3984 );
3985 for s in &[Sampler2D, Sampler2DRect] {
3986 declare_function_ext(
3987 state,
3988 "swgl_isTextureLinear",
3989 None,
3990 Type::new(Bool),
3991 vec![Type::new(*s)],
3992 RunClass::Scalar,
3993 );
3994 declare_function_ext(
3995 state,
3996 "swgl_isTextureRGBA8",
3997 None,
3998 Type::new(Bool),
3999 vec![Type::new(*s)],
4000 RunClass::Scalar,
4001 );
4002 declare_function_ext(
4003 state,
4004 "swgl_isTextureR8",
4005 None,
4006 Type::new(Bool),
4007 vec![Type::new(*s)],
4008 RunClass::Scalar,
4009 );
4010 declare_function(
4011 state,
4012 "swgl_commitTextureLinearRGBA8",
4013 None,
4014 Type::new(Void),
4015 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4016 );
4017 declare_function(
4018 state,
4019 "swgl_commitTextureLinearR8",
4020 None,
4021 Type::new(Void),
4022 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4023 );
4024 declare_function(
4025 state,
4026 "swgl_commitTextureLinearR8ToRGBA8",
4027 None,
4028 Type::new(Void),
4029 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4030 );
4031 declare_function(
4032 state,
4033 "swgl_commitPartialTextureLinearR8",
4034 None,
4035 Type::new(Void),
4036 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4037 );
4038 declare_function(
4039 state,
4040 "swgl_commitPartialTextureLinearInvertR8",
4041 None,
4042 Type::new(Void),
4043 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4044 );
4045 declare_function(
4046 state,
4047 "swgl_commitTextureLinearColorRGBA8",
4048 None,
4049 Type::new(Void),
4050 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4051 );
4052 declare_function(
4053 state,
4054 "swgl_commitTextureLinearColorRGBA8",
4055 None,
4056 Type::new(Void),
4057 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4058 );
4059 declare_function(
4060 state,
4061 "swgl_commitTextureLinearColorR8",
4062 None,
4063 Type::new(Void),
4064 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)],
4065 );
4066 declare_function(
4067 state,
4068 "swgl_commitTextureLinearColorR8ToRGBA8",
4069 None,
4070 Type::new(Void),
4071 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4072 );
4073
4074 declare_function(
4075 state,
4076 "swgl_commitTextureLinearRepeatRGBA8",
4077 None,
4078 Type::new(Void),
4079 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4080 Type::new(Vec4), Type::new(Vec4)],
4081 );
4082 declare_function(
4083 state,
4084 "swgl_commitTextureLinearRepeatColorRGBA8",
4085 None,
4086 Type::new(Void),
4087 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4088 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4089 );
4090
4091 declare_function(
4092 state,
4093 "swgl_commitTextureNearestRGBA8",
4094 None,
4095 Type::new(Void),
4096 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4097 );
4098 declare_function(
4099 state,
4100 "swgl_commitTextureNearestColorRGBA8",
4101 None,
4102 Type::new(Void),
4103 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4104 );
4105 declare_function(
4106 state,
4107 "swgl_commitTextureNearestRepeatRGBA8",
4108 None,
4109 Type::new(Void),
4110 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4111 Type::new(Vec4), Type::new(Vec4)],
4112 );
4113 declare_function(
4114 state,
4115 "swgl_commitTextureNearestRepeatColorRGBA8",
4116 None,
4117 Type::new(Void),
4118 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4119 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4120 );
4121
4122 declare_function(
4123 state,
4124 "swgl_commitTextureRGBA8",
4125 None,
4126 Type::new(Void),
4127 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)],
4128 );
4129 declare_function(
4130 state,
4131 "swgl_commitTextureColorRGBA8",
4132 None,
4133 Type::new(Void),
4134 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)],
4135 );
4136 declare_function(
4137 state,
4138 "swgl_commitTextureRepeatRGBA8",
4139 None,
4140 Type::new(Void),
4141 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4142 Type::new(Vec4), Type::new(Vec4)],
4143 );
4144 declare_function(
4145 state,
4146 "swgl_commitTextureRepeatColorRGBA8",
4147 None,
4148 Type::new(Void),
4149 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2),
4150 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)],
4151 );
4152
4153 declare_function(
4154 state,
4155 "swgl_commitGaussianBlurRGBA8",
4156 None,
4157 Type::new(Void),
4158 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4159 Type::new(Int), Type::new(Vec2)],
4160 );
4161 declare_function(
4162 state,
4163 "swgl_commitGaussianBlurR8",
4164 None,
4165 Type::new(Void),
4166 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool),
4167 Type::new(Int), Type::new(Vec2)],
4168 );
4169 declare_function(
4170 state,
4171 "swgl_commitTextureLinearYUV",
4172 None,
4173 Type::new(Void),
4174 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4175 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4176 );
4177 declare_function(
4178 state,
4179 "swgl_commitTextureLinearYUV",
4180 None,
4181 Type::new(Void),
4182 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4183 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4184 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4185 );
4186 declare_function(
4187 state,
4188 "swgl_commitTextureLinearYUV",
4189 None,
4190 Type::new(Void),
4191 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4192 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4193 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4194 Type::new(Vec3), Type::new(Mat3), Type::new(Int)],
4195 );
4196 declare_function(
4197 state,
4198 "swgl_commitTextureLinearColorYUV",
4199 None,
4200 Type::new(Void),
4201 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4202 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4203 Type::new(Float)],
4204 );
4205 declare_function(
4206 state,
4207 "swgl_commitTextureLinearColorYUV",
4208 None,
4209 Type::new(Void),
4210 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4211 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4212 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4213 Type::new(Float)],
4214 );
4215 declare_function(
4216 state,
4217 "swgl_commitTextureLinearColorYUV",
4218 None,
4219 Type::new(Void),
4220 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4221 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4222 Type::new(*s), Type::new(Vec2), Type::new(Vec4),
4223 Type::new(Vec3), Type::new(Mat3), Type::new(Int),
4224 Type::new(Float)],
4225 );
4226 }
4227
4228 TranslationUnit(tu.0.map(state, translate_external_declaration))
4229 }
4230
infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass4231 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass {
4232 match expr.kind {
4233 ExprKind::Variable(ref i) => {
4234 *assign = *i;
4235 match &state.sym(*i).decl {
4236 SymDecl::Local(_, _, ref run_class) => *run_class,
4237 SymDecl::Global(_, _, _, ref run_class) => *run_class,
4238 _ => panic!(),
4239 }
4240 }
4241 ExprKind::IntConst(_)
4242 | ExprKind::UIntConst(_)
4243 | ExprKind::BoolConst(_)
4244 | ExprKind::FloatConst(_)
4245 | ExprKind::DoubleConst(_) => RunClass::Scalar,
4246 ExprKind::Unary(_, ref e) => infer_expr(state, e),
4247 ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)),
4248 ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c)
4249 .merge(infer_expr(state, s))
4250 .merge(infer_expr(state, e)),
4251 ExprKind::Assignment(ref v, _, ref e) => {
4252 let mut sym = SymRef(!0);
4253 let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e));
4254 assert!(sym != SymRef(!0));
4255 state.merge_run_class(sym, run_class)
4256 }
4257 ExprKind::Bracket(ref e, ref indx) => {
4258 infer_expr_inner(state, e, assign).merge(infer_expr(state, indx))
4259 }
4260 ExprKind::FunCall(ref fun, ref args) => {
4261 let arg_classes: Vec<(RunClass, SymRef)> = args
4262 .iter()
4263 .map(|e| {
4264 let mut assign = SymRef(!0);
4265 let run_class = infer_expr_inner(state, e, &mut assign);
4266 (run_class, assign)
4267 })
4268 .collect();
4269 let run_class = if args.is_empty() {
4270 RunClass::Scalar
4271 } else {
4272 arg_classes
4273 .iter()
4274 .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y))
4275 };
4276 match fun {
4277 FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl {
4278 SymDecl::NativeFunction(_, _, ref ret_class) => {
4279 if *ret_class != RunClass::Unknown {
4280 *ret_class
4281 } else {
4282 run_class
4283 }
4284 }
4285 SymDecl::UserFunction(ref fd, ref run_class) => {
4286 for (&(mut arg_class, assign), param) in
4287 arg_classes.iter().zip(fd.prototype.parameters.iter())
4288 {
4289 if let FunctionParameterDeclaration::Named(Some(qual), p) = param {
4290 match qual {
4291 ParameterQualifier::InOut | ParameterQualifier::Out => {
4292 if let SymDecl::Local(_, _, param_class) =
4293 &state.sym(p.sym).decl
4294 {
4295 match param_class {
4296 RunClass::Unknown | RunClass::Vector => {
4297 arg_class = RunClass::Vector;
4298 }
4299 RunClass::Dependent(mask) => {
4300 for i in 0 .. 31 {
4301 if (mask & (1 << i)) != 0 {
4302 arg_class =
4303 arg_class.merge(arg_classes[i].0);
4304 }
4305 }
4306 }
4307 RunClass::Scalar => {}
4308 }
4309 }
4310 assert!(assign != SymRef(!0));
4311 state.merge_run_class(assign, arg_class);
4312 }
4313 _ => {}
4314 }
4315 }
4316 }
4317 if fd.prototype.ty.kind == TypeKind::Void {
4318 RunClass::Scalar
4319 } else {
4320 match *run_class {
4321 RunClass::Unknown | RunClass::Vector => RunClass::Vector,
4322 RunClass::Dependent(mask) => {
4323 let mut ret_class = RunClass::Unknown;
4324 for i in 0 .. 31 {
4325 if (mask & (1 << i)) != 0 {
4326 ret_class = ret_class.merge(arg_classes[i].0);
4327 }
4328 }
4329 ret_class
4330 }
4331 RunClass::Scalar => RunClass::Scalar,
4332 }
4333 }
4334 }
4335 SymDecl::Struct(..) => run_class,
4336 _ => panic!(),
4337 },
4338 FunIdentifier::Constructor(..) => run_class,
4339 }
4340 }
4341 ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign),
4342 ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign),
4343 ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign),
4344 ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign),
4345 ExprKind::Comma(ref a, ref b) => {
4346 infer_expr(state, a);
4347 infer_expr(state, b)
4348 }
4349 ExprKind::Cond(_, ref e) => infer_expr(state, e),
4350 ExprKind::CondMask => RunClass::Vector,
4351 }
4352 }
4353
infer_expr(state: &mut State, expr: &Expr) -> RunClass4354 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass {
4355 infer_expr_inner(state, expr, &mut SymRef(!0))
4356 }
4357
infer_condition(state: &mut State, c: &Condition)4358 fn infer_condition(state: &mut State, c: &Condition) {
4359 match *c {
4360 Condition::Expr(ref e) => {
4361 infer_expr(state, e);
4362 }
4363 }
4364 }
4365
infer_iteration_statement(state: &mut State, ist: &IterationStatement)4366 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) {
4367 let changed = state.run_class_changed.replace(true);
4368 match *ist {
4369 IterationStatement::While(ref cond, ref body) => {
4370 while state.run_class_changed.replace(false) {
4371 infer_condition(state, cond);
4372 infer_statement(state, body);
4373 }
4374 }
4375 IterationStatement::DoWhile(ref body, ref cond) => {
4376 while state.run_class_changed.replace(false) {
4377 infer_statement(state, body);
4378 infer_expr(state, cond);
4379 }
4380 }
4381 IterationStatement::For(ref init, ref rest, ref body) => {
4382 match *init {
4383 ForInitStatement::Expression(ref expr) => {
4384 if let Some(ref e) = *expr {
4385 infer_expr(state, e);
4386 }
4387 }
4388 ForInitStatement::Declaration(ref d) => {
4389 infer_declaration(state, d);
4390 }
4391 }
4392 while state.run_class_changed.replace(false) {
4393 if let Some(ref cond) = rest.condition {
4394 infer_condition(state, cond);
4395 }
4396 if let Some(ref e) = rest.post_expr {
4397 infer_expr(state, e);
4398 }
4399 infer_statement(state, body);
4400 }
4401 }
4402 }
4403 state.run_class_changed.set(changed);
4404 }
4405
infer_selection_statement(state: &mut State, sst: &SelectionStatement)4406 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) {
4407 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond));
4408 mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4409 let branch_declaration = state.branch_declaration;
4410 state.branch_declaration = state.last_declaration;
4411 infer_statement(state, &sst.body);
4412 if let Some(ref else_st) = sst.else_stmt {
4413 infer_statement(state, else_st);
4414 }
4415 state.branch_run_class = branch_run_class;
4416 state.branch_declaration = branch_declaration;
4417 }
4418
infer_expression_statement(state: &mut State, est: &ExprStatement)4419 fn infer_expression_statement(state: &mut State, est: &ExprStatement) {
4420 if let Some(ref e) = *est {
4421 infer_expr(state, e);
4422 }
4423 }
4424
infer_switch_statement(state: &mut State, sst: &SwitchStatement)4425 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) {
4426 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head));
4427 mem::swap(&mut state.branch_run_class, &mut branch_run_class);
4428 let branch_declaration = state.branch_declaration;
4429 state.branch_declaration = state.last_declaration;
4430 for case in &sst.cases {
4431 for st in &case.stmts {
4432 infer_statement(state, st);
4433 }
4434 }
4435 state.branch_run_class = branch_run_class;
4436 state.branch_declaration = branch_declaration;
4437 }
4438
infer_jump_statement(state: &mut State, j: &JumpStatement)4439 fn infer_jump_statement(state: &mut State, j: &JumpStatement) {
4440 match *j {
4441 JumpStatement::Continue => {}
4442 JumpStatement::Break => {}
4443 JumpStatement::Discard => {}
4444 JumpStatement::Return(ref e) => {
4445 if let Some(e) = e {
4446 let run_class = infer_expr(state, e);
4447 state.return_run_class(run_class);
4448 }
4449 }
4450 }
4451 }
4452
infer_initializer(state: &mut State, i: &Initializer) -> RunClass4453 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass {
4454 match *i {
4455 Initializer::Simple(ref e) => infer_expr(state, e),
4456 Initializer::List(ref list) => {
4457 let mut run_class = RunClass::Unknown;
4458 for ini in list.0.iter() {
4459 run_class = run_class.merge(infer_initializer(state, ini));
4460 }
4461 run_class
4462 }
4463 }
4464 }
4465
infer_declaration(state: &mut State, d: &Declaration)4466 fn infer_declaration(state: &mut State, d: &Declaration) {
4467 match *d {
4468 Declaration::FunctionPrototype(..) => {}
4469 Declaration::InitDeclaratorList(ref list) => {
4470 state.last_declaration = list.head.name;
4471
4472 let mut run_class = RunClass::Unknown;
4473 for decl in &list.tail {
4474 if let Some(ref initializer) = decl.initializer {
4475 run_class = run_class.merge(infer_initializer(state, initializer));
4476 }
4477 }
4478 if let Some(ref initializer) = list.head.initializer {
4479 run_class = run_class.merge(infer_initializer(state, initializer));
4480 state.merge_run_class(list.head.name, run_class);
4481 }
4482 }
4483 Declaration::Precision(..) => {}
4484 Declaration::Block(..) => {}
4485 Declaration::Global(..) => {}
4486 Declaration::StructDefinition(..) => {}
4487 }
4488 }
4489
infer_simple_statement(state: &mut State, sst: &SimpleStatement)4490 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) {
4491 match *sst {
4492 SimpleStatement::Declaration(ref d) => infer_declaration(state, d),
4493 SimpleStatement::Expression(ref e) => infer_expression_statement(state, e),
4494 SimpleStatement::Selection(ref s) => infer_selection_statement(state, s),
4495 SimpleStatement::Switch(ref s) => infer_switch_statement(state, s),
4496 SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i),
4497 SimpleStatement::Jump(ref j) => infer_jump_statement(state, j),
4498 }
4499 }
4500
infer_compound_statement(state: &mut State, cst: &CompoundStatement)4501 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) {
4502 for st in &cst.statement_list {
4503 infer_statement(state, st);
4504 }
4505 }
4506
infer_statement(state: &mut State, st: &Statement)4507 fn infer_statement(state: &mut State, st: &Statement) {
4508 match *st {
4509 Statement::Compound(ref cst) => infer_compound_statement(state, cst),
4510 Statement::Simple(ref sst) => infer_simple_statement(state, sst),
4511 }
4512 }
4513
infer_function_definition(state: &mut State, fd: &FunctionDefinition)4514 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) {
4515 state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap());
4516
4517 state.run_class_changed.set(true);
4518 while state.run_class_changed.replace(false) {
4519 for st in &fd.body.statement_list {
4520 infer_statement(state, st);
4521 }
4522 }
4523
4524 state.in_function = None;
4525 }
4526
infer_external_declaration(state: &mut State, ed: &ExternalDeclaration)4527 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) {
4528 match *ed {
4529 ExternalDeclaration::Preprocessor(_) => {}
4530 ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd),
4531 ExternalDeclaration::Declaration(_) => {}
4532 }
4533 }
4534
infer_run_class(state: &mut State, tu: &TranslationUnit)4535 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) {
4536 for ed in &(tu.0).0 {
4537 infer_external_declaration(state, ed);
4538 }
4539 }
4540