Path: blob/main_old/src/compiler/translator/DirectiveHandler.cpp
1693 views
//1// Copyright 2012 The ANGLE Project Authors. All rights reserved.2// Use of this source code is governed by a BSD-style license that can be3// found in the LICENSE file.4//56#include "compiler/translator/DirectiveHandler.h"78#include <sstream>910#include "angle_gl.h"11#include "common/debug.h"12#include "compiler/translator/Common.h"13#include "compiler/translator/Diagnostics.h"1415namespace sh16{1718static TBehavior getBehavior(const std::string &str)19{20const char kRequire[] = "require";21const char kEnable[] = "enable";22const char kDisable[] = "disable";23const char kWarn[] = "warn";2425if (str == kRequire)26return EBhRequire;27else if (str == kEnable)28return EBhEnable;29else if (str == kDisable)30return EBhDisable;31else if (str == kWarn)32return EBhWarn;33return EBhUndefined;34}3536TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,37TDiagnostics &diagnostics,38int &shaderVersion,39sh::GLenum shaderType)40: mExtensionBehavior(extBehavior),41mDiagnostics(diagnostics),42mShaderVersion(shaderVersion),43mShaderType(shaderType)44{}4546TDirectiveHandler::~TDirectiveHandler() {}4748void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)49{50mDiagnostics.error(loc, msg.c_str(), "");51}5253void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,54const std::string &name,55const std::string &value,56bool stdgl)57{58if (stdgl)59{60const char kInvariant[] = "invariant";61const char kAll[] = "all";6263if (name == kInvariant && value == kAll)64{65if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)66{67// ESSL 3.00.4 section 4.6.168mDiagnostics.error(69loc, "#pragma STDGL invariant(all) can not be used in fragment shader",70name.c_str());71}72mPragma.stdgl.invariantAll = true;73}74// The STDGL pragma is used to reserve pragmas for use by future75// revisions of GLSL. Do not generate an error on unexpected76// name and value.77return;78}79else80{81const char kOptimize[] = "optimize";82const char kDebug[] = "debug";83const char kOn[] = "on";84const char kOff[] = "off";8586bool invalidValue = false;87if (name == kOptimize)88{89if (value == kOn)90mPragma.optimize = true;91else if (value == kOff)92mPragma.optimize = false;93else94invalidValue = true;95}96else if (name == kDebug)97{98if (value == kOn)99mPragma.debug = true;100else if (value == kOff)101mPragma.debug = false;102else103invalidValue = true;104}105else106{107mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);108return;109}110111if (invalidValue)112{113mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());114}115}116}117118void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,119const std::string &name,120const std::string &behavior)121{122const char kExtAll[] = "all";123124TBehavior behaviorVal = getBehavior(behavior);125if (behaviorVal == EBhUndefined)126{127mDiagnostics.error(loc, "behavior invalid", name.c_str());128return;129}130131if (name == kExtAll)132{133if (behaviorVal == EBhRequire)134{135mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());136}137else if (behaviorVal == EBhEnable)138{139mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());140}141else142{143for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();144iter != mExtensionBehavior.end(); ++iter)145iter->second = behaviorVal;146}147return;148}149150TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));151if (iter != mExtensionBehavior.end())152{153iter->second = behaviorVal;154// OVR_multiview is implicitly enabled when OVR_multiview2 is enabled155if (name == "GL_OVR_multiview2")156{157constexpr char kMultiviewExtName[] = "GL_OVR_multiview";158iter = mExtensionBehavior.find(GetExtensionByName(kMultiviewExtName));159if (iter != mExtensionBehavior.end())160{161iter->second = behaviorVal;162}163}164// EXT_shader_io_blocks is implicitly enabled when EXT_geometry_shader or165// EXT_tessellation_shader is enabled.166if (name == "GL_EXT_geometry_shader" || name == "GL_EXT_tessellation_shader")167{168constexpr char kIOBlocksExtName[] = "GL_EXT_shader_io_blocks";169iter = mExtensionBehavior.find(GetExtensionByName(kIOBlocksExtName));170if (iter != mExtensionBehavior.end())171{172iter->second = behaviorVal;173}174}175// GL_APPLE_clip_distance is implicitly enabled when GL_EXT_clip_cull_distance is enabled176else if (name == "GL_EXT_clip_cull_distance")177{178// This extension only can be enabled on greater than ESSL 300179if (mShaderVersion < 300)180{181mDiagnostics.error(loc, "extension can be enabled on greater than ESSL 300",182name.c_str());183return;184}185186constexpr char kAPPLEClipDistanceEXTName[] = "GL_APPLE_clip_distance";187iter = mExtensionBehavior.find(GetExtensionByName(kAPPLEClipDistanceEXTName));188if (iter != mExtensionBehavior.end())189{190iter->second = behaviorVal;191}192}193return;194}195196switch (behaviorVal)197{198case EBhRequire:199mDiagnostics.error(loc, "extension is not supported", name.c_str());200break;201case EBhEnable:202case EBhWarn:203case EBhDisable:204mDiagnostics.warning(loc, "extension is not supported", name.c_str());205break;206default:207UNREACHABLE();208break;209}210}211212void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc,213int version,214ShShaderSpec spec)215{216if (((version == 100 || version == 300 || version == 310 || version == 320) &&217!IsDesktopGLSpec(spec)) ||218IsDesktopGLSpec(spec))219{220mShaderVersion = version;221}222else223{224std::stringstream stream = sh::InitializeStream<std::stringstream>();225stream << version;226std::string str = stream.str();227mDiagnostics.error(loc, "client/version number not supported", str.c_str());228}229}230231} // namespace sh232233234