Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / angle / src / compiler / translator / VersionGLSL.cpp
1 //
2 // Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #include "compiler/translator/VersionGLSL.h"
8
9 static const int GLSL_VERSION_110 = 110;
10 static const int GLSL_VERSION_120 = 120;
11
12 // We need to scan for the following:
13 // 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
14 //    but only at the global scope.
15 // 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
16 //    but inside any scope.
17 // 3. Call to a matrix constructor with another matrix as argument.
18 //    (These constructors were reserved in GLSL version 1.10.)
19 // 4. Arrays as "out" function parameters.
20 //    GLSL spec section 6.1.1: "When calling a function, expressions that do
21 //    not evaluate to l-values cannot be passed to parameters declared as
22 //    out or inout."
23 //    GLSL 1.1 section 5.8: "Other binary or unary expressions,
24 //    non-dereferenced arrays, function names, swizzles with repeated fields,
25 //    and constants cannot be l-values."
26 //    GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
27 //    are built-in types, entire structures or arrays... are all l-values."
28 //
29 // TODO(alokp): The following two cases of invariant decalaration get lost
30 // during parsing - they do not get carried over to the intermediate tree.
31 // Handle these cases:
32 // 1. When a pragma is used to force all output variables to be invariant:
33 //    - #pragma STDGL invariant(all)
34 // 2. When a previously decalared or built-in variable is marked invariant:
35 //    - invariant gl_Position;
36 //    - varying vec3 color; invariant color;
37 //
38 TVersionGLSL::TVersionGLSL(sh::GLenum type)
39     : mVersion(GLSL_VERSION_110)
40 {
41 }
42
43 void TVersionGLSL::visitSymbol(TIntermSymbol *node)
44 {
45     if (node->getSymbol() == "gl_PointCoord")
46         updateVersion(GLSL_VERSION_120);
47 }
48
49 bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
50 {
51     bool visitChildren = true;
52
53     switch (node->getOp())
54     {
55       case EOpSequence:
56         // We need to visit sequence children to get to global or inner scope.
57         visitChildren = true;
58         break;
59       case EOpDeclaration:
60         {
61             const TIntermSequence &sequence = *(node->getSequence());
62             TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
63             if ((qualifier == EvqInvariantVaryingIn) ||
64                 (qualifier == EvqInvariantVaryingOut))
65             {
66                 updateVersion(GLSL_VERSION_120);
67             }
68             break;
69         }
70       case EOpParameters:
71         {
72             const TIntermSequence &params = *(node->getSequence());
73             for (TIntermSequence::const_iterator iter = params.begin();
74                  iter != params.end(); ++iter)
75             {
76                 const TIntermTyped *param = (*iter)->getAsTyped();
77                 if (param->isArray())
78                 {
79                     TQualifier qualifier = param->getQualifier();
80                     if ((qualifier == EvqOut) || (qualifier ==  EvqInOut))
81                     {
82                         updateVersion(GLSL_VERSION_120);
83                         break;
84                     }
85                 }
86             }
87             // Fully processed. No need to visit children.
88             visitChildren = false;
89             break;
90         }
91       case EOpConstructMat2:
92       case EOpConstructMat3:
93       case EOpConstructMat4:
94         {
95             const TIntermSequence &sequence = *(node->getSequence());
96             if (sequence.size() == 1)
97             {
98                 TIntermTyped *typed = sequence.front()->getAsTyped();
99                 if (typed && typed->isMatrix())
100                 {
101                     updateVersion(GLSL_VERSION_120);
102                 }
103             }
104             break;
105         }
106       default:
107         break;
108     }
109
110     return visitChildren;
111 }
112
113 void TVersionGLSL::updateVersion(int version)
114 {
115     mVersion = std::max(version, mVersion);
116 }
117