Edit

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

Branch :

  • Show log

    Commit

  • Author : Shahbaz Youssefi
    Date : 2021-07-30 16:51:45
    Hash : 1ce78397
    Message : Remove support for WEBGL_debug_shader_precision This extension was rejected, and the implementation was hacky. This clean up is part of an ongoing work to improve precision handling. Bug: angleproject:6059 Change-Id: If08581ec6f19cf1698ffa3dd6d248dc5e68a1d31 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/3064303 Reviewed-by: Kenneth Russell <kbr@chromium.org> Commit-Queue: Shahbaz Youssefi <syoussefi@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)
        : mExtensionBehavior(extBehavior),
          mDiagnostics(diagnostics),
          mShaderVersion(shaderVersion),
          mShaderType(shaderType)
    {}
    
    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 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
            {
                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")
            {
                constexpr char kMultiviewExtName[] = "GL_OVR_multiview";
                iter = mExtensionBehavior.find(GetExtensionByName(kMultiviewExtName));
                if (iter != mExtensionBehavior.end())
                {
                    iter->second = behaviorVal;
                }
            }
            // EXT_shader_io_blocks is implicitly enabled when EXT_geometry_shader or
            // EXT_tessellation_shader is enabled.
            if (name == "GL_EXT_geometry_shader" || name == "GL_EXT_tessellation_shader")
            {
                constexpr char kIOBlocksExtName[] = "GL_EXT_shader_io_blocks";
                iter = mExtensionBehavior.find(GetExtensionByName(kIOBlocksExtName));
                if (iter != mExtensionBehavior.end())
                {
                    iter->second = behaviorVal;
                }
            }
            // GL_APPLE_clip_distance is implicitly enabled when GL_EXT_clip_cull_distance is enabled
            else if (name == "GL_EXT_clip_cull_distance")
            {
                // This extension only can be enabled on greater than ESSL 300
                if (mShaderVersion < 300)
                {
                    mDiagnostics.error(loc, "extension can be enabled on greater than ESSL 300",
                                       name.c_str());
                    return;
                }
    
                constexpr char kAPPLEClipDistanceEXTName[] = "GL_APPLE_clip_distance";
                iter = mExtensionBehavior.find(GetExtensionByName(kAPPLEClipDistanceEXTName));
                if (iter != mExtensionBehavior.end())
                {
                    iter->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 || version == 320) &&
             !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