blob: 9e593ac761056d3d01e352f73708dff9563506e3 [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
Jamie Madill45bcc782016-11-07 13:58:48 -05009namespace sh
10{
11
Geoff Lang7b9b2842015-06-15 11:02:49 -070012int ShaderOutputTypeToGLSLVersion(ShShaderOutput output)
13{
14 switch (output)
15 {
16 case SH_GLSL_130_OUTPUT: return GLSL_VERSION_130;
Geoff Lang8273e002015-06-15 13:40:19 -070017 case SH_GLSL_140_OUTPUT: return GLSL_VERSION_140;
18 case SH_GLSL_150_CORE_OUTPUT: return GLSL_VERSION_150;
19 case SH_GLSL_330_CORE_OUTPUT: return GLSL_VERSION_330;
20 case SH_GLSL_400_CORE_OUTPUT: return GLSL_VERSION_400;
Geoff Lang7b9b2842015-06-15 11:02:49 -070021 case SH_GLSL_410_CORE_OUTPUT: return GLSL_VERSION_410;
22 case SH_GLSL_420_CORE_OUTPUT: return GLSL_VERSION_420;
Geoff Lang8273e002015-06-15 13:40:19 -070023 case SH_GLSL_430_CORE_OUTPUT: return GLSL_VERSION_430;
24 case SH_GLSL_440_CORE_OUTPUT: return GLSL_VERSION_440;
25 case SH_GLSL_450_CORE_OUTPUT: return GLSL_VERSION_450;
Geoff Lang7b9b2842015-06-15 11:02:49 -070026 case SH_GLSL_COMPATIBILITY_OUTPUT: return GLSL_VERSION_110;
27 default: UNREACHABLE(); return 0;
28 }
29}
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000030
alokp@chromium.org8d47c112012-09-06 16:03:23 +000031// We need to scan for the following:
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000032// 1. "invariant" keyword: This can occur in both - vertex and fragment shaders
33// but only at the global scope.
34// 2. "gl_PointCoord" built-in variable: This can only occur in fragment shader
35// but inside any scope.
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +000036// 3. Call to a matrix constructor with another matrix as argument.
37// (These constructors were reserved in GLSL version 1.10.)
alokp@chromium.org8d47c112012-09-06 16:03:23 +000038// 4. Arrays as "out" function parameters.
39// GLSL spec section 6.1.1: "When calling a function, expressions that do
40// not evaluate to l-values cannot be passed to parameters declared as
41// out or inout."
42// GLSL 1.1 section 5.8: "Other binary or unary expressions,
43// non-dereferenced arrays, function names, swizzles with repeated fields,
44// and constants cannot be l-values."
45// GLSL 1.2 relaxed the restriction on arrays, section 5.8: "Variables that
46// are built-in types, entire structures or arrays... are all l-values."
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000047//
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080048TVersionGLSL::TVersionGLSL(sh::GLenum type,
49 const TPragma &pragma,
50 ShShaderOutput output)
Olli Etuaho3d0d9a42015-06-01 12:16:36 +030051 : TIntermTraverser(true, false, false)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000052{
Geoff Lang7b9b2842015-06-15 11:02:49 -070053 mVersion = ShaderOutputTypeToGLSLVersion(output);
54 if (pragma.stdgl.invariantAll)
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080055 {
Geoff Lang7b9b2842015-06-15 11:02:49 -070056 ensureVersionIsAtLeast(GLSL_VERSION_120);
Zhenyao Mo05b6b7f2015-03-02 17:08:09 -080057 }
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000058}
59
Zhenyao Moe40d1e92014-07-16 17:40:36 -070060void TVersionGLSL::visitSymbol(TIntermSymbol *node)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000061{
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000062 if (node->getSymbol() == "gl_PointCoord")
Geoff Lang7b9b2842015-06-15 11:02:49 -070063 {
64 ensureVersionIsAtLeast(GLSL_VERSION_120);
65 }
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000066}
67
Olli Etuaho13389b62016-10-16 11:48:18 +010068bool TVersionGLSL::visitDeclaration(Visit, TIntermDeclaration *node)
69{
70 const TIntermSequence &sequence = *(node->getSequence());
71 if (sequence.front()->getAsTyped()->getType().isInvariant())
72 {
73 ensureVersionIsAtLeast(GLSL_VERSION_120);
74 }
75 return true;
76}
77
Zhenyao Moe40d1e92014-07-16 17:40:36 -070078bool TVersionGLSL::visitAggregate(Visit, TIntermAggregate *node)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000079{
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +000080 bool visitChildren = true;
alokp@chromium.org9ecf3952010-10-13 19:28:25 +000081
Zhenyao Moe40d1e92014-07-16 17:40:36 -070082 switch (node->getOp())
83 {
Jamie Madill3b5c2da2014-08-19 15:23:32 -040084 case EOpInvariantDeclaration:
Geoff Lang7b9b2842015-06-15 11:02:49 -070085 ensureVersionIsAtLeast(GLSL_VERSION_120);
Jamie Madill3b5c2da2014-08-19 15:23:32 -040086 break;
Zhenyao Moe40d1e92014-07-16 17:40:36 -070087 case EOpParameters:
88 {
89 const TIntermSequence &params = *(node->getSequence());
90 for (TIntermSequence::const_iterator iter = params.begin();
91 iter != params.end(); ++iter)
92 {
93 const TIntermTyped *param = (*iter)->getAsTyped();
94 if (param->isArray())
alokp@chromium.org8d47c112012-09-06 16:03:23 +000095 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070096 TQualifier qualifier = param->getQualifier();
97 if ((qualifier == EvqOut) || (qualifier == EvqInOut))
98 {
Geoff Lang7b9b2842015-06-15 11:02:49 -070099 ensureVersionIsAtLeast(GLSL_VERSION_120);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700100 break;
101 }
alokp@chromium.org8d47c112012-09-06 16:03:23 +0000102 }
103 }
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700104 // Fully processed. No need to visit children.
105 visitChildren = false;
106 break;
alokp@chromium.org8d47c112012-09-06 16:03:23 +0000107 }
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000108 case EOpConstructMat2:
Alexis Hetu07e57df2015-06-16 16:55:52 -0400109 case EOpConstructMat2x3:
110 case EOpConstructMat2x4:
111 case EOpConstructMat3x2:
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000112 case EOpConstructMat3:
Alexis Hetu07e57df2015-06-16 16:55:52 -0400113 case EOpConstructMat3x4:
114 case EOpConstructMat4x2:
115 case EOpConstructMat4x3:
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700116 case EOpConstructMat4:
117 {
118 const TIntermSequence &sequence = *(node->getSequence());
119 if (sequence.size() == 1)
120 {
121 TIntermTyped *typed = sequence.front()->getAsTyped();
122 if (typed && typed->isMatrix())
123 {
Geoff Lang7b9b2842015-06-15 11:02:49 -0700124 ensureVersionIsAtLeast(GLSL_VERSION_120);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700125 }
126 }
127 break;
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000128 }
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700129 default:
kbr@chromium.orge26cb5e2011-01-18 21:27:02 +0000130 break;
alokp@chromium.org9ecf3952010-10-13 19:28:25 +0000131 }
132
133 return visitChildren;
134}
135
Geoff Lang7b9b2842015-06-15 11:02:49 -0700136void TVersionGLSL::ensureVersionIsAtLeast(int version)
alokp@chromium.org9ecf3952010-10-13 19:28:25 +0000137{
138 mVersion = std::max(version, mVersion);
139}
140
Jamie Madill45bcc782016-11-07 13:58:48 -0500141} // namespace sh