blob: cd2cf6fafdc7b6bc1b5849dfd79177e90e1f3aa0 [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
Jamie Madilld7b1ab52016-12-12 14:42:19 -050018static TBehavior getBehavior(const std::string &str)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000019{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070020 const char kRequire[] = "require";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050021 const char kEnable[] = "enable";
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070022 const char kDisable[] = "disable";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050023 const char kWarn[] = "warn";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000024
Jamie Madilld7b1ab52016-12-12 14:42:19 -050025 if (str == kRequire)
26 return EBhRequire;
27 else if (str == kEnable)
28 return EBhEnable;
29 else if (str == kDisable)
30 return EBhDisable;
31 else if (str == kWarn)
32 return EBhWarn;
alokp@chromium.org8b851c62012-06-15 16:25:11 +000033 return EBhUndefined;
34}
35
Olli Etuaho5f80d012016-01-11 11:16:01 +020036TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
37 TDiagnostics &diagnostics,
38 int &shaderVersion,
39 sh::GLenum shaderType,
Olli Etuaho853dc1a2014-11-06 17:25:48 +020040 bool debugShaderPrecisionSupported)
alokp@chromium.org73bc2982012-06-19 18:48:05 +000041 : mExtensionBehavior(extBehavior),
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000042 mDiagnostics(diagnostics),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020043 mShaderVersion(shaderVersion),
Olli Etuaho5f80d012016-01-11 11:16:01 +020044 mShaderType(shaderType),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020045 mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000046{
47}
48
49TDirectiveHandler::~TDirectiveHandler()
50{
51}
52
Jamie Madilld7b1ab52016-12-12 14:42:19 -050053void TDirectiveHandler::handleError(const pp::SourceLocation &loc, const std::string &msg)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000054{
Shannon Woods7f2d7942013-11-19 15:07:58 -050055 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000056}
57
Jamie Madilld7b1ab52016-12-12 14:42:19 -050058void TDirectiveHandler::handlePragma(const pp::SourceLocation &loc,
59 const std::string &name,
60 const std::string &value,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070061 bool stdgl)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000062{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070063 if (stdgl)
64 {
65 const char kInvariant[] = "invariant";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050066 const char kAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000067
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070068 if (name == kInvariant && value == kAll)
Olli Etuaho5f80d012016-01-11 11:16:01 +020069 {
70 if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
71 {
72 // ESSL 3.00.4 section 4.6.1
73 mDiagnostics.writeInfo(
74 pp::Diagnostics::PP_ERROR, loc,
75 "#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
76 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070077 mPragma.stdgl.invariantAll = true;
Olli Etuaho5f80d012016-01-11 11:16:01 +020078 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000079 // The STDGL pragma is used to reserve pragmas for use by future
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070080 // revisions of GLSL. Do not generate an error on unexpected
81 // name and value.
alokp@chromium.org8b851c62012-06-15 16:25:11 +000082 return;
83 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000084 else
85 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050086 const char kOptimize[] = "optimize";
87 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020088 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050089 const char kOn[] = "on";
90 const char kOff[] = "off";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000091
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070092 bool invalidValue = false;
93 if (name == kOptimize)
94 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050095 if (value == kOn)
96 mPragma.optimize = true;
97 else if (value == kOff)
98 mPragma.optimize = false;
99 else
100 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700101 }
102 else if (name == kDebug)
103 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500104 if (value == kOn)
105 mPragma.debug = true;
106 else if (value == kOff)
107 mPragma.debug = false;
108 else
109 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700110 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200111 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
112 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500113 if (value == kOn)
114 mPragma.debugShaderPrecision = true;
115 else if (value == kOff)
116 mPragma.debugShaderPrecision = false;
117 else
118 invalidValue = true;
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200119 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700120 else
121 {
122 mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
123 return;
124 }
125
126 if (invalidValue)
127 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500128 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "invalid pragma value", value,
Olli Etuaho391befe2015-08-12 16:30:38 +0300129 "'on' or 'off' expected");
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700130 }
131 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000132}
133
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500134void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
135 const std::string &name,
136 const std::string &behavior)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000137{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700138 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000139
140 TBehavior behaviorVal = getBehavior(behavior);
141 if (behaviorVal == EBhUndefined)
142 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500143 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "behavior", name, "invalid");
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000144 return;
145 }
146
147 if (name == kExtAll)
148 {
149 if (behaviorVal == EBhRequire)
150 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500151 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "extension", name,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000152 "cannot have 'require' behavior");
153 }
154 else if (behaviorVal == EBhEnable)
155 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500156 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "extension", name,
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000157 "cannot have 'enable' behavior");
158 }
159 else
160 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000161 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
162 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000163 iter->second = behaviorVal;
164 }
165 return;
166 }
167
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000168 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
169 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000170 {
171 iter->second = behaviorVal;
172 return;
173 }
174
Shannon Woods7f2d7942013-11-19 15:07:58 -0500175 pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500176 switch (behaviorVal)
177 {
178 case EBhRequire:
179 severity = pp::Diagnostics::PP_ERROR;
180 break;
181 case EBhEnable:
182 case EBhWarn:
183 case EBhDisable:
184 severity = pp::Diagnostics::PP_WARNING;
185 break;
186 default:
187 UNREACHABLE();
188 break;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000189 }
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500190 mDiagnostics.writeInfo(severity, loc, "extension", name, "is not supported");
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000191}
192
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500193void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000194{
Martin Radev1be913c2016-07-11 17:59:16 +0300195 if (version == 100 || version == 300 || version == 310)
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000196 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000197 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000198 }
199 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000200 {
201 std::stringstream stream;
202 stream << version;
203 std::string str = stream.str();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500204 mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, "version number", str,
205 "not supported");
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000206 }
207}
Jamie Madill45bcc782016-11-07 13:58:48 -0500208
209} // namespace sh