tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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