hir.rs (149474B)
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, ArraySpecifierDimension, 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> { 49 fn lift(state: &mut State, s: S) -> Self; 50 } 51 52 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 { 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 { 113 fn lift(state: &mut State, a: &ArraySpecifier) -> Self { 114 ArraySizes { 115 sizes: a.dimensions.0.iter().map(|a| match a { 116 ArraySpecifierDimension::Unsized => panic!(), 117 ArraySpecifierDimension::ExplicitlySized(expr) => translate_expression(state, expr), 118 }).collect(), 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 { 245 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 325 pub fn is_bool(&self) -> bool { 326 use TypeKind::*; 327 match self { 328 Bool | BVec2 | BVec3 | BVec4 => true, 329 _ => false, 330 } 331 } 332 333 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 344 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 355 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 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 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 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 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 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 { 760 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 { 784 pub fn new(kind: TypeKind) -> Self { 785 Type { 786 kind, 787 precision: None, 788 array_sizes: None, 789 } 790 } 791 792 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 { 802 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 { 818 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 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 { 855 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 { 878 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 { 893 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 { 928 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 { 945 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 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 { 979 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 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 1005 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 1015 pub fn sym(&self, sym: SymRef) -> Ref<Symbol> { 1016 self.syms[sym.0 as usize].borrow() 1017 } 1018 1019 pub fn sym_mut(&mut self, sym: SymRef) -> &mut Symbol { 1020 self.syms[sym.0 as usize].get_mut() 1021 } 1022 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 1028 fn push_scope(&mut self, name: String) { 1029 self.scopes.push(Scope::new(name)); 1030 } 1031 fn pop_scope(&mut self) { 1032 self.scopes.pop(); 1033 } 1034 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 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 1053 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 { 1108 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 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 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 { 1246 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 { 1271 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 1341 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 1354 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>, Vec<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. 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 1458 fn deref(&self) -> &Self::Target { 1459 &self.0 1460 } 1461 } 1462 1463 impl DerefMut for TranslationUnit { 1464 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 1473 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 1482 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 1491 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 { 1520 pub fn new() -> Self { 1521 CompoundStatement { 1522 statement_list: Vec::new(), 1523 } 1524 } 1525 } 1526 1527 impl FromIterator<Statement> for CompoundStatement { 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. 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). 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. 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. 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 { 1623 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> { 1681 fn map<U, F: FnMut(&mut State, &T) -> U>(&self, s: &mut State, f: F) -> NonEmpty<U>; 1682 fn new(x: T) -> NonEmpty<T>; 1683 } 1684 1685 impl<T> NonEmptyExt<T> for NonEmpty<T> { 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 } 1689 fn new(x: T) -> NonEmpty<T> { 1690 NonEmpty::from_non_empty_iter(vec![x].into_iter()).unwrap() 1691 } 1692 } 1693 1694 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 1703 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 1718 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 1728 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 1892 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 1903 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 1948 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 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 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 2017 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 2024 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 2049 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 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 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 2141 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. 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. 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 2199 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 for dimension in idx { 2243 let idx = match dimension.kind { 2244 ExprKind::IntConst(idx) => idx, 2245 ExprKind::UIntConst(idx) => idx as i32, 2246 _ => panic!("bad index for gl_ClipDistance"), 2247 }; 2248 assert!(idx >= 0 && idx < 4); 2249 state.used_clip_dist |= 1 << idx; 2250 } 2251 } 2252 } 2253 } 2254 Expr { 2255 kind: ExprKind::Assignment(lhs, op.clone(), rhs), 2256 ty, 2257 } 2258 } 2259 syntax::Expr::Binary(op, lhs, rhs) => { 2260 let lhs = Box::new(translate_expression(state, lhs)); 2261 let rhs = Box::new(translate_expression(state, rhs)); 2262 let ty = match op { 2263 BinaryOp::Equal | BinaryOp::NonEqual | BinaryOp::GT | BinaryOp::GTE | BinaryOp::LT | BinaryOp::LTE => { 2264 // comparison operators have a bool result 2265 Type::new(TypeKind::Bool) 2266 } 2267 BinaryOp::Mult => { 2268 match (lhs.ty.kind, rhs.ty.kind) { 2269 (TypeKind::Mat2, TypeKind::Vec2) | 2270 (TypeKind::Mat3, TypeKind::Vec3) | 2271 (TypeKind::Mat3, TypeKind::Mat3) | 2272 (TypeKind::Mat3, TypeKind::Mat43) | 2273 (TypeKind::Mat4, TypeKind::Vec4) => rhs.ty.clone(), 2274 (TypeKind::Mat43, TypeKind::Vec4) => Type::new(TypeKind::Vec3), 2275 (TypeKind::Mat2, TypeKind::Float) | 2276 (TypeKind::Mat3, TypeKind::Float) | 2277 (TypeKind::Mat4, TypeKind::Float) => lhs.ty.clone(), 2278 _ => promoted_type(&lhs.ty, &rhs.ty), 2279 } 2280 } 2281 _ => promoted_type(&lhs.ty, &rhs.ty), 2282 }; 2283 2284 Expr { 2285 kind: ExprKind::Binary(op.clone(), lhs, rhs), 2286 ty, 2287 } 2288 } 2289 syntax::Expr::Unary(op, e) => { 2290 let e = Box::new(translate_expression(state, e)); 2291 let ty = e.ty.clone(); 2292 Expr { 2293 kind: ExprKind::Unary(op.clone(), e), 2294 ty, 2295 } 2296 } 2297 syntax::Expr::BoolConst(b) => Expr { 2298 kind: ExprKind::BoolConst(*b), 2299 ty: Type::new(TypeKind::Bool), 2300 }, 2301 syntax::Expr::Comma(lhs, rhs) => { 2302 let lhs = Box::new(translate_expression(state, lhs)); 2303 let rhs = Box::new(translate_expression(state, rhs)); 2304 assert_eq!(lhs.ty, rhs.ty); 2305 let ty = lhs.ty.clone(); 2306 Expr { 2307 kind: ExprKind::Comma(lhs, rhs), 2308 ty, 2309 } 2310 } 2311 syntax::Expr::DoubleConst(d) => Expr { 2312 kind: ExprKind::DoubleConst(*d), 2313 ty: Type::new(TypeKind::Double), 2314 }, 2315 syntax::Expr::FloatConst(f) => Expr { 2316 kind: ExprKind::FloatConst(*f), 2317 ty: Type::new(TypeKind::Float), 2318 }, 2319 syntax::Expr::FunCall(fun, params) => { 2320 let ret_ty: Type; 2321 let mut params: Vec<Expr> = params 2322 .iter() 2323 .map(|x| translate_expression(state, x)) 2324 .collect(); 2325 Expr { 2326 kind: ExprKind::FunCall( 2327 match fun { 2328 syntax::FunIdentifier::Identifier(i) => { 2329 let name = i.as_str(); 2330 if name == "texelFetchOffset" && params.len() >= 4 { 2331 if let Some((sampler, base, x, y)) = get_texel_fetch_offset( 2332 state, ¶ms[0], ¶ms[1], ¶ms[3], 2333 ) { 2334 if let Some(offsets) = 2335 state.texel_fetches.get_mut(&(sampler, base)) 2336 { 2337 offsets.add_offset(x, y); 2338 } else { 2339 state 2340 .texel_fetches 2341 .insert((sampler, base), TexelFetchOffsets::new(x, y)); 2342 } 2343 } 2344 } else if name == "swgl_stepInterp" { 2345 let mut globals = state.modified_globals.borrow_mut(); 2346 for (i, sym) in state.syms.iter().enumerate() { 2347 match &sym.borrow().decl { 2348 SymDecl::Global(StorageClass::In, _, _, RunClass::Vector) => { 2349 let symref = SymRef(i as u32); 2350 if !globals.contains(&symref) { 2351 globals.push(symref); 2352 } 2353 } 2354 _ => {} 2355 } 2356 } 2357 } 2358 let sym = match state.lookup(name) { 2359 Some(s) => s, 2360 None => panic!("missing symbol {}", name), 2361 }; 2362 // Force any boolean basic type constructors to generate correct 2363 // bit patterns. 2364 if let Some(t) = TypeKind::from_glsl_primitive_type_name(name) { 2365 if t.is_bool() { 2366 force_params_to_bool(state, &mut params); 2367 } else { 2368 force_params_from_bool(state, &mut params); 2369 } 2370 } 2371 match &state.sym(sym).decl { 2372 SymDecl::NativeFunction(fn_ty, _, _) => { 2373 // Search for a signature where all parameter types are 2374 // compatible. If there are many compatible signatures, 2375 // then choose the one with the most exact matches. 2376 // This is an approximation of the algorith described in 2377 // the "Function Definitions" section of the spec. 2378 let mut ret = None; 2379 let mut best_score = 0; 2380 'next_sig: for sig in &fn_ty.signatures { 2381 let mut score = 0; 2382 for (e, p) in params.iter().zip(sig.params.iter()) { 2383 if e.ty == *p { 2384 score += 1; 2385 } else if !can_implicitly_convert_to(&e.ty, p) { 2386 continue 'next_sig; 2387 } 2388 } 2389 if score >= best_score { 2390 ret = Some(sig.ret.clone()); 2391 best_score = score; 2392 // If all parameters match exactly, then there 2393 // is no need to search for other matches. 2394 if best_score >= params.len() { 2395 break; 2396 } 2397 } 2398 } 2399 ret_ty = match ret { 2400 Some(t) => t, 2401 None => { 2402 dbg!(&fn_ty.signatures); 2403 dbg!(params.iter().map(|p| p).collect::<Vec<_>>()); 2404 panic!("no matching func {}", i.as_str()) 2405 } 2406 }; 2407 } 2408 SymDecl::UserFunction(fd, _) => { 2409 let mut globals = state.modified_globals.borrow_mut(); 2410 for global in &fd.globals { 2411 if !globals.contains(global) { 2412 globals.push(*global); 2413 } 2414 } 2415 let mut matching = true; 2416 for (e, p) in params.iter().zip(fd.prototype.parameters.iter()) 2417 { 2418 matching &= match p { 2419 FunctionParameterDeclaration::Named(q, d) => { 2420 match q { 2421 Some(ParameterQualifier::InOut) 2422 | Some(ParameterQualifier::Out) => { 2423 if let Some(global) = is_output(e, state) { 2424 if !globals.contains(&global) { 2425 globals.push(global); 2426 } 2427 } 2428 } 2429 _ => {} 2430 } 2431 can_implicitly_convert_to(&e.ty, &d.ty) 2432 } 2433 FunctionParameterDeclaration::Unnamed(..) => panic!(), 2434 }; 2435 } 2436 assert!(matching); 2437 ret_ty = fd.prototype.ty.clone(); 2438 } 2439 SymDecl::Struct(_) => ret_ty = Type::new(TypeKind::Struct(sym)), 2440 _ => panic!("can only call functions"), 2441 }; 2442 FunIdentifier::Identifier(sym) 2443 } 2444 // array constructor 2445 syntax::FunIdentifier::Expr(e) => { 2446 let ty = match &**e { 2447 syntax::Expr::Bracket(i, array) => { 2448 let kind = match &**i { 2449 syntax::Expr::Variable(i) => match i.as_str() { 2450 "vec4" => TypeKind::Vec4, 2451 "vec2" => TypeKind::Vec2, 2452 "int" => TypeKind::Int, 2453 _ => panic!("unexpected type constructor {:?}", i), 2454 }, 2455 _ => panic!(), 2456 }; 2457 2458 Type { 2459 kind, 2460 precision: None, 2461 array_sizes: Some(Box::new(lift(state, array))), 2462 } 2463 } 2464 _ => panic!(), 2465 }; 2466 ret_ty = ty.clone(); 2467 2468 FunIdentifier::Constructor(ty) 2469 } 2470 }, 2471 params, 2472 ), 2473 ty: ret_ty, 2474 } 2475 } 2476 syntax::Expr::IntConst(i) => Expr { 2477 kind: ExprKind::IntConst(*i), 2478 ty: Type::new(TypeKind::Int), 2479 }, 2480 syntax::Expr::UIntConst(u) => Expr { 2481 kind: ExprKind::UIntConst(*u), 2482 ty: Type::new(TypeKind::UInt), 2483 }, 2484 syntax::Expr::PostDec(e) => { 2485 let e = Box::new(translate_expression(state, e)); 2486 let ty = e.ty.clone(); 2487 Expr { 2488 kind: ExprKind::PostDec(e), 2489 ty, 2490 } 2491 } 2492 syntax::Expr::PostInc(e) => { 2493 let e = Box::new(translate_expression(state, e)); 2494 let ty = e.ty.clone(); 2495 Expr { 2496 kind: ExprKind::PostInc(e), 2497 ty, 2498 } 2499 } 2500 syntax::Expr::Ternary(cond, lhs, rhs) => { 2501 let cond = Box::new(translate_expression(state, cond)); 2502 let lhs = Box::new(translate_expression(state, lhs)); 2503 let rhs = Box::new(translate_expression(state, rhs)); 2504 let ty = promoted_type(&lhs.ty, &rhs.ty); 2505 Expr { 2506 kind: ExprKind::Ternary(cond, lhs, rhs), 2507 ty, 2508 } 2509 } 2510 syntax::Expr::Dot(e, i) => { 2511 let e = Box::new(translate_expression(state, e)); 2512 let ty = e.ty.clone(); 2513 let ivec = is_ivec(&ty); 2514 if is_vector(&ty) { 2515 let ty = Type::new(match i.as_str().len() { 2516 1 => { 2517 if ivec { 2518 TypeKind::Int 2519 } else { 2520 TypeKind::Float 2521 } 2522 } 2523 2 => { 2524 if ivec { 2525 TypeKind::IVec2 2526 } else { 2527 TypeKind::Vec2 2528 } 2529 } 2530 3 => { 2531 if ivec { 2532 TypeKind::IVec3 2533 } else { 2534 TypeKind::Vec3 2535 } 2536 } 2537 4 => { 2538 if ivec { 2539 TypeKind::IVec4 2540 } else { 2541 TypeKind::Vec4 2542 } 2543 } 2544 _ => panic!(), 2545 }); 2546 2547 let sel = SwizzleSelector::parse(i.as_str()); 2548 2549 Expr { 2550 kind: ExprKind::SwizzleSelector(e, sel), 2551 ty, 2552 } 2553 } else { 2554 match ty.kind { 2555 TypeKind::Struct(s) => { 2556 let sym = state.sym(s); 2557 let fields = match &sym.decl { 2558 SymDecl::Struct(fields) => fields, 2559 _ => panic!("expected struct"), 2560 }; 2561 let field = fields 2562 .fields 2563 .iter() 2564 .find(|x| &x.name == i) 2565 .expect(&format!("missing field `{}` in `{}`", i, sym.name)); 2566 Expr { 2567 kind: ExprKind::Dot(e, i.clone()), 2568 ty: field.ty.clone(), 2569 } 2570 } 2571 _ => panic!("expected struct found {:#?} {:#?}", e, ty), 2572 } 2573 } 2574 } 2575 syntax::Expr::Bracket(e, specifier) => { 2576 let e = Box::new(translate_expression(state, e)); 2577 let ty = if let Some(ty) = index_vector(&e.ty) { 2578 Type::new(ty) 2579 } else if let Some(ty) = index_matrix(&e.ty) { 2580 Type::new(ty) 2581 } else { 2582 let a = match &e.ty.array_sizes { 2583 Some(a) => { 2584 let mut a = *a.clone(); 2585 a.sizes.pop(); 2586 if a.sizes.len() == 0 { 2587 None 2588 } else { 2589 Some(Box::new(a)) 2590 } 2591 } 2592 _ => panic!("{:#?}", e), 2593 }; 2594 Type { 2595 kind: e.ty.kind.clone(), 2596 precision: e.ty.precision.clone(), 2597 array_sizes: a, 2598 } 2599 }; 2600 let indx = specifier.dimensions.0.iter().map(|a| match a { 2601 ArraySpecifierDimension::Unsized => panic!("need expression"), 2602 ArraySpecifierDimension::ExplicitlySized(e) => translate_expression(state, e), 2603 }).collect(); 2604 Expr { 2605 kind: ExprKind::Bracket(e, indx), 2606 ty, 2607 } 2608 } 2609 } 2610 } 2611 2612 fn translate_switch(state: &mut State, s: &syntax::SwitchStatement) -> SwitchStatement { 2613 let mut cases = Vec::new(); 2614 2615 let mut case = None; 2616 for stmt in &s.body { 2617 match stmt { 2618 syntax::Statement::Simple(s) => match &**s { 2619 syntax::SimpleStatement::CaseLabel(label) => { 2620 match case.take() { 2621 Some(case) => cases.push(case), 2622 _ => {} 2623 } 2624 case = Some(Case { 2625 label: translate_case(state, &label), 2626 stmts: Vec::new(), 2627 }) 2628 } 2629 _ => match case { 2630 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)), 2631 _ => panic!("switch must start with case"), 2632 }, 2633 }, 2634 _ => match case { 2635 Some(ref mut case) => case.stmts.push(translate_statement(state, stmt)), 2636 _ => panic!("switch must start with case"), 2637 }, 2638 } 2639 } 2640 match case.take() { 2641 Some(case) => cases.push(case), 2642 _ => {} 2643 } 2644 SwitchStatement { 2645 head: Box::new(translate_expression(state, &s.head)), 2646 cases, 2647 } 2648 } 2649 2650 fn translate_jump(state: &mut State, s: &syntax::JumpStatement) -> JumpStatement { 2651 match s { 2652 syntax::JumpStatement::Break => JumpStatement::Break, 2653 syntax::JumpStatement::Continue => JumpStatement::Continue, 2654 syntax::JumpStatement::Discard => JumpStatement::Discard, 2655 syntax::JumpStatement::Return(e) => { 2656 JumpStatement::Return(e.as_ref().map(|e| Box::new(translate_expression(state, e)))) 2657 } 2658 } 2659 } 2660 2661 fn translate_condition(state: &mut State, c: &syntax::Condition) -> Condition { 2662 match c { 2663 syntax::Condition::Expr(e) => Condition::Expr(Box::new(translate_expression(state, e))), 2664 _ => panic!(), 2665 } 2666 } 2667 2668 fn translate_for_init(state: &mut State, s: &syntax::ForInitStatement) -> ForInitStatement { 2669 match s { 2670 syntax::ForInitStatement::Expression(e) => { 2671 ForInitStatement::Expression(e.as_ref().map(|e| translate_expression(state, e))) 2672 } 2673 syntax::ForInitStatement::Declaration(d) => ForInitStatement::Declaration(Box::new( 2674 translate_declaration(state, d, RunClass::Scalar), 2675 )), 2676 } 2677 } 2678 2679 fn translate_for_rest(state: &mut State, s: &syntax::ForRestStatement) -> ForRestStatement { 2680 ForRestStatement { 2681 condition: s.condition.as_ref().map(|c| translate_condition(state, c)), 2682 post_expr: s 2683 .post_expr 2684 .as_ref() 2685 .map(|e| Box::new(translate_expression(state, e))), 2686 } 2687 } 2688 2689 fn translate_iteration(state: &mut State, s: &syntax::IterationStatement) -> IterationStatement { 2690 match s { 2691 syntax::IterationStatement::While(cond, s) => IterationStatement::While( 2692 translate_condition(state, cond), 2693 Box::new(translate_statement(state, s)), 2694 ), 2695 syntax::IterationStatement::For(init, rest, s) => IterationStatement::For( 2696 translate_for_init(state, init), 2697 translate_for_rest(state, rest), 2698 Box::new(translate_statement(state, s)), 2699 ), 2700 syntax::IterationStatement::DoWhile(s, e) => IterationStatement::DoWhile( 2701 Box::new(translate_statement(state, s)), 2702 Box::new(translate_expression(state, e)), 2703 ), 2704 } 2705 } 2706 2707 fn translate_case(state: &mut State, c: &syntax::CaseLabel) -> CaseLabel { 2708 match c { 2709 syntax::CaseLabel::Def => CaseLabel::Def, 2710 syntax::CaseLabel::Case(e) => CaseLabel::Case(Box::new(translate_expression(state, e))), 2711 } 2712 } 2713 2714 fn translate_selection_rest( 2715 state: &mut State, 2716 s: &syntax::SelectionRestStatement, 2717 ) -> (Box<Statement>, Option<Box<Statement>>) { 2718 match s { 2719 syntax::SelectionRestStatement::Statement(s) => { 2720 (Box::new(translate_statement(state, s)), None) 2721 } 2722 syntax::SelectionRestStatement::Else(if_body, rest) => ( 2723 Box::new(translate_statement(state, if_body)), 2724 Some(Box::new(translate_statement(state, rest))), 2725 ), 2726 } 2727 } 2728 2729 fn translate_selection(state: &mut State, s: &syntax::SelectionStatement) -> SelectionStatement { 2730 let cond = Box::new(translate_expression(state, &s.cond)); 2731 let (body, else_stmt) = translate_selection_rest(state, &s.rest); 2732 SelectionStatement { 2733 cond, 2734 body, 2735 else_stmt, 2736 } 2737 } 2738 2739 fn translate_simple_statement(state: &mut State, s: &syntax::SimpleStatement) -> SimpleStatement { 2740 match s { 2741 syntax::SimpleStatement::Declaration(d) => { 2742 SimpleStatement::Declaration(translate_declaration(state, d, RunClass::Unknown)) 2743 } 2744 syntax::SimpleStatement::Expression(e) => { 2745 SimpleStatement::Expression(e.as_ref().map(|e| translate_expression(state, e))) 2746 } 2747 syntax::SimpleStatement::Iteration(i) => { 2748 SimpleStatement::Iteration(translate_iteration(state, i)) 2749 } 2750 syntax::SimpleStatement::Selection(s) => { 2751 SimpleStatement::Selection(translate_selection(state, s)) 2752 } 2753 syntax::SimpleStatement::Jump(j) => SimpleStatement::Jump(translate_jump(state, j)), 2754 syntax::SimpleStatement::Switch(s) => SimpleStatement::Switch(translate_switch(state, s)), 2755 syntax::SimpleStatement::CaseLabel(_) => panic!("should be handled by translate_switch"), 2756 } 2757 } 2758 2759 fn translate_statement(state: &mut State, s: &syntax::Statement) -> Statement { 2760 match s { 2761 syntax::Statement::Compound(s) => { 2762 Statement::Compound(Box::new(translate_compound_statement(state, s))) 2763 } 2764 syntax::Statement::Simple(s) => { 2765 Statement::Simple(Box::new(translate_simple_statement(state, s))) 2766 } 2767 } 2768 } 2769 2770 fn translate_compound_statement( 2771 state: &mut State, 2772 cs: &syntax::CompoundStatement, 2773 ) -> CompoundStatement { 2774 CompoundStatement { 2775 statement_list: cs 2776 .statement_list 2777 .iter() 2778 .map(|x| translate_statement(state, x)) 2779 .collect(), 2780 } 2781 } 2782 2783 fn translate_function_parameter_declaration( 2784 state: &mut State, 2785 p: &syntax::FunctionParameterDeclaration, 2786 index: usize, 2787 ) -> FunctionParameterDeclaration { 2788 match p { 2789 syntax::FunctionParameterDeclaration::Named(qual, p) => { 2790 let mut ty: Type = lift(state, &p.ty); 2791 if let Some(a) = &p.ident.array_spec { 2792 ty.array_sizes = Some(Box::new(lift(state, a))); 2793 } 2794 2795 ty.precision = get_precision(qual); 2796 2797 let decl = SymDecl::Local( 2798 StorageClass::None, 2799 ty.clone(), 2800 RunClass::Dependent(1 << index), 2801 ); 2802 let d = FunctionParameterDeclarator { 2803 ty, 2804 name: p.ident.ident.clone(), 2805 sym: state.declare(p.ident.ident.as_str(), decl), 2806 }; 2807 FunctionParameterDeclaration::Named(lift_type_qualifier_for_parameter(state, qual), d) 2808 } 2809 syntax::FunctionParameterDeclaration::Unnamed(qual, p) => { 2810 FunctionParameterDeclaration::Unnamed( 2811 lift_type_qualifier_for_parameter(state, qual), 2812 p.clone(), 2813 ) 2814 } 2815 } 2816 } 2817 2818 fn translate_prototype( 2819 state: &mut State, 2820 cs: &syntax::FunctionPrototype, 2821 ) -> (FunctionPrototype, SymRef) { 2822 let prototype = FunctionPrototype { 2823 ty: lift(state, &cs.ty), 2824 name: cs.name.clone(), 2825 parameters: cs 2826 .parameters 2827 .iter() 2828 .enumerate() 2829 .map(|(i, x)| translate_function_parameter_declaration(state, x, i)) 2830 .collect(), 2831 }; 2832 let sym = if let Some(sym) = state.lookup(prototype.name.as_str()) { 2833 match &state.sym(sym).decl { 2834 SymDecl::UserFunction(..) => {} 2835 _ => panic!( 2836 "prototype conflicts with existing symbol: {}", 2837 prototype.name.as_str() 2838 ), 2839 } 2840 sym 2841 } else { 2842 let pfd = Rc::new(FunctionDefinition { 2843 prototype: prototype.clone(), 2844 body: CompoundStatement::new(), 2845 globals: Vec::new(), 2846 texel_fetches: HashMap::new(), 2847 }); 2848 state.declare( 2849 prototype.name.as_str(), 2850 SymDecl::UserFunction(pfd, RunClass::Unknown), 2851 ) 2852 }; 2853 (prototype, sym) 2854 } 2855 2856 fn translate_function_prototype( 2857 state: &mut State, 2858 prototype: &syntax::FunctionPrototype, 2859 ) -> FunctionPrototype { 2860 let (prototype, _) = translate_prototype(state, prototype); 2861 prototype 2862 } 2863 2864 fn translate_function_definition( 2865 state: &mut State, 2866 sfd: &syntax::FunctionDefinition, 2867 ) -> Rc<FunctionDefinition> { 2868 let (prototype, sym) = translate_prototype(state, &sfd.prototype); 2869 2870 state.push_scope(prototype.name.as_str().into()); 2871 state.in_function = Some(sym); 2872 state.modified_globals.get_mut().clear(); 2873 state.texel_fetches.clear(); 2874 let body = translate_compound_statement(state, &sfd.statement); 2875 let mut globals = Vec::new(); 2876 mem::swap(&mut globals, state.modified_globals.get_mut()); 2877 let mut texel_fetches = HashMap::new(); 2878 mem::swap(&mut texel_fetches, &mut state.texel_fetches); 2879 state.in_function = None; 2880 state.pop_scope(); 2881 2882 let fd = Rc::new(FunctionDefinition { 2883 prototype, 2884 body, 2885 globals, 2886 texel_fetches, 2887 }); 2888 state.sym_mut(sym).decl = SymDecl::UserFunction(fd.clone(), RunClass::Unknown); 2889 fd 2890 } 2891 2892 fn translate_external_declaration( 2893 state: &mut State, 2894 ed: &syntax::ExternalDeclaration, 2895 ) -> ExternalDeclaration { 2896 match ed { 2897 syntax::ExternalDeclaration::Declaration(d) => { 2898 ExternalDeclaration::Declaration(translate_declaration(state, d, RunClass::Unknown)) 2899 } 2900 syntax::ExternalDeclaration::FunctionDefinition(fd) => { 2901 ExternalDeclaration::FunctionDefinition(translate_function_definition(state, fd)) 2902 } 2903 syntax::ExternalDeclaration::Preprocessor(p) => { 2904 ExternalDeclaration::Preprocessor(p.clone()) 2905 } 2906 } 2907 } 2908 2909 fn declare_function_ext( 2910 state: &mut State, 2911 name: &str, 2912 cxx_name: Option<&'static str>, 2913 ret: Type, 2914 params: Vec<Type>, 2915 run_class: RunClass, 2916 ) { 2917 let sig = FunctionSignature { ret, params }; 2918 match state.lookup_sym_mut(name) { 2919 Some(Symbol { 2920 decl: SymDecl::NativeFunction(f, ..), 2921 .. 2922 }) => f.signatures.push(sig), 2923 None => { 2924 state.declare( 2925 name, 2926 SymDecl::NativeFunction( 2927 FunctionType { 2928 signatures: NonEmpty::new(sig), 2929 }, 2930 cxx_name, 2931 run_class, 2932 ), 2933 ); 2934 } 2935 _ => panic!("overloaded function name {}", name), 2936 } 2937 //state.declare(name, Type::Function(FunctionType{ v})) 2938 } 2939 2940 fn declare_function( 2941 state: &mut State, 2942 name: &str, 2943 cxx_name: Option<&'static str>, 2944 ret: Type, 2945 params: Vec<Type>, 2946 ) { 2947 declare_function_ext(state, name, cxx_name, ret, params, RunClass::Unknown) 2948 } 2949 2950 pub fn ast_to_hir(state: &mut State, tu: &syntax::TranslationUnit) -> TranslationUnit { 2951 // global scope 2952 state.push_scope("global".into()); 2953 use TypeKind::*; 2954 declare_function( 2955 state, 2956 "vec2", 2957 Some("make_vec2"), 2958 Type::new(Vec2), 2959 vec![Type::new(Float)], 2960 ); 2961 declare_function( 2962 state, 2963 "vec2", 2964 Some("make_vec2"), 2965 Type::new(Vec2), 2966 vec![Type::new(Float), Type::new(Float)], 2967 ); 2968 declare_function( 2969 state, 2970 "vec2", 2971 Some("make_vec2"), 2972 Type::new(Vec2), 2973 vec![Type::new(IVec2)], 2974 ); 2975 declare_function( 2976 state, 2977 "vec2", 2978 Some("make_vec2"), 2979 Type::new(Vec2), 2980 vec![Type::new(IVec3)], 2981 ); 2982 declare_function( 2983 state, 2984 "vec3", 2985 Some("make_vec3"), 2986 Type::new(Vec3), 2987 vec![Type::new(Float), Type::new(Float), Type::new(Float)], 2988 ); 2989 declare_function( 2990 state, 2991 "vec3", 2992 Some("make_vec3"), 2993 Type::new(Vec3), 2994 vec![Type::new(Float)], 2995 ); 2996 declare_function( 2997 state, 2998 "vec3", 2999 Some("make_vec3"), 3000 Type::new(Vec3), 3001 vec![Type::new(Vec2), Type::new(Float)], 3002 ); 3003 declare_function( 3004 state, 3005 "vec4", 3006 Some("make_vec4"), 3007 Type::new(Vec4), 3008 vec![Type::new(Float)], 3009 ); 3010 declare_function( 3011 state, 3012 "vec4", 3013 Some("make_vec4"), 3014 Type::new(Vec4), 3015 vec![Type::new(Vec3), Type::new(Float)], 3016 ); 3017 declare_function( 3018 state, 3019 "vec4", 3020 Some("make_vec4"), 3021 Type::new(Vec4), 3022 vec![ 3023 Type::new(Float), 3024 Type::new(Float), 3025 Type::new(Float), 3026 Type::new(Float), 3027 ], 3028 ); 3029 declare_function( 3030 state, 3031 "vec4", 3032 Some("make_vec4"), 3033 Type::new(Vec4), 3034 vec![Type::new(Vec2), Type::new(Float), Type::new(Float)], 3035 ); 3036 declare_function( 3037 state, 3038 "vec4", 3039 Some("make_vec4"), 3040 Type::new(Vec4), 3041 vec![Type::new(Vec2), Type::new(Vec2)], 3042 ); 3043 declare_function( 3044 state, 3045 "vec4", 3046 Some("make_vec4"), 3047 Type::new(Vec4), 3048 vec![Type::new(Float), Type::new(Float), Type::new(Vec2)], 3049 ); 3050 declare_function( 3051 state, 3052 "vec4", 3053 Some("make_vec4"), 3054 Type::new(Vec4), 3055 vec![Type::new(Vec4)], 3056 ); 3057 declare_function( 3058 state, 3059 "vec4", 3060 Some("make_vec4"), 3061 Type::new(Vec4), 3062 vec![Type::new(IVec4)], 3063 ); 3064 3065 declare_function( 3066 state, 3067 "bvec2", 3068 Some("make_bvec2"), 3069 Type::new(BVec2), 3070 vec![Type::new(Bool)], 3071 ); 3072 declare_function( 3073 state, 3074 "bvec3", 3075 Some("make_bvec3"), 3076 Type::new(BVec3), 3077 vec![Type::new(Bool)], 3078 ); 3079 declare_function( 3080 state, 3081 "bvec4", 3082 Some("make_bvec4"), 3083 Type::new(BVec4), 3084 vec![Type::new(Bool)], 3085 ); 3086 declare_function( 3087 state, 3088 "bvec4", 3089 Some("make_bvec4"), 3090 Type::new(BVec4), 3091 vec![Type::new(BVec2), Type::new(BVec2)], 3092 ); 3093 declare_function( 3094 state, 3095 "bvec4", 3096 Some("make_bvec4"), 3097 Type::new(BVec4), 3098 vec![Type::new(Bool), Type::new(Bool), Type::new(Bool), Type::new(Bool)], 3099 ); 3100 declare_function( 3101 state, 3102 "int", 3103 Some("make_int"), 3104 Type::new(Int), 3105 vec![Type::new(Float)], 3106 ); 3107 declare_function( 3108 state, 3109 "float", 3110 Some("make_float"), 3111 Type::new(Float), 3112 vec![Type::new(Float)], 3113 ); 3114 declare_function( 3115 state, 3116 "float", 3117 Some("make_float"), 3118 Type::new(Float), 3119 vec![Type::new(Int)], 3120 ); 3121 declare_function( 3122 state, 3123 "int", 3124 Some("make_int"), 3125 Type::new(Int), 3126 vec![Type::new(UInt)], 3127 ); 3128 declare_function( 3129 state, 3130 "uint", 3131 Some("make_uint"), 3132 Type::new(UInt), 3133 vec![Type::new(Float)], 3134 ); 3135 declare_function( 3136 state, 3137 "uint", 3138 Some("make_uint"), 3139 Type::new(UInt), 3140 vec![Type::new(Int)], 3141 ); 3142 declare_function( 3143 state, 3144 "ivec2", 3145 Some("make_ivec2"), 3146 Type::new(IVec2), 3147 vec![Type::new(UInt), Type::new(UInt)], 3148 ); 3149 declare_function( 3150 state, 3151 "ivec2", 3152 Some("make_ivec2"), 3153 Type::new(IVec2), 3154 vec![Type::new(Int), Type::new(Int)], 3155 ); 3156 declare_function( 3157 state, 3158 "ivec2", 3159 Some("make_ivec2"), 3160 Type::new(IVec2), 3161 vec![Type::new(Vec2)], 3162 ); 3163 declare_function( 3164 state, 3165 "ivec3", 3166 Some("make_ivec3"), 3167 Type::new(IVec3), 3168 vec![Type::new(IVec2), Type::new(Int)], 3169 ); 3170 declare_function( 3171 state, 3172 "ivec4", 3173 Some("make_ivec4"), 3174 Type::new(IVec4), 3175 vec![ 3176 Type::new(Int), 3177 Type::new(Int), 3178 Type::new(Int), 3179 Type::new(Int), 3180 ], 3181 ); 3182 declare_function( 3183 state, 3184 "ivec4", 3185 Some("make_ivec4"), 3186 Type::new(IVec4), 3187 vec![Type::new(Vec4)], 3188 ); 3189 declare_function( 3190 state, 3191 "ivec4", 3192 Some("make_ivec4"), 3193 Type::new(IVec4), 3194 vec![Type::new(IVec2), Type::new(Int), Type::new(Int)], 3195 ); 3196 3197 declare_function( 3198 state, 3199 "mat2", 3200 Some("make_mat2"), 3201 Type::new(Mat2), 3202 vec![Type::new(Vec2), Type::new(Vec2)], 3203 ); 3204 declare_function( 3205 state, 3206 "mat2", 3207 Some("make_mat2"), 3208 Type::new(Mat2), 3209 vec![Type::new(Float)], 3210 ); 3211 declare_function( 3212 state, 3213 "mat2", 3214 Some("make_mat2"), 3215 Type::new(Mat2), 3216 vec![Type::new(Mat4)], 3217 ); 3218 declare_function( 3219 state, 3220 "mat3", 3221 Some("make_mat3"), 3222 Type::new(Mat3), 3223 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)], 3224 ); 3225 declare_function( 3226 state, 3227 "mat3", 3228 Some("make_mat3"), 3229 Type::new(Mat3), 3230 vec![Type::new(Mat4)], 3231 ); 3232 declare_function( 3233 state, 3234 "mat3", 3235 Some("make_mat3"), 3236 Type::new(Mat3), 3237 vec![ 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 Type::new(Float), 3246 Type::new(Float), 3247 ], 3248 ); 3249 declare_function( 3250 state, 3251 "mat3x4", 3252 Some("make_mat3x4"), 3253 Type::new(Mat34), 3254 vec![ 3255 Type::new(Float), 3256 Type::new(Float), 3257 Type::new(Float), 3258 Type::new(Float), 3259 3260 Type::new(Float), 3261 Type::new(Float), 3262 Type::new(Float), 3263 Type::new(Float), 3264 3265 Type::new(Float), 3266 Type::new(Float), 3267 Type::new(Float), 3268 Type::new(Float), 3269 ], 3270 ); 3271 declare_function( 3272 state, 3273 "transpose", 3274 None, 3275 Type::new(Mat43), 3276 vec![Type::new(Mat34)], 3277 ); 3278 declare_function( 3279 state, 3280 "mat4", 3281 Some("make_mat4"), 3282 Type::new(Mat4), 3283 vec![ 3284 Type::new(Vec4), 3285 Type::new(Vec4), 3286 Type::new(Vec4), 3287 Type::new(Vec4), 3288 ], 3289 ); 3290 declare_function( 3291 state, 3292 "mat4", 3293 Some("make_mat4"), 3294 Type::new(Mat4), 3295 vec![ 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 Type::new(Float), 3311 Type::new(Float), 3312 ], 3313 ); 3314 declare_function(state, "abs", None, Type::new(Vec2), vec![Type::new(Vec2)]); 3315 declare_function(state, "abs", None, Type::new(Vec3), vec![Type::new(Vec3)]); 3316 declare_function(state, "abs", None, Type::new(Float), vec![Type::new(Float)]); 3317 declare_function(state, "sign", None, Type::new(Vec2), vec![Type::new(Vec2)]); 3318 declare_function(state, "sign", None, Type::new(Vec3), vec![Type::new(Vec3)]); 3319 declare_function(state, "sign", None, Type::new(Float), vec![Type::new(Float)]); 3320 declare_function( 3321 state, 3322 "dot", 3323 None, 3324 Type::new(Float), 3325 vec![Type::new(Vec3), Type::new(Vec3)], 3326 ); 3327 declare_function( 3328 state, 3329 "dot", 3330 None, 3331 Type::new(Float), 3332 vec![Type::new(Vec2), Type::new(Vec2)], 3333 ); 3334 for t in &[Vec2, Vec3, Vec4] { 3335 declare_function( 3336 state, 3337 "min", 3338 None, 3339 Type::new(*t), 3340 vec![Type::new(*t), Type::new(Float)], 3341 ); 3342 declare_function( 3343 state, 3344 "max", 3345 None, 3346 Type::new(*t), 3347 vec![Type::new(*t), Type::new(Float)], 3348 ); 3349 } 3350 for t in &[Int, Float, Vec2, Vec3, Vec4] { 3351 declare_function( 3352 state, 3353 "min", 3354 None, 3355 Type::new(*t), 3356 vec![Type::new(*t), Type::new(*t)], 3357 ); 3358 declare_function( 3359 state, 3360 "max", 3361 None, 3362 Type::new(*t), 3363 vec![Type::new(*t), Type::new(*t)], 3364 ); 3365 } 3366 3367 declare_function( 3368 state, 3369 "mix", 3370 None, 3371 Type::new(Vec2), 3372 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)], 3373 ); 3374 declare_function( 3375 state, 3376 "mix", 3377 None, 3378 Type::new(Vec2), 3379 vec![Type::new(Vec2), Type::new(Vec2), Type::new(BVec2)], 3380 ); 3381 declare_function( 3382 state, 3383 "mix", 3384 None, 3385 Type::new(Vec2), 3386 vec![Type::new(Vec2), Type::new(Vec2), Type::new(Float)], 3387 ); 3388 declare_function( 3389 state, 3390 "mix", 3391 None, 3392 Type::new(Vec3), 3393 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Vec3)], 3394 ); 3395 declare_function( 3396 state, 3397 "mix", 3398 None, 3399 Type::new(Vec4), 3400 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)], 3401 ); 3402 declare_function( 3403 state, 3404 "mix", 3405 None, 3406 Type::new(Vec4), 3407 vec![Type::new(Vec4), Type::new(Vec4), Type::new(Float)], 3408 ); 3409 declare_function( 3410 state, 3411 "mix", 3412 None, 3413 Type::new(Vec3), 3414 vec![Type::new(Vec3), Type::new(Vec3), Type::new(Float)], 3415 ); 3416 declare_function( 3417 state, 3418 "mix", 3419 None, 3420 Type::new(Vec3), 3421 vec![Type::new(Vec3), Type::new(Vec3), Type::new(BVec3)], 3422 ); 3423 declare_function( 3424 state, 3425 "mix", 3426 None, 3427 Type::new(Float), 3428 vec![Type::new(Float), Type::new(Float), Type::new(Float)], 3429 ); 3430 declare_function( 3431 state, 3432 "mix", 3433 None, 3434 Type::new(Vec4), 3435 vec![Type::new(Vec4), Type::new(Vec4), Type::new(BVec4)], 3436 ); 3437 declare_function( 3438 state, 3439 "step", 3440 None, 3441 Type::new(Float), 3442 vec![Type::new(Float), Type::new(Float)], 3443 ); 3444 declare_function( 3445 state, 3446 "step", 3447 None, 3448 Type::new(Vec2), 3449 vec![Type::new(Vec2), Type::new(Vec2)], 3450 ); 3451 declare_function( 3452 state, 3453 "step", 3454 None, 3455 Type::new(Vec2), 3456 vec![Type::new(Float), Type::new(Vec2)], 3457 ); 3458 declare_function( 3459 state, 3460 "step", 3461 None, 3462 Type::new(Vec3), 3463 vec![Type::new(Vec3), Type::new(Vec3)], 3464 ); 3465 declare_function( 3466 state, 3467 "step", 3468 None, 3469 Type::new(Vec4), 3470 vec![Type::new(Float), Type::new(Vec4)], 3471 ); 3472 declare_function( 3473 state, 3474 "notEqual", 3475 None, 3476 Type::new(BVec4), 3477 vec![Type::new(IVec4), Type::new(IVec4)], 3478 ); 3479 3480 declare_function_ext( 3481 state, 3482 "fwidth", 3483 None, 3484 Type::new(Vec2), 3485 vec![Type::new(Vec2)], 3486 RunClass::Scalar, 3487 ); 3488 declare_function_ext( 3489 state, 3490 "dFdx", 3491 None, 3492 Type::new(Float), 3493 vec![Type::new(Float)], 3494 RunClass::Scalar, 3495 ); 3496 declare_function_ext( 3497 state, 3498 "dFdx", 3499 None, 3500 Type::new(Vec2), 3501 vec![Type::new(Vec2)], 3502 RunClass::Scalar, 3503 ); 3504 3505 declare_function(state, "cos", None, Type::new(Float), vec![Type::new(Float)]); 3506 declare_function(state, "sin", None, Type::new(Float), vec![Type::new(Float)]); 3507 declare_function(state, "tan", None, Type::new(Float), vec![Type::new(Float)]); 3508 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float)]); 3509 declare_function(state, "atan", None, Type::new(Float), vec![Type::new(Float), Type::new(Float)]); 3510 for t in &[Vec2, Vec3, Vec4] { 3511 declare_function( 3512 state, 3513 "clamp", 3514 None, 3515 Type::new(*t), 3516 vec![Type::new(*t), Type::new(Float), Type::new(Float)], 3517 ); 3518 } 3519 for t in &[Float, Vec2, Vec3, Vec4] { 3520 declare_function( 3521 state, 3522 "clamp", 3523 None, 3524 Type::new(*t), 3525 vec![Type::new(*t), Type::new(*t), Type::new(*t)], 3526 ); 3527 } 3528 declare_function( 3529 state, 3530 "length", 3531 None, 3532 Type::new(Float), 3533 vec![Type::new(Vec2)], 3534 ); 3535 declare_function(state, "pow", None, Type::new(Vec3), vec![Type::new(Vec3)]); 3536 declare_function(state, "pow", None, Type::new(Float), vec![Type::new(Float)]); 3537 declare_function(state, "exp", None, Type::new(Float), vec![Type::new(Float)]); 3538 declare_function(state, "exp2", None, Type::new(Float), vec![Type::new(Float)]); 3539 declare_function(state, "log", None, Type::new(Float), vec![Type::new(Float)]); 3540 declare_function(state, "log2", None, Type::new(Float), vec![Type::new(Float)]); 3541 for t in &[Float, Vec2] { 3542 // recip is non-standard 3543 declare_function( 3544 state, 3545 "recip", 3546 None, 3547 Type::new(*t), 3548 vec![Type::new(*t)], 3549 ); 3550 declare_function( 3551 state, 3552 "inversesqrt", 3553 None, 3554 Type::new(*t), 3555 vec![Type::new(*t)], 3556 ); 3557 declare_function( 3558 state, 3559 "sqrt", 3560 None, 3561 Type::new(*t), 3562 vec![Type::new(*t)], 3563 ); 3564 } 3565 declare_function( 3566 state, 3567 "distance", 3568 None, 3569 Type::new(Float), 3570 vec![Type::new(Vec2), Type::new(Vec2)], 3571 ); 3572 3573 declare_function( 3574 state, 3575 "equal", 3576 None, 3577 Type::new(BVec2), 3578 vec![Type::new(Vec2), Type::new(Vec2)], 3579 ); 3580 declare_function( 3581 state, 3582 "equal", 3583 None, 3584 Type::new(BVec4), 3585 vec![Type::new(Vec4), Type::new(Vec4)], 3586 ); 3587 declare_function( 3588 state, 3589 "notEqual", 3590 None, 3591 Type::new(BVec2), 3592 vec![Type::new(Vec2), Type::new(Vec2)], 3593 ); 3594 declare_function( 3595 state, 3596 "notEqual", 3597 None, 3598 Type::new(BVec4), 3599 vec![Type::new(Vec4), Type::new(Vec4)], 3600 ); 3601 declare_function( 3602 state, 3603 "lessThanEqual", 3604 None, 3605 Type::new(BVec2), 3606 vec![Type::new(Vec2), Type::new(Vec2)], 3607 ); 3608 declare_function( 3609 state, 3610 "lessThanEqual", 3611 None, 3612 Type::new(BVec3), 3613 vec![Type::new(Vec3), Type::new(Vec3)], 3614 ); 3615 declare_function( 3616 state, 3617 "lessThanEqual", 3618 None, 3619 Type::new(BVec4), 3620 vec![Type::new(Vec4), Type::new(Vec4)], 3621 ); 3622 declare_function( 3623 state, 3624 "lessThan", 3625 None, 3626 Type::new(BVec2), 3627 vec![Type::new(Vec2), Type::new(Vec2)], 3628 ); 3629 declare_function( 3630 state, 3631 "lessThan", 3632 None, 3633 Type::new(BVec4), 3634 vec![Type::new(Vec4), Type::new(Vec4)], 3635 ); 3636 declare_function( 3637 state, 3638 "greaterThan", 3639 None, 3640 Type::new(BVec2), 3641 vec![Type::new(Vec2), Type::new(Vec2)], 3642 ); 3643 declare_function( 3644 state, 3645 "greaterThan", 3646 None, 3647 Type::new(BVec4), 3648 vec![Type::new(Vec4), Type::new(Vec4)], 3649 ); 3650 declare_function( 3651 state, 3652 "greaterThanEqual", 3653 None, 3654 Type::new(BVec2), 3655 vec![Type::new(Vec2), Type::new(Vec2)], 3656 ); 3657 declare_function( 3658 state, 3659 "greaterThanEqual", 3660 None, 3661 Type::new(BVec4), 3662 vec![Type::new(Vec4), Type::new(Vec4)], 3663 ); 3664 declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec2)]); 3665 declare_function(state, "any", None, Type::new(Bool), vec![Type::new(BVec4)]); 3666 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec2)]); 3667 declare_function(state, "all", None, Type::new(Bool), vec![Type::new(BVec4)]); 3668 3669 declare_function( 3670 state, 3671 "if_then_else", 3672 None, 3673 Type::new(Vec3), 3674 vec![Type::new(BVec3), Type::new(Vec3), Type::new(Vec3)], 3675 ); 3676 declare_function(state, "floor", None, Type::new(Vec4), vec![Type::new(Vec4)]); 3677 declare_function(state, "floor", None, Type::new(Vec2), vec![Type::new(Vec2)]); 3678 declare_function( 3679 state, 3680 "floor", 3681 None, 3682 Type::new(Float), 3683 vec![Type::new(Float)], 3684 ); 3685 declare_function( 3686 state, 3687 "ceil", 3688 None, 3689 Type::new(Float), 3690 vec![Type::new(Float)], 3691 ); 3692 declare_function( 3693 state, 3694 "round", 3695 None, 3696 Type::new(Float), 3697 vec![Type::new(Float)], 3698 ); 3699 declare_function( 3700 state, 3701 "fract", 3702 None, 3703 Type::new(Float), 3704 vec![Type::new(Float)], 3705 ); 3706 declare_function( 3707 state, 3708 "fract", 3709 None, 3710 Type::new(Vec2), 3711 vec![Type::new(Vec2)], 3712 ); 3713 declare_function(state, "mod", None, Type::new(Vec2), vec![Type::new(Vec2)]); 3714 declare_function(state, "mod", None, Type::new(Float), vec![Type::new(Float)]); 3715 3716 declare_function( 3717 state, 3718 "texelFetch", 3719 None, 3720 Type::new(Vec4), 3721 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)], 3722 ); 3723 declare_function( 3724 state, 3725 "texelFetch", 3726 None, 3727 Type::new(IVec4), 3728 vec![Type::new(ISampler2D), Type::new(IVec2), Type::new(Int)], 3729 ); 3730 declare_function( 3731 state, 3732 "texelFetchOffset", 3733 None, 3734 Type::new(Vec4), 3735 vec![ 3736 Type::new(Sampler2D), 3737 Type::new(IVec2), 3738 Type::new(Int), 3739 Type::new(IVec2), 3740 ], 3741 ); 3742 declare_function( 3743 state, 3744 "texelFetchOffset", 3745 None, 3746 Type::new(IVec4), 3747 vec![ 3748 Type::new(ISampler2D), 3749 Type::new(IVec2), 3750 Type::new(Int), 3751 Type::new(IVec2), 3752 ], 3753 ); 3754 declare_function( 3755 state, 3756 "texture", 3757 None, 3758 Type::new(Vec4), 3759 vec![Type::new(Sampler2D), Type::new(Vec2)], 3760 ); 3761 declare_function( 3762 state, 3763 "texture", 3764 None, 3765 Type::new(Vec4), 3766 vec![Type::new(Sampler2DRect), Type::new(Vec2)], 3767 ); 3768 declare_function( 3769 state, 3770 "textureSize", 3771 None, 3772 Type::new(IVec2), 3773 vec![Type::new(Sampler2D), Type::new(Int)], 3774 ); 3775 declare_function( 3776 state, 3777 "textureSize", 3778 None, 3779 Type::new(IVec2), 3780 vec![Type::new(Sampler2DRect), Type::new(Int)], 3781 ); 3782 3783 declare_function( 3784 state, 3785 "inverse", 3786 None, 3787 Type::new(Mat2), 3788 vec![Type::new(Mat2)], 3789 ); 3790 declare_function( 3791 state, 3792 "transpose", 3793 None, 3794 Type::new(Mat3), 3795 vec![Type::new(Mat3)], 3796 ); 3797 declare_function( 3798 state, 3799 "normalize", 3800 None, 3801 Type::new(Vec2), 3802 vec![Type::new(Vec2)], 3803 ); 3804 state.declare( 3805 "gl_FragCoord", 3806 SymDecl::Global(StorageClass::In, None, Type::new(Vec4), RunClass::Vector), 3807 ); 3808 state.declare( 3809 "gl_FragColor", 3810 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector), 3811 ); 3812 state.declare( 3813 "gl_Position", 3814 SymDecl::Global(StorageClass::Out, None, Type::new(Vec4), RunClass::Vector), 3815 ); 3816 state.clip_dist_sym = state.declare( 3817 "gl_ClipDistance", 3818 SymDecl::Global(StorageClass::Out, None, Type::new_array(Float, 4), RunClass::Vector), 3819 ); 3820 3821 state.declare( 3822 "swgl_SpanLength", 3823 SymDecl::Global(StorageClass::In, None, Type::new(Int), RunClass::Scalar), 3824 ); 3825 state.declare( 3826 "swgl_StepSize", 3827 SymDecl::Global(StorageClass::Const, None, Type::new(Int), RunClass::Scalar), 3828 ); 3829 3830 for t in &[Float, Vec2, Vec3, Vec4, Int, IVec2, IVec3, IVec4, Mat3, Mat4] { 3831 declare_function_ext( 3832 state, 3833 "swgl_forceScalar", 3834 None, 3835 Type::new(*t), 3836 vec![Type::new(*t)], 3837 RunClass::Scalar, 3838 ); 3839 } 3840 3841 // GL_ARB_shader_group_vote 3842 for (name, cxx_name) in &[("anyInvocations", "test_any"), 3843 ("allInvocations", "test_all"), 3844 ("allInvocationsEqual", "test_equal")] { 3845 declare_function_ext( 3846 state, 3847 name, 3848 Some(cxx_name), 3849 Type::new(Bool), 3850 vec![Type::new(Bool)], 3851 RunClass::Scalar, 3852 ); 3853 } 3854 3855 declare_function( 3856 state, 3857 "swgl_stepInterp", 3858 None, 3859 Type::new(Void), 3860 vec![], 3861 ); 3862 3863 for t in &[Float, Vec2, Vec3, Vec4] { 3864 declare_function_ext( 3865 state, 3866 "swgl_interpStep", 3867 None, 3868 Type::new(*t), 3869 vec![Type::new(*t)], 3870 RunClass::Scalar, 3871 ); 3872 } 3873 3874 declare_function( 3875 state, 3876 "swgl_commitPartialSolidRGBA8", 3877 None, 3878 Type::new(Void), 3879 vec![Type::new(Int), Type::new(Vec4)], 3880 ); 3881 declare_function( 3882 state, 3883 "swgl_commitPartialSolidR8", 3884 None, 3885 Type::new(Void), 3886 vec![Type::new(Int), Type::new(Float)], 3887 ); 3888 declare_function( 3889 state, 3890 "swgl_commitSolidRGBA8", 3891 None, 3892 Type::new(Void), 3893 vec![Type::new(Vec4)], 3894 ); 3895 declare_function( 3896 state, 3897 "swgl_commitSolidR8", 3898 None, 3899 Type::new(Void), 3900 vec![Type::new(Float)], 3901 ); 3902 declare_function( 3903 state, 3904 "swgl_commitColorRGBA8", 3905 None, 3906 Type::new(Void), 3907 vec![Type::new(Vec4)], 3908 ); 3909 declare_function( 3910 state, 3911 "swgl_commitColorR8", 3912 None, 3913 Type::new(Void), 3914 vec![Type::new(Float)], 3915 ); 3916 declare_function( 3917 state, 3918 "swgl_blendDropShadow", 3919 None, 3920 Type::new(Void), 3921 vec![Type::new(Vec4)], 3922 ); 3923 declare_function( 3924 state, 3925 "swgl_blendSubpixelText", 3926 None, 3927 Type::new(Void), 3928 vec![Type::new(Vec4)], 3929 ); 3930 declare_function( 3931 state, 3932 "swgl_clipMask", 3933 None, 3934 Type::new(Void), 3935 vec![Type::new(Sampler2D), Type::new(Vec2), Type::new(Vec2), Type::new(Vec2)], 3936 ); 3937 declare_function( 3938 state, 3939 "swgl_antiAlias", 3940 None, 3941 Type::new(Void), 3942 vec![Type::new(Int)], 3943 ); 3944 declare_function( 3945 state, 3946 "swgl_antiAlias", 3947 None, 3948 Type::new(Void), 3949 vec![Type::new(BVec4)], 3950 ); 3951 declare_function_ext( 3952 state, 3953 "swgl_validateGradient", 3954 None, 3955 Type::new(Int), 3956 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)], 3957 RunClass::Scalar, 3958 ); 3959 declare_function_ext( 3960 state, 3961 "swgl_validateGradientFromStops", 3962 None, 3963 Type::new(Int), 3964 vec![Type::new(Sampler2D), Type::new(IVec2), Type::new(Int)], 3965 RunClass::Scalar, 3966 ); 3967 declare_function( 3968 state, 3969 "swgl_commitLinearGradientRGBA8", 3970 None, 3971 Type::new(Void), 3972 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Bool), 3973 Type::new(Vec2), Type::new(Vec2), Type::new(Float)], 3974 ); 3975 declare_function( 3976 state, 3977 "swgl_commitDitheredLinearGradientRGBA8", 3978 None, 3979 Type::new(Void), 3980 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Bool), 3981 Type::new(Vec2), Type::new(Vec2), Type::new(Float)], 3982 ); 3983 declare_function( 3984 state, 3985 "swgl_commitLinearGradientFromStopsRGBA8", 3986 None, 3987 Type::new(Void), 3988 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), 3989 Type::new(Vec2), Type::new(Vec2), Type::new(Float)], 3990 ); 3991 declare_function( 3992 state, 3993 "swgl_commitDitheredLinearGradientFromStopsRGBA8", 3994 None, 3995 Type::new(Void), 3996 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), 3997 Type::new(Vec2), Type::new(Vec2), Type::new(Float), Type::new(Vec4)], 3998 ); 3999 declare_function( 4000 state, 4001 "swgl_commitRadialGradientRGBA8", 4002 None, 4003 Type::new(Void), 4004 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2), 4005 Type::new(Float)], 4006 ); 4007 declare_function( 4008 state, 4009 "swgl_commitDitheredRadialGradientRGBA8", 4010 None, 4011 Type::new(Void), 4012 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2), 4013 Type::new(Float)], 4014 ); 4015 declare_function( 4016 state, 4017 "swgl_commitRadialGradientFromStopsRGBA8", 4018 None, 4019 Type::new(Void), 4020 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2), 4021 Type::new(Float)], 4022 ); 4023 declare_function( 4024 state, 4025 "swgl_commitDitheredRadialGradientFromStopsRGBA8", 4026 None, 4027 Type::new(Void), 4028 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Int), Type::new(Float), Type::new(Bool), Type::new(Vec2), 4029 Type::new(Float)], 4030 ); 4031 declare_function( 4032 state, 4033 "swgl_commitGradientRGBA8", 4034 None, 4035 Type::new(Void), 4036 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float)], 4037 ); 4038 declare_function( 4039 state, 4040 "swgl_commitGradientColorRGBA8", 4041 None, 4042 Type::new(Void), 4043 vec![Type::new(Sampler2D), Type::new(Int), Type::new(Float), Type::new(Float)], 4044 ); 4045 for s in &[Sampler2D, Sampler2DRect] { 4046 declare_function_ext( 4047 state, 4048 "swgl_isTextureLinear", 4049 None, 4050 Type::new(Bool), 4051 vec![Type::new(*s)], 4052 RunClass::Scalar, 4053 ); 4054 declare_function_ext( 4055 state, 4056 "swgl_isTextureRGBA8", 4057 None, 4058 Type::new(Bool), 4059 vec![Type::new(*s)], 4060 RunClass::Scalar, 4061 ); 4062 declare_function_ext( 4063 state, 4064 "swgl_isTextureR8", 4065 None, 4066 Type::new(Bool), 4067 vec![Type::new(*s)], 4068 RunClass::Scalar, 4069 ); 4070 declare_function( 4071 state, 4072 "swgl_commitTextureLinearRGBA8", 4073 None, 4074 Type::new(Void), 4075 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4076 ); 4077 declare_function( 4078 state, 4079 "swgl_commitTextureLinearR8", 4080 None, 4081 Type::new(Void), 4082 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4083 ); 4084 declare_function( 4085 state, 4086 "swgl_commitTextureLinearR8ToRGBA8", 4087 None, 4088 Type::new(Void), 4089 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4090 ); 4091 declare_function( 4092 state, 4093 "swgl_commitPartialTextureLinearR8", 4094 None, 4095 Type::new(Void), 4096 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4097 ); 4098 declare_function( 4099 state, 4100 "swgl_commitPartialTextureLinearInvertR8", 4101 None, 4102 Type::new(Void), 4103 vec![Type::new(Int), Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4104 ); 4105 declare_function( 4106 state, 4107 "swgl_commitTextureLinearColorRGBA8", 4108 None, 4109 Type::new(Void), 4110 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)], 4111 ); 4112 declare_function( 4113 state, 4114 "swgl_commitTextureLinearColorRGBA8", 4115 None, 4116 Type::new(Void), 4117 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)], 4118 ); 4119 declare_function( 4120 state, 4121 "swgl_commitTextureLinearColorR8", 4122 None, 4123 Type::new(Void), 4124 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Float)], 4125 ); 4126 declare_function( 4127 state, 4128 "swgl_commitTextureLinearColorR8ToRGBA8", 4129 None, 4130 Type::new(Void), 4131 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)], 4132 ); 4133 4134 declare_function( 4135 state, 4136 "swgl_commitTextureLinearRepeatRGBA8", 4137 None, 4138 Type::new(Void), 4139 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4140 Type::new(Vec4), Type::new(Vec4)], 4141 ); 4142 declare_function( 4143 state, 4144 "swgl_commitTextureLinearRepeatColorRGBA8", 4145 None, 4146 Type::new(Void), 4147 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4148 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)], 4149 ); 4150 4151 declare_function( 4152 state, 4153 "swgl_commitTextureNearestRGBA8", 4154 None, 4155 Type::new(Void), 4156 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4157 ); 4158 declare_function( 4159 state, 4160 "swgl_commitTextureNearestColorRGBA8", 4161 None, 4162 Type::new(Void), 4163 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)], 4164 ); 4165 declare_function( 4166 state, 4167 "swgl_commitTextureNearestRepeatRGBA8", 4168 None, 4169 Type::new(Void), 4170 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4171 Type::new(Vec4), Type::new(Vec4)], 4172 ); 4173 declare_function( 4174 state, 4175 "swgl_commitTextureNearestRepeatColorRGBA8", 4176 None, 4177 Type::new(Void), 4178 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4179 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)], 4180 ); 4181 4182 declare_function( 4183 state, 4184 "swgl_commitTextureRGBA8", 4185 None, 4186 Type::new(Void), 4187 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4)], 4188 ); 4189 declare_function( 4190 state, 4191 "swgl_commitTextureColorRGBA8", 4192 None, 4193 Type::new(Void), 4194 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Vec4)], 4195 ); 4196 declare_function( 4197 state, 4198 "swgl_commitTextureRepeatRGBA8", 4199 None, 4200 Type::new(Void), 4201 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4202 Type::new(Vec4), Type::new(Vec4)], 4203 ); 4204 declare_function( 4205 state, 4206 "swgl_commitTextureRepeatColorRGBA8", 4207 None, 4208 Type::new(Void), 4209 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec2), 4210 Type::new(Vec4), Type::new(Vec4), Type::new(Vec4)], 4211 ); 4212 4213 declare_function( 4214 state, 4215 "swgl_commitGaussianBlurRGBA8", 4216 None, 4217 Type::new(Void), 4218 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool), 4219 Type::new(Int), Type::new(Vec2)], 4220 ); 4221 declare_function( 4222 state, 4223 "swgl_commitGaussianBlurR8", 4224 None, 4225 Type::new(Void), 4226 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), Type::new(Bool), 4227 Type::new(Int), Type::new(Vec2)], 4228 ); 4229 declare_function( 4230 state, 4231 "swgl_commitTextureLinearYUV", 4232 None, 4233 Type::new(Void), 4234 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4235 Type::new(Vec3), Type::new(Mat3), Type::new(Int)], 4236 ); 4237 declare_function( 4238 state, 4239 "swgl_commitTextureLinearYUV", 4240 None, 4241 Type::new(Void), 4242 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4243 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4244 Type::new(Vec3), Type::new(Mat3), Type::new(Int)], 4245 ); 4246 declare_function( 4247 state, 4248 "swgl_commitTextureLinearYUV", 4249 None, 4250 Type::new(Void), 4251 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4252 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4253 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4254 Type::new(Vec3), Type::new(Mat3), Type::new(Int)], 4255 ); 4256 declare_function( 4257 state, 4258 "swgl_commitTextureLinearColorYUV", 4259 None, 4260 Type::new(Void), 4261 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4262 Type::new(Vec3), Type::new(Mat3), Type::new(Int), 4263 Type::new(Float)], 4264 ); 4265 declare_function( 4266 state, 4267 "swgl_commitTextureLinearColorYUV", 4268 None, 4269 Type::new(Void), 4270 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4271 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4272 Type::new(Vec3), Type::new(Mat3), Type::new(Int), 4273 Type::new(Float)], 4274 ); 4275 declare_function( 4276 state, 4277 "swgl_commitTextureLinearColorYUV", 4278 None, 4279 Type::new(Void), 4280 vec![Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4281 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4282 Type::new(*s), Type::new(Vec2), Type::new(Vec4), 4283 Type::new(Vec3), Type::new(Mat3), Type::new(Int), 4284 Type::new(Float)], 4285 ); 4286 } 4287 4288 TranslationUnit(tu.0.map(state, translate_external_declaration)) 4289 } 4290 4291 fn infer_expr_inner(state: &mut State, expr: &Expr, assign: &mut SymRef) -> RunClass { 4292 match expr.kind { 4293 ExprKind::Variable(ref i) => { 4294 *assign = *i; 4295 match &state.sym(*i).decl { 4296 SymDecl::Local(_, _, ref run_class) => *run_class, 4297 SymDecl::Global(_, _, _, ref run_class) => *run_class, 4298 _ => panic!(), 4299 } 4300 } 4301 ExprKind::IntConst(_) 4302 | ExprKind::UIntConst(_) 4303 | ExprKind::BoolConst(_) 4304 | ExprKind::FloatConst(_) 4305 | ExprKind::DoubleConst(_) => RunClass::Scalar, 4306 ExprKind::Unary(_, ref e) => infer_expr(state, e), 4307 ExprKind::Binary(_, ref l, ref r) => infer_expr(state, l).merge(infer_expr(state, r)), 4308 ExprKind::Ternary(ref c, ref s, ref e) => infer_expr(state, c) 4309 .merge(infer_expr(state, s)) 4310 .merge(infer_expr(state, e)), 4311 ExprKind::Assignment(ref v, _, ref e) => { 4312 let mut sym = SymRef(!0); 4313 let run_class = infer_expr_inner(state, v, &mut sym).merge(infer_expr(state, e)); 4314 assert!(sym != SymRef(!0)); 4315 state.merge_run_class(sym, run_class) 4316 } 4317 ExprKind::Bracket(ref e, ref indx) => { 4318 indx.iter().fold( 4319 infer_expr_inner(state, e, assign), 4320 |run_class, indx| run_class.merge(infer_expr(state, indx)), 4321 ) 4322 } 4323 ExprKind::FunCall(ref fun, ref args) => { 4324 let arg_classes: Vec<(RunClass, SymRef)> = args 4325 .iter() 4326 .map(|e| { 4327 let mut assign = SymRef(!0); 4328 let run_class = infer_expr_inner(state, e, &mut assign); 4329 (run_class, assign) 4330 }) 4331 .collect(); 4332 let run_class = if args.is_empty() { 4333 RunClass::Scalar 4334 } else { 4335 arg_classes 4336 .iter() 4337 .fold(RunClass::Unknown, |x, &(y, _)| x.merge(y)) 4338 }; 4339 match fun { 4340 FunIdentifier::Identifier(ref sym) => match &state.sym(*sym).decl { 4341 SymDecl::NativeFunction(_, _, ref ret_class) => { 4342 if *ret_class != RunClass::Unknown { 4343 *ret_class 4344 } else { 4345 run_class 4346 } 4347 } 4348 SymDecl::UserFunction(ref fd, ref run_class) => { 4349 for (&(mut arg_class, assign), param) in 4350 arg_classes.iter().zip(fd.prototype.parameters.iter()) 4351 { 4352 if let FunctionParameterDeclaration::Named(Some(qual), p) = param { 4353 match qual { 4354 ParameterQualifier::InOut | ParameterQualifier::Out => { 4355 if let SymDecl::Local(_, _, param_class) = 4356 &state.sym(p.sym).decl 4357 { 4358 match param_class { 4359 RunClass::Unknown | RunClass::Vector => { 4360 arg_class = RunClass::Vector; 4361 } 4362 RunClass::Dependent(mask) => { 4363 for i in 0 .. 31 { 4364 if (mask & (1 << i)) != 0 { 4365 arg_class = 4366 arg_class.merge(arg_classes[i].0); 4367 } 4368 } 4369 } 4370 RunClass::Scalar => {} 4371 } 4372 } 4373 assert!(assign != SymRef(!0)); 4374 state.merge_run_class(assign, arg_class); 4375 } 4376 _ => {} 4377 } 4378 } 4379 } 4380 if fd.prototype.ty.kind == TypeKind::Void { 4381 RunClass::Scalar 4382 } else { 4383 match *run_class { 4384 RunClass::Unknown | RunClass::Vector => RunClass::Vector, 4385 RunClass::Dependent(mask) => { 4386 let mut ret_class = RunClass::Unknown; 4387 for i in 0 .. 31 { 4388 if (mask & (1 << i)) != 0 { 4389 ret_class = ret_class.merge(arg_classes[i].0); 4390 } 4391 } 4392 ret_class 4393 } 4394 RunClass::Scalar => RunClass::Scalar, 4395 } 4396 } 4397 } 4398 SymDecl::Struct(..) => run_class, 4399 _ => panic!(), 4400 }, 4401 FunIdentifier::Constructor(..) => run_class, 4402 } 4403 } 4404 ExprKind::Dot(ref e, _) => infer_expr_inner(state, e, assign), 4405 ExprKind::SwizzleSelector(ref e, _) => infer_expr_inner(state, e, assign), 4406 ExprKind::PostInc(ref e) => infer_expr_inner(state, e, assign), 4407 ExprKind::PostDec(ref e) => infer_expr_inner(state, e, assign), 4408 ExprKind::Comma(ref a, ref b) => { 4409 infer_expr(state, a); 4410 infer_expr(state, b) 4411 } 4412 ExprKind::Cond(_, ref e) => infer_expr(state, e), 4413 ExprKind::CondMask => RunClass::Vector, 4414 } 4415 } 4416 4417 fn infer_expr(state: &mut State, expr: &Expr) -> RunClass { 4418 infer_expr_inner(state, expr, &mut SymRef(!0)) 4419 } 4420 4421 fn infer_condition(state: &mut State, c: &Condition) { 4422 match *c { 4423 Condition::Expr(ref e) => { 4424 infer_expr(state, e); 4425 } 4426 } 4427 } 4428 4429 fn infer_iteration_statement(state: &mut State, ist: &IterationStatement) { 4430 let changed = state.run_class_changed.replace(true); 4431 match *ist { 4432 IterationStatement::While(ref cond, ref body) => { 4433 while state.run_class_changed.replace(false) { 4434 infer_condition(state, cond); 4435 infer_statement(state, body); 4436 } 4437 } 4438 IterationStatement::DoWhile(ref body, ref cond) => { 4439 while state.run_class_changed.replace(false) { 4440 infer_statement(state, body); 4441 infer_expr(state, cond); 4442 } 4443 } 4444 IterationStatement::For(ref init, ref rest, ref body) => { 4445 match *init { 4446 ForInitStatement::Expression(ref expr) => { 4447 if let Some(ref e) = *expr { 4448 infer_expr(state, e); 4449 } 4450 } 4451 ForInitStatement::Declaration(ref d) => { 4452 infer_declaration(state, d); 4453 } 4454 } 4455 while state.run_class_changed.replace(false) { 4456 if let Some(ref cond) = rest.condition { 4457 infer_condition(state, cond); 4458 } 4459 if let Some(ref e) = rest.post_expr { 4460 infer_expr(state, e); 4461 } 4462 infer_statement(state, body); 4463 } 4464 } 4465 } 4466 state.run_class_changed.set(changed); 4467 } 4468 4469 fn infer_selection_statement(state: &mut State, sst: &SelectionStatement) { 4470 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.cond)); 4471 mem::swap(&mut state.branch_run_class, &mut branch_run_class); 4472 let branch_declaration = state.branch_declaration; 4473 state.branch_declaration = state.last_declaration; 4474 infer_statement(state, &sst.body); 4475 if let Some(ref else_st) = sst.else_stmt { 4476 infer_statement(state, else_st); 4477 } 4478 state.branch_run_class = branch_run_class; 4479 state.branch_declaration = branch_declaration; 4480 } 4481 4482 fn infer_expression_statement(state: &mut State, est: &ExprStatement) { 4483 if let Some(ref e) = *est { 4484 infer_expr(state, e); 4485 } 4486 } 4487 4488 fn infer_switch_statement(state: &mut State, sst: &SwitchStatement) { 4489 let mut branch_run_class = state.branch_run_class.merge(infer_expr(state, &sst.head)); 4490 mem::swap(&mut state.branch_run_class, &mut branch_run_class); 4491 let branch_declaration = state.branch_declaration; 4492 state.branch_declaration = state.last_declaration; 4493 for case in &sst.cases { 4494 for st in &case.stmts { 4495 infer_statement(state, st); 4496 } 4497 } 4498 state.branch_run_class = branch_run_class; 4499 state.branch_declaration = branch_declaration; 4500 } 4501 4502 fn infer_jump_statement(state: &mut State, j: &JumpStatement) { 4503 match *j { 4504 JumpStatement::Continue => {} 4505 JumpStatement::Break => {} 4506 JumpStatement::Discard => {} 4507 JumpStatement::Return(ref e) => { 4508 if let Some(e) = e { 4509 let run_class = infer_expr(state, e); 4510 state.return_run_class(run_class); 4511 } 4512 } 4513 } 4514 } 4515 4516 fn infer_initializer(state: &mut State, i: &Initializer) -> RunClass { 4517 match *i { 4518 Initializer::Simple(ref e) => infer_expr(state, e), 4519 Initializer::List(ref list) => { 4520 let mut run_class = RunClass::Unknown; 4521 for ini in list.0.iter() { 4522 run_class = run_class.merge(infer_initializer(state, ini)); 4523 } 4524 run_class 4525 } 4526 } 4527 } 4528 4529 fn infer_declaration(state: &mut State, d: &Declaration) { 4530 match *d { 4531 Declaration::FunctionPrototype(..) => {} 4532 Declaration::InitDeclaratorList(ref list) => { 4533 state.last_declaration = list.head.name; 4534 4535 let mut run_class = RunClass::Unknown; 4536 for decl in &list.tail { 4537 if let Some(ref initializer) = decl.initializer { 4538 run_class = run_class.merge(infer_initializer(state, initializer)); 4539 } 4540 } 4541 if let Some(ref initializer) = list.head.initializer { 4542 run_class = run_class.merge(infer_initializer(state, initializer)); 4543 state.merge_run_class(list.head.name, run_class); 4544 } 4545 } 4546 Declaration::Precision(..) => {} 4547 Declaration::Block(..) => {} 4548 Declaration::Global(..) => {} 4549 Declaration::StructDefinition(..) => {} 4550 } 4551 } 4552 4553 fn infer_simple_statement(state: &mut State, sst: &SimpleStatement) { 4554 match *sst { 4555 SimpleStatement::Declaration(ref d) => infer_declaration(state, d), 4556 SimpleStatement::Expression(ref e) => infer_expression_statement(state, e), 4557 SimpleStatement::Selection(ref s) => infer_selection_statement(state, s), 4558 SimpleStatement::Switch(ref s) => infer_switch_statement(state, s), 4559 SimpleStatement::Iteration(ref i) => infer_iteration_statement(state, i), 4560 SimpleStatement::Jump(ref j) => infer_jump_statement(state, j), 4561 } 4562 } 4563 4564 fn infer_compound_statement(state: &mut State, cst: &CompoundStatement) { 4565 for st in &cst.statement_list { 4566 infer_statement(state, st); 4567 } 4568 } 4569 4570 fn infer_statement(state: &mut State, st: &Statement) { 4571 match *st { 4572 Statement::Compound(ref cst) => infer_compound_statement(state, cst), 4573 Statement::Simple(ref sst) => infer_simple_statement(state, sst), 4574 } 4575 } 4576 4577 fn infer_function_definition(state: &mut State, fd: &FunctionDefinition) { 4578 state.in_function = Some(state.lookup(fd.prototype.name.as_str()).unwrap()); 4579 4580 state.run_class_changed.set(true); 4581 while state.run_class_changed.replace(false) { 4582 for st in &fd.body.statement_list { 4583 infer_statement(state, st); 4584 } 4585 } 4586 4587 state.in_function = None; 4588 } 4589 4590 fn infer_external_declaration(state: &mut State, ed: &ExternalDeclaration) { 4591 match *ed { 4592 ExternalDeclaration::Preprocessor(_) => {} 4593 ExternalDeclaration::FunctionDefinition(ref fd) => infer_function_definition(state, fd), 4594 ExternalDeclaration::Declaration(_) => {} 4595 } 4596 } 4597 4598 pub fn infer_run_class(state: &mut State, tu: &TranslationUnit) { 4599 for ed in &(tu.0).0 { 4600 infer_external_declaration(state, ed); 4601 } 4602 }