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