blob: bbcad25b54ed79d33dd4722ad7c786b2f11bf417 [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{
Olli Etuaho77ba4082016-12-16 12:01:18 +000055 mDiagnostics.error(loc, msg.c_str(), "");
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
Olli Etuaho77ba4082016-12-16 12:01:18 +000073 mDiagnostics.error(
74 loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
75 name.c_str());
Olli Etuaho5f80d012016-01-11 11:16:01 +020076 }
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 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000128 mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700129 }
130 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000131}
132
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500133void TDirectiveHandler::handleExtension(const pp::SourceLocation &loc,
134 const std::string &name,
135 const std::string &behavior)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000136{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700137 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000138
139 TBehavior behaviorVal = getBehavior(behavior);
140 if (behaviorVal == EBhUndefined)
141 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000142 mDiagnostics.error(loc, "behavior invalid", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000143 return;
144 }
145
146 if (name == kExtAll)
147 {
148 if (behaviorVal == EBhRequire)
149 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000150 mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000151 }
152 else if (behaviorVal == EBhEnable)
153 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000154 mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000155 }
156 else
157 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000158 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
159 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000160 iter->second = behaviorVal;
161 }
162 return;
163 }
164
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000165 TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
166 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000167 {
168 iter->second = behaviorVal;
169 return;
170 }
171
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500172 switch (behaviorVal)
173 {
174 case EBhRequire:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000175 mDiagnostics.error(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500176 break;
177 case EBhEnable:
178 case EBhWarn:
179 case EBhDisable:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000180 mDiagnostics.warning(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500181 break;
182 default:
183 UNREACHABLE();
184 break;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000185 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000186}
187
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500188void TDirectiveHandler::handleVersion(const pp::SourceLocation &loc, int version)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000189{
Martin Radev1be913c2016-07-11 17:59:16 +0300190 if (version == 100 || version == 300 || version == 310)
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000191 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000192 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000193 }
194 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000195 {
196 std::stringstream stream;
197 stream << version;
198 std::string str = stream.str();
Olli Etuaho77ba4082016-12-16 12:01:18 +0000199 mDiagnostics.error(loc, "version number not supported", str.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000200 }
201}
Jamie Madill45bcc782016-11-07 13:58:48 -0500202
203} // namespace sh