blob: ff8a69efa52fcee90352b3ff4aef49f7c57e7327 [file] [log] [blame]
alokp@chromium.org8b851c62012-06-15 16:25:11 +00001//
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +00002// Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
alokp@chromium.org8b851c62012-06-15 16:25:11 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/DirectiveHandler.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +00008
9#include <sstream>
10
Olli Etuaho5f80d012016-01-11 11:16:01 +020011#include "angle_gl.h"
Olli Etuahod57e0db2015-04-24 15:05:08 +030012#include "common/debug.h"
Geoff Lang17732822013-08-29 13:46:49 -040013#include "compiler/translator/Diagnostics.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +000014
15static TBehavior getBehavior(const std::string& str)
16{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070017 const char kRequire[] = "require";
18 const char kEnable[] = "enable";
19 const char kDisable[] = "disable";
20 const char kWarn[] = "warn";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000021
22 if (str == kRequire) return EBhRequire;
23 else if (str == kEnable) return EBhEnable;
24 else if (str == kDisable) return EBhDisable;
25 else if (str == kWarn) return EBhWarn;
26 return EBhUndefined;
27}
28
Olli Etuaho5f80d012016-01-11 11:16:01 +020029TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
30 TDiagnostics &diagnostics,
31 int &shaderVersion,
32 sh::GLenum shaderType,
Olli Etuaho853dc1a2014-11-06 17:25:48 +020033 bool debugShaderPrecisionSupported)
alokp@chromium.org73bc2982012-06-19 18:48:05 +000034 : mExtensionBehavior(extBehavior),
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000035 mDiagnostics(diagnostics),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020036 mShaderVersion(shaderVersion),
Olli Etuaho5f80d012016-01-11 11:16:01 +020037 mShaderType(shaderType),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020038 mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000039{
40}
41
42TDirectiveHandler::~TDirectiveHandler()
43{
44}
45
46void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
47 const std::string& msg)
48{
Shannon Woods7f2d7942013-11-19 15:07:58 -050049 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000050}
51
52void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
53 const std::string& name,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070054 const std::string& value,
55 bool stdgl)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000056{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070057 if (stdgl)
58 {
59 const char kInvariant[] = "invariant";
60 const char kAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000061
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070062 if (name == kInvariant && value == kAll)
Olli Etuaho5f80d012016-01-11 11:16:01 +020063 {
64 if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
65 {
66 // ESSL 3.00.4 section 4.6.1
67 mDiagnostics.writeInfo(
68 pp::Diagnostics::PP_ERROR, loc,
69 "#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
70 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070071 mPragma.stdgl.invariantAll = true;
Olli Etuaho5f80d012016-01-11 11:16:01 +020072 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000073 // The STDGL pragma is used to reserve pragmas for use by future
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070074 // revisions of GLSL. Do not generate an error on unexpected
75 // name and value.
alokp@chromium.org8b851c62012-06-15 16:25:11 +000076 return;
77 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000078 else
79 {
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070080 const char kOptimize[] = "optimize";
81 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020082 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070083 const char kOn[] = "on";
84 const char kOff[] = "off";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000085
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070086 bool invalidValue = false;
87 if (name == kOptimize)
88 {
89 if (value == kOn) mPragma.optimize = true;
90 else if (value == kOff) mPragma.optimize = false;
91 else invalidValue = true;
92 }
93 else if (name == kDebug)
94 {
95 if (value == kOn) mPragma.debug = true;
96 else if (value == kOff) mPragma.debug = false;
97 else invalidValue = true;
98 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +020099 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
100 {
101 if (value == kOn) mPragma.debugShaderPrecision = true;
102 else if (value == kOff) mPragma.debugShaderPrecision = false;
103 else invalidValue = true;
104 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700105 else
106 {
107 mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
108 return;
109 }
110
111 if (invalidValue)
112 {
Olli Etuaho391befe2015-08-12 16:30:38 +0300113 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
114 "invalid pragma value", value,
115 "'on' or 'off' expected");
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700116 }
117 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000118}
119
120void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
121 const std::string& name,
122 const std::string& behavior)
123{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700124 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000125
126 TBehavior behaviorVal = getBehavior(behavior);
127 if (behaviorVal == EBhUndefined)
128 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500129 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000130 "behavior", name, "invalid");
131 return;
132 }
133
134 if (name == kExtAll)
135 {
136 if (behaviorVal == EBhRequire)
137 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500138 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000139 "extension", name,
140 "cannot have 'require' behavior");
141 }
142 else if (behaviorVal == EBhEnable)
143 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500144 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000145 "extension", name,
146 "cannot have 'enable' behavior");
147 }
148 else
149 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000150 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
151 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000152 iter->second = behaviorVal;
153 }
154 return;
155 }
156
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000157 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
158 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000159 {
160 iter->second = behaviorVal;
161 return;
162 }
163
Shannon Woods7f2d7942013-11-19 15:07:58 -0500164 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000165 switch (behaviorVal) {
166 case EBhRequire:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500167 severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000168 break;
169 case EBhEnable:
170 case EBhWarn:
171 case EBhDisable:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500172 severity = pp::Diagnostics::PP_WARNING;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000173 break;
174 default:
175 UNREACHABLE();
176 break;
177 }
178 mDiagnostics.writeInfo(severity, loc,
179 "extension", name, "is not supported");
180}
181
182void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
183 int version)
184{
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000185 if (version == 100 ||
186 version == 300)
187 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000188 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000189 }
190 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000191 {
192 std::stringstream stream;
193 stream << version;
194 std::string str = stream.str();
Shannon Woods7f2d7942013-11-19 15:07:58 -0500195 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000196 "version number", str, "not supported");
197 }
198}