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