ForcePrecisionQualifier.cpp (2935B)
1 // 2 // Copyright 2020 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/tree_ops/ForcePrecisionQualifier.h" 8 #include "angle_gl.h" 9 #include "common/debug.h" 10 #include "compiler/translator/Compiler.h" 11 #include "compiler/translator/tree_util/IntermTraverse.h" 12 #include "compiler/translator/util.h" 13 14 namespace sh 15 { 16 17 namespace 18 { 19 class TPrecisionTraverser : public TIntermTraverser 20 { 21 public: 22 TPrecisionTraverser(TSymbolTable *symbolTable); 23 24 protected: 25 bool visitDeclaration(Visit visit, TIntermDeclaration *node) override; 26 27 void overwriteVariablePrecision(TType *type) const; 28 }; 29 30 TPrecisionTraverser::TPrecisionTraverser(TSymbolTable *symbolTable) 31 : TIntermTraverser(true, true, true, symbolTable) 32 {} 33 34 void TPrecisionTraverser::overwriteVariablePrecision(TType *type) const 35 { 36 if (type->getPrecision() == EbpHigh) 37 { 38 type->setPrecision(EbpMedium); 39 } 40 } 41 42 bool TPrecisionTraverser::visitDeclaration(Visit visit, TIntermDeclaration *node) 43 { 44 // Variable declaration. 45 if (visit == PreVisit) 46 { 47 const TIntermSequence &sequence = *(node->getSequence()); 48 TIntermTyped *variable = sequence.front()->getAsTyped(); 49 const TType &type = variable->getType(); 50 TQualifier qualifier = variable->getQualifier(); 51 52 // Don't modify uniform since it might be shared between vertex and fragment shader 53 if (qualifier == EvqUniform) 54 { 55 return true; 56 } 57 58 // Visit the struct. 59 if (type.isStructSpecifier()) 60 { 61 const TStructure *structure = type.getStruct(); 62 const TFieldList &fields = structure->fields(); 63 for (size_t i = 0; i < fields.size(); ++i) 64 { 65 const TField *field = fields[i]; 66 const TType *fieldType = field->type(); 67 overwriteVariablePrecision((TType *)fieldType); 68 } 69 } 70 else if (type.getBasicType() == EbtInterfaceBlock) 71 { 72 const TInterfaceBlock *interfaceBlock = type.getInterfaceBlock(); 73 const TFieldList &fields = interfaceBlock->fields(); 74 for (const TField *field : fields) 75 { 76 const TType *fieldType = field->type(); 77 overwriteVariablePrecision((TType *)fieldType); 78 } 79 } 80 else 81 { 82 overwriteVariablePrecision((TType *)&type); 83 } 84 } 85 return true; 86 } 87 } // namespace 88 89 bool ForceShaderPrecisionToMediump(TIntermNode *root, TSymbolTable *symbolTable, GLenum shaderType) 90 { 91 if (shaderType != GL_FRAGMENT_SHADER) 92 { 93 return true; 94 } 95 96 TPrecisionTraverser traverser(symbolTable); 97 root->traverse(&traverser); 98 return true; 99 } 100 101 } // namespace sh