1 : //
2 : // Copyright (c) 2002-2010 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/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 three things:
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 : //
20 : // If it weren't for (3) then we would only need to scan the global
21 : // scope of the vertex shader. However, we need to scan the entire
22 : // shader in both cases.
23 : //
24 : // TODO(alokp): The following two cases of invariant decalaration get lost
25 : // during parsing - they do not get carried over to the intermediate tree.
26 : // Handle these cases:
27 : // 1. When a pragma is used to force all output variables to be invariant:
28 : // - #pragma STDGL invariant(all)
29 : // 2. When a previously decalared or built-in variable is marked invariant:
30 : // - invariant gl_Position;
31 : // - varying vec3 color; invariant color;
32 : //
33 0 : TVersionGLSL::TVersionGLSL(ShShaderType type)
34 : : mShaderType(type),
35 0 : mVersion(GLSL_VERSION_110)
36 : {
37 0 : }
38 :
39 0 : void TVersionGLSL::visitSymbol(TIntermSymbol* node)
40 : {
41 0 : if (node->getSymbol() == "gl_PointCoord")
42 0 : updateVersion(GLSL_VERSION_120);
43 0 : }
44 :
45 0 : void TVersionGLSL::visitConstantUnion(TIntermConstantUnion*)
46 : {
47 0 : }
48 :
49 0 : bool TVersionGLSL::visitBinary(Visit, TIntermBinary*)
50 : {
51 0 : return true;
52 : }
53 :
54 0 : bool TVersionGLSL::visitUnary(Visit, TIntermUnary*)
55 : {
56 0 : return true;
57 : }
58 :
59 0 : bool TVersionGLSL::visitSelection(Visit, TIntermSelection*)
60 : {
61 0 : return true;
62 : }
63 :
64 0 : bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate* node)
65 : {
66 0 : bool visitChildren = true;
67 :
68 0 : switch (node->getOp()) {
69 : case EOpSequence:
70 : // We need to visit sequence children to get to global or inner scope.
71 0 : visitChildren = true;
72 0 : break;
73 : case EOpDeclaration: {
74 0 : const TIntermSequence& sequence = node->getSequence();
75 0 : TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
76 0 : if ((qualifier == EvqInvariantVaryingIn) ||
77 : (qualifier == EvqInvariantVaryingOut)) {
78 0 : updateVersion(GLSL_VERSION_120);
79 : }
80 0 : break;
81 : }
82 : case EOpConstructMat2:
83 : case EOpConstructMat3:
84 : case EOpConstructMat4: {
85 0 : const TIntermSequence& sequence = node->getSequence();
86 0 : if (sequence.size() == 1) {
87 0 : TIntermTyped* typed = sequence.front()->getAsTyped();
88 0 : if (typed && typed->isMatrix()) {
89 0 : updateVersion(GLSL_VERSION_120);
90 : }
91 : }
92 0 : break;
93 : }
94 :
95 0 : default: break;
96 : }
97 :
98 0 : return visitChildren;
99 : }
100 :
101 0 : bool TVersionGLSL::visitLoop(Visit, TIntermLoop*)
102 : {
103 0 : return true;
104 : }
105 :
106 0 : bool TVersionGLSL::visitBranch(Visit, TIntermBranch*)
107 : {
108 0 : return true;
109 : }
110 :
111 0 : void TVersionGLSL::updateVersion(int version)
112 : {
113 0 : mVersion = std::max(version, mVersion);
114 0 : }
115 :
|