Edit

kc3-lang/angle/src/compiler/translator/DirectiveHandler.cpp

Branch :

  • Show log

    Commit

  • Author : Clemen Deng
    Date : 2019-08-13 10:33:36
    Hash : 1d742ce8
    Message : Deleted unnecessary built-in conditions A few built-in variables are checking against overly complicated extension conditions, deleting these will make the array lookup easier to implement. Also changed functionality to always enable GL_OVR_multiview when GL_OVR_multiview2 is enabled Bug: angleproject:3805 Change-Id: I10fc7db0fa8b496fbba8b2c27a7311ac3c24dbe4 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1752082 Commit-Queue: Clemen Deng <clemendeng@google.com> Reviewed-by: Geoff Lang <geofflang@chromium.org>

  • src/compiler/translator/DirectiveHandler.cpp
  • //
    // Copyright 2012 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    #include "compiler/translator/DirectiveHandler.h"
    
    #include <sstream>
    
    #include "angle_gl.h"
    #include "common/debug.h"
    #include "compiler/translator/Common.h"
    #include "compiler/translator/Diagnostics.h"
    
    namespace sh
    {
    
    static TBehavior getBehavior(const std::string &str)
    {
        const char kRequire[] = "require";
        const char kEnable[]  = "enable";
        const char kDisable[] = "disable";
        const char kWarn[]    = "warn";
    
        if (str == kRequire)
            return EBhRequire;
        else if (str == kEnable)
            return EBhEnable;
        else if (str == kDisable)
            return EBhDisable;
        else if (str == kWarn)
            return EBhWarn;
        return EBhUndefined;
    }
    
    TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
                                         TDiagnostics &diagnostics,
                                         int &shaderVersion,
                                         sh::GLenum shaderType,
                                         bool debugShaderPrecisionSupported)
        : mExtensionBehavior(extBehavior),
          mDiagnostics(diagnostics),
          mShaderVersion(shaderVersion),
          mShaderType(shaderType),
          mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
    {}
    
    TDirectiveHandler::~TDirectiveHandler() {}
    
    void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
    {
        mDiagnostics.error(loc, msg.c_str(), "");
    }
    
    void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
                                         const std::string &name,
                                         const std::string &value,
                                         bool stdgl)
    {
        if (stdgl)
        {
            const char kInvariant[] = "invariant";
            const char kAll[]       = "all";
    
            if (name == kInvariant && value == kAll)
            {
                if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
                {
                    // ESSL 3.00.4 section 4.6.1
                    mDiagnostics.error(
                        loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
                        name.c_str());
                }
                mPragma.stdgl.invariantAll = true;
            }
            // The STDGL pragma is used to reserve pragmas for use by future
            // revisions of GLSL.  Do not generate an error on unexpected
            // name and value.
            return;
        }
        else
        {
            const char kOptimize[]             = "optimize";
            const char kDebug[]                = "debug";
            const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
            const char kOn[]                   = "on";
            const char kOff[]                  = "off";
    
            bool invalidValue = false;
            if (name == kOptimize)
            {
                if (value == kOn)
                    mPragma.optimize = true;
                else if (value == kOff)
                    mPragma.optimize = false;
                else
                    invalidValue = true;
            }
            else if (name == kDebug)
            {
                if (value == kOn)
                    mPragma.debug = true;
                else if (value == kOff)
                    mPragma.debug = false;
                else
                    invalidValue = true;
            }
            else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
            {
                if (value == kOn)
                    mPragma.debugShaderPrecision = true;
                else if (value == kOff)
                    mPragma.debugShaderPrecision = false;
                else
                    invalidValue = true;
            }
            else
            {
                mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
                return;
            }
    
            if (invalidValue)
            {
                mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
            }
        }
    }
    
    void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
                                            const std::string &name,
                                            const std::string &behavior)
    {
        const char kExtAll[] = "all";
    
        TBehavior behaviorVal = getBehavior(behavior);
        if (behaviorVal == EBhUndefined)
        {
            mDiagnostics.error(loc, "behavior invalid", name.c_str());
            return;
        }
    
        if (name == kExtAll)
        {
            if (behaviorVal == EBhRequire)
            {
                mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
            }
            else if (behaviorVal == EBhEnable)
            {
                mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
            }
            else
            {
                for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
                     iter != mExtensionBehavior.end(); ++iter)
                    iter->second = behaviorVal;
            }
            return;
        }
    
        TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
        if (iter != mExtensionBehavior.end())
        {
            iter->second = behaviorVal;
            // OVR_multiview is implicitly enabled when OVR_multiview2 is enabled
            if (name == "GL_OVR_multiview2")
            {
                const std::string multiview = "GL_OVR_multiview";
                TExtensionBehavior::iterator iterMultiview =
                    mExtensionBehavior.find(GetExtensionByName(multiview.c_str()));
                if (iterMultiview != mExtensionBehavior.end())
                {
                    iterMultiview->second = behaviorVal;
                }
            }
            return;
        }
    
        switch (behaviorVal)
        {
            case EBhRequire:
                mDiagnostics.error(loc, "extension is not supported", name.c_str());
                break;
            case EBhEnable:
            case EBhWarn:
            case EBhDisable:
                mDiagnostics.warning(loc, "extension is not supported", name.c_str());
                break;
            default:
                UNREACHABLE();
                break;
        }
    }
    
    void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,
                                          int version,
                                          ShShaderSpec spec)
    {
        if (((version == 100 || version == 300 || version == 310) && !IsDesktopGLSpec(spec)) ||
            IsDesktopGLSpec(spec))
        {
            mShaderVersion = version;
        }
        else
        {
            std::stringstream stream = sh::InitializeStream<std::stringstream>();
            stream << version;
            std::string str = stream.str();
            mDiagnostics.error(loc, "client/version number not supported", str.c_str());
        }
    }
    
    }  // namespace sh