Line data Source code
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 : #include "angle_gl.h"
10 :
11 : namespace sh
12 : {
13 :
14 0 : int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
15 : {
16 0 : switch (output)
17 : {
18 0 : case SH_GLSL_130_OUTPUT: return GLSL_VERSION_130;
19 0 : case SH_GLSL_140_OUTPUT: return GLSL_VERSION_140;
20 0 : case SH_GLSL_150_CORE_OUTPUT: return GLSL_VERSION_150;
21 0 : case SH_GLSL_330_CORE_OUTPUT: return GLSL_VERSION_330;
22 0 : case SH_GLSL_400_CORE_OUTPUT: return GLSL_VERSION_400;
23 0 : case SH_GLSL_410_CORE_OUTPUT: return GLSL_VERSION_410;
24 0 : case SH_GLSL_420_CORE_OUTPUT: return GLSL_VERSION_420;
25 0 : case SH_GLSL_430_CORE_OUTPUT: return GLSL_VERSION_430;
26 0 : case SH_GLSL_440_CORE_OUTPUT: return GLSL_VERSION_440;
27 0 : case SH_GLSL_450_CORE_OUTPUT: return GLSL_VERSION_450;
28 0 : case SH_GLSL_COMPATIBILITY_OUTPUT: return GLSL_VERSION_110;
29 0 : default: UNREACHABLE(); return 0;
30 : }
31 : }
32 :
33 : // We need to scan for the following:
34 : // 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
35 : // but only at the global scope.
36 : // 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
37 : // but inside any scope.
38 : // 3. Call to a matrix constructor with another matrix as argument.
39 : // (These constructors were reserved in GLSL version 1.10.)
40 : // 4. Arrays as "out" function parameters.
41 : // GLSL spec section 6.1.1: "When calling a function, expressions that do
42 : // not evaluate to l-values cannot be passed to parameters declared as
43 : // out or inout."
44 : // GLSL 1.1 section 5.8: "Other binary or unary expressions,
45 : // non-dereferenced arrays, function names, swizzles with repeated fields,
46 : // and constants cannot be l-values."
47 : // GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
48 : // are built-in types, entire structures or arrays... are all l-values."
49 : //
50 0 : TVersionGLSL::TVersionGLSL(sh::GLenum type,
51 : const TPragma &pragma,
52 0 : ShShaderOutput output)
53 0 : : TIntermTraverser(true, false, false)
54 : {
55 0 : mVersion = ShaderOutputTypeToGLSLVersion(output);
56 0 : if (pragma.stdgl.invariantAll)
57 : {
58 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
59 : }
60 0 : if (type == GL_COMPUTE_SHADER)
61 : {
62 0 : ensureVersionIsAtLeast(GLSL_VERSION_430);
63 : }
64 0 : }
65 :
66 0 : void TVersionGLSL::visitSymbol(TIntermSymbol *node)
67 : {
68 0 : if (node->getSymbol() == "gl_PointCoord")
69 : {
70 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
71 : }
72 0 : }
73 :
74 0 : bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
75 : {
76 0 : const TIntermSequence &sequence = *(node->getSequence());
77 0 : if (sequence.front()->getAsTyped()->getType().isInvariant())
78 : {
79 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
80 : }
81 0 : return true;
82 : }
83 :
84 0 : bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
85 : {
86 0 : bool visitChildren = true;
87 :
88 0 : switch (node->getOp())
89 : {
90 : case EOpInvariantDeclaration:
91 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
92 0 : break;
93 : case EOpParameters:
94 : {
95 0 : const TIntermSequence ¶ms = *(node->getSequence());
96 0 : for (TIntermSequence::const_iterator iter = params.begin();
97 0 : iter != params.end(); ++iter)
98 : {
99 0 : const TIntermTyped *param = (*iter)->getAsTyped();
100 0 : if (param->isArray())
101 : {
102 0 : TQualifier qualifier = param->getQualifier();
103 0 : if ((qualifier == EvqOut) || (qualifier == EvqInOut))
104 : {
105 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
106 0 : break;
107 : }
108 : }
109 : }
110 : // Fully processed. No need to visit children.
111 0 : visitChildren = false;
112 0 : break;
113 : }
114 : case EOpConstructMat2:
115 : case EOpConstructMat2x3:
116 : case EOpConstructMat2x4:
117 : case EOpConstructMat3x2:
118 : case EOpConstructMat3:
119 : case EOpConstructMat3x4:
120 : case EOpConstructMat4x2:
121 : case EOpConstructMat4x3:
122 : case EOpConstructMat4:
123 : {
124 0 : const TIntermSequence &sequence = *(node->getSequence());
125 0 : if (sequence.size() == 1)
126 : {
127 0 : TIntermTyped *typed = sequence.front()->getAsTyped();
128 0 : if (typed && typed->isMatrix())
129 : {
130 0 : ensureVersionIsAtLeast(GLSL_VERSION_120);
131 : }
132 : }
133 0 : break;
134 : }
135 : default:
136 0 : break;
137 : }
138 :
139 0 : return visitChildren;
140 : }
141 :
142 0 : void TVersionGLSL::ensureVersionIsAtLeast(int version)
143 : {
144 0 : mVersion = std::max(version, mVersion);
145 0 : }
146 :
147 : } // namespace sh
|