diff options
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp')
-rw-r--r-- | gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp | 304 |
1 files changed, 304 insertions, 0 deletions
diff --git a/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp new file mode 100644 index 0000000000..80b238e055 --- /dev/null +++ b/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp @@ -0,0 +1,304 @@ +// +// 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; + } + } + // All the extensions listed in the spec here: + // https://www.khronos.org/registry/OpenGL/extensions/ANDROID/ANDROID_extension_pack_es31a.txt + // are implicitly enabled when GL_ANDROID_extension_pack_es31a is enabled + if (name == "GL_ANDROID_extension_pack_es31a") + { + constexpr char kGeometryShaderExtName[] = "GL_EXT_geometry_shader"; + constexpr char kTessellationShaderExtName[] = "GL_EXT_tessellation_shader"; + constexpr char kGpuShader5ExtName[] = "GL_EXT_gpu_shader5"; + constexpr char kTextureBufferExtName[] = "GL_EXT_texture_buffer"; + constexpr char kTextureCubeMapArrayExtName[] = "GL_EXT_texture_cube_map_array"; + constexpr char kSampleVariablesExtName[] = "GL_OES_sample_variables"; + constexpr char kShaderMultisampleInterpolationExtName[] = + "GL_OES_shader_multisample_interpolation"; + constexpr char kShaderImageAtomicExtName[] = "GL_OES_shader_image_atomic"; + constexpr char kTextureStorageMultisample2dArrayExtName[] = + "GL_OES_texture_storage_multisample_2d_array"; + iter = mExtensionBehavior.find(GetExtensionByName(kGeometryShaderExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kTessellationShaderExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kGpuShader5ExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kTextureBufferExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kTextureCubeMapArrayExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kSampleVariablesExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = + mExtensionBehavior.find(GetExtensionByName(kShaderMultisampleInterpolationExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find(GetExtensionByName(kShaderImageAtomicExtName)); + if (iter != mExtensionBehavior.end()) + { + iter->second = behaviorVal; + } + + iter = mExtensionBehavior.find( + GetExtensionByName(kTextureStorageMultisample2dArrayExtName)); + 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 |