summaryrefslogtreecommitdiffstats
path: root/gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp')
-rw-r--r--gfx/angle/checkout/src/compiler/translator/DirectiveHandler.cpp304
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