tor-browser

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

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