blob: f6f568897d12f26b6731c60c1c342fd6dab8c174 [file] [log] [blame]
alokp@chromium.org9ecf3952010-10-13 19:28:25 +00001//
alokp@chromium.org8d47c112012-09-06 16:03:23 +00002// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org9ecf3952010-10-13 19:28:25 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/VersionGLSL.h"
alokp@chromium.org9ecf3952010-10-13 19:28:25 +00008
9static const int GLSL_VERSION_110 = 110;
10static const int GLSL_VERSION_120 = 120;
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080011static const int GLSL_VERSION_150 = 150;
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000012
alokp@chromium.org8d47c112012-09-06 16:03:23 +000013// We need to scan for the following:
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000014// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
15// but only at the global scope.
16// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
17// but inside any scope.
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +000018// 3. Call to a matrix constructor with another matrix as argument.
19// (These constructors were reserved in GLSL version 1.10.)
alokp@chromium.org8d47c112012-09-06 16:03:23 +000020// 4. Arrays as "out" function parameters.
21// GLSL spec section 6.1.1: "When calling a function, expressions that do
22// not evaluate to l-values cannot be passed to parameters declared as
23// out or inout."
24// GLSL 1.1 section 5.8: "Other binary or unary expressions,
25// non-dereferenced arrays, function names, swizzles with repeated fields,
26// and constants cannot be l-values."
27// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
28// are built-in types, entire structures or arrays... are all l-values."
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000029//
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080030TVersionGLSL::TVersionGLSL(sh::GLenum type,
31 const TPragma &pragma,
32 ShShaderOutput output)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000033{
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080034 if (output == SH_GLSL_CORE_OUTPUT)
35 {
36 mVersion = GLSL_VERSION_150;
37 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070038 else
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080039 {
40 ASSERT(output == SH_GLSL_COMPATIBILITY_OUTPUT);
41 if (pragma.stdgl.invariantAll)
42 mVersion = GLSL_VERSION_120;
43 else
44 mVersion = GLSL_VERSION_110;
45 }
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000046}
47
Zhenyao Moe40d1e92014-07-16 17:40:36 -070048void TVersionGLSL::visitSymbol(TIntermSymbol *node)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000049{
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000050 if (node->getSymbol() == "gl_PointCoord")
51 updateVersion(GLSL_VERSION_120);
52}
53
Zhenyao Moe40d1e92014-07-16 17:40:36 -070054bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000055{
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +000056 bool visitChildren = true;
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000057
Zhenyao Moe40d1e92014-07-16 17:40:36 -070058 switch (node->getOp())
59 {
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000060 case EOpSequence:
61 // We need to visit sequence children to get to global or inner scope.
62 visitChildren = true;
63 break;
Zhenyao Moe40d1e92014-07-16 17:40:36 -070064 case EOpDeclaration:
alokp@chromium.org8d47c112012-09-06 16:03:23 +000065 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070066 const TIntermSequence &sequence = *(node->getSequence());
67 TQualifier qualifier = sequence.front()->getAsTyped()->getQualifier();
68 if ((qualifier == EvqInvariantVaryingIn) ||
69 (qualifier == EvqInvariantVaryingOut))
alokp@chromium.org8d47c112012-09-06 16:03:23 +000070 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070071 updateVersion(GLSL_VERSION_120);
72 }
73 break;
74 }
Jamie Madill3b5c2da2014-08-19 15:23:32 -040075 case EOpInvariantDeclaration:
76 updateVersion(GLSL_VERSION_120);
77 break;
Zhenyao Moe40d1e92014-07-16 17:40:36 -070078 case EOpParameters:
79 {
80 const TIntermSequence &params = *(node->getSequence());
81 for (TIntermSequence::const_iterator iter = params.begin();
82 iter != params.end(); ++iter)
83 {
84 const TIntermTyped *param = (*iter)->getAsTyped();
85 if (param->isArray())
alokp@chromium.org8d47c112012-09-06 16:03:23 +000086 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070087 TQualifier qualifier = param->getQualifier();
88 if ((qualifier == EvqOut) || (qualifier == EvqInOut))
89 {
90 updateVersion(GLSL_VERSION_120);
91 break;
92 }
alokp@chromium.org8d47c112012-09-06 16:03:23 +000093 }
94 }
Zhenyao Moe40d1e92014-07-16 17:40:36 -070095 // Fully processed. No need to visit children.
96 visitChildren = false;
97 break;
alokp@chromium.org8d47c112012-09-06 16:03:23 +000098 }
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +000099 case EOpConstructMat2:
100 case EOpConstructMat3:
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700101 case EOpConstructMat4:
102 {
103 const TIntermSequence &sequence = *(node->getSequence());
104 if (sequence.size() == 1)
105 {
106 TIntermTyped *typed = sequence.front()->getAsTyped();
107 if (typed && typed->isMatrix())
108 {
109 updateVersion(GLSL_VERSION_120);
110 }
111 }
112 break;
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000113 }
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700114 default:
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000115 break;
alokp@chromium.org9ecf3952010-10-13 19:28:25 +0000116 }
117
118 return visitChildren;
119}
120
alokp@chromium.org9ecf3952010-10-13 19:28:25 +0000121void TVersionGLSL::updateVersion(int version)
122{
123 mVersion = std::max(version, mVersion);
124}
125