blob: 073994d3cf772c8082199ab4c35dccc345f5d776 [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
Jamie Madill45bcc782016-11-07 13:58:48 -050015namespace sh
16{
17
alokp@chromium.org8b851c62012-06-15 16:25:11 +000018static TBehavior getBehavior(const std::string& str)
19{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070020 const char kRequire[] = "require";
21 const char kEnable[] = "enable";
22 const char kDisable[] = "disable";
23 const char kWarn[] = "warn";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000024
25 if (str == kRequire) return EBhRequire;
26 else if (str == kEnable) return EBhEnable;
27 else if (str == kDisable) return EBhDisable;
28 else if (str == kWarn) return EBhWarn;
29 return EBhUndefined;
30}
31
Olli Etuaho5f80d012016-01-11 11:16:01 +020032TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
33 TDiagnostics &diagnostics,
34 int &shaderVersion,
35 sh::GLenum shaderType,
Olli Etuaho853dc1a2014-11-06 17:25:48 +020036 bool debugShaderPrecisionSupported)
alokp@chromium.org73bc2982012-06-19 18:48:05 +000037 : mExtensionBehavior(extBehavior),
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000038 mDiagnostics(diagnostics),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020039 mShaderVersion(shaderVersion),
Olli Etuaho5f80d012016-01-11 11:16:01 +020040 mShaderType(shaderType),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020041 mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000042{
43}
44
45TDirectiveHandler::~TDirectiveHandler()
46{
47}
48
49void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
50 const std::string& msg)
51{
Shannon Woods7f2d7942013-11-19 15:07:58 -050052 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000053}
54
55void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
56 const std::string& name,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070057 const std::string& value,
58 bool stdgl)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000059{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070060 if (stdgl)
61 {
62 const char kInvariant[] = "invariant";
63 const char kAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000064
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070065 if (name == kInvariant && value == kAll)
Olli Etuaho5f80d012016-01-11 11:16:01 +020066 {
67 if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
68 {
69 // ESSL 3.00.4 section 4.6.1
70 mDiagnostics.writeInfo(
71 pp::Diagnostics::PP_ERROR, loc,
72 "#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
73 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070074 mPragma.stdgl.invariantAll = true;
Olli Etuaho5f80d012016-01-11 11:16:01 +020075 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000076 // The STDGL pragma is used to reserve pragmas for use by future
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070077 // revisions of GLSL. Do not generate an error on unexpected
78 // name and value.
alokp@chromium.org8b851c62012-06-15 16:25:11 +000079 return;
80 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000081 else
82 {
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070083 const char kOptimize[] = "optimize";
84 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020085 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070086 const char kOn[] = "on";
87 const char kOff[] = "off";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000088
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070089 bool invalidValue = false;
90 if (name == kOptimize)
91 {
92 if (value == kOn) mPragma.optimize = true;
93 else if (value == kOff) mPragma.optimize = false;
94 else invalidValue = true;
95 }
96 else if (name == kDebug)
97 {
98 if (value == kOn) mPragma.debug = true;
99 else if (value == kOff) mPragma.debug = false;
100 else invalidValue = true;
101 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200102 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
103 {
104 if (value == kOn) mPragma.debugShaderPrecision = true;
105 else if (value == kOff) mPragma.debugShaderPrecision = false;
106 else invalidValue = true;
107 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700108 else
109 {
110 mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
111 return;
112 }
113
114 if (invalidValue)
115 {
Olli Etuaho391befe2015-08-12 16:30:38 +0300116 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
117 "invalid pragma value", value,
118 "'on' or 'off' expected");
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700119 }
120 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000121}
122
123void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
124 const std::string& name,
125 const std::string& behavior)
126{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700127 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000128
129 TBehavior behaviorVal = getBehavior(behavior);
130 if (behaviorVal == EBhUndefined)
131 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500132 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000133 "behavior", name, "invalid");
134 return;
135 }
136
137 if (name == kExtAll)
138 {
139 if (behaviorVal == EBhRequire)
140 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500141 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000142 "extension", name,
143 "cannot have 'require' behavior");
144 }
145 else if (behaviorVal == EBhEnable)
146 {
Shannon Woods7f2d7942013-11-19 15:07:58 -0500147 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000148 "extension", name,
149 "cannot have 'enable' behavior");
150 }
151 else
152 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000153 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
154 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000155 iter->second = behaviorVal;
156 }
157 return;
158 }
159
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000160 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
161 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000162 {
163 iter->second = behaviorVal;
164 return;
165 }
166
Shannon Woods7f2d7942013-11-19 15:07:58 -0500167 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000168 switch (behaviorVal) {
169 case EBhRequire:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500170 severity = pp::Diagnostics::PP_ERROR;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000171 break;
172 case EBhEnable:
173 case EBhWarn:
174 case EBhDisable:
Shannon Woods7f2d7942013-11-19 15:07:58 -0500175 severity = pp::Diagnostics::PP_WARNING;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000176 break;
177 default:
178 UNREACHABLE();
179 break;
180 }
181 mDiagnostics.writeInfo(severity, loc,
182 "extension", name, "is not supported");
183}
184
185void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
186 int version)
187{
Martin Radev1be913c2016-07-11 17:59:16 +0300188 if (version == 100 || version == 300 || version == 310)
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000189 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000190 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000191 }
192 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000193 {
194 std::stringstream stream;
195 stream << version;
196 std::string str = stream.str();
Shannon Woods7f2d7942013-11-19 15:07:58 -0500197 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000198 "version number", str, "not supported");
199 }
200}
Jamie Madill45bcc782016-11-07 13:58:48 -0500201
202} // namespace sh