blob: e468fd44d3b7eb0f12d7235622237b6f8b4d2dab [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"
Jonah Ryan-Davis5f662c02019-01-31 13:53:59 -050013#include "compiler/translator/Common.h"
Geoff Lang17732822013-08-29 13:46:49 -040014#include "compiler/translator/Diagnostics.h"
alokp@chromium.org8b851c62012-06-15 16:25:11 +000015
Jamie Madill45bcc782016-11-07 13:58:48 -050016namespace sh
17{
18
Jamie Madilld7b1ab52016-12-12 14:42:19 -050019static TBehavior getBehavior(const std::string &str)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000020{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070021 const char kRequire[] = "require";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050022 const char kEnable[] = "enable";
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070023 const char kDisable[] = "disable";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050024 const char kWarn[] = "warn";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000025
Jamie Madilld7b1ab52016-12-12 14:42:19 -050026 if (str == kRequire)
27 return EBhRequire;
28 else if (str == kEnable)
29 return EBhEnable;
30 else if (str == kDisable)
31 return EBhDisable;
32 else if (str == kWarn)
33 return EBhWarn;
alokp@chromium.org8b851c62012-06-15 16:25:11 +000034 return EBhUndefined;
35}
36
Olli Etuaho5f80d012016-01-11 11:16:01 +020037TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
38 TDiagnostics &diagnostics,
39 int &shaderVersion,
40 sh::GLenum shaderType,
Olli Etuaho853dc1a2014-11-06 17:25:48 +020041 bool debugShaderPrecisionSupported)
alokp@chromium.org73bc2982012-06-19 18:48:05 +000042 : mExtensionBehavior(extBehavior),
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +000043 mDiagnostics(diagnostics),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020044 mShaderVersion(shaderVersion),
Olli Etuaho5f80d012016-01-11 11:16:01 +020045 mShaderType(shaderType),
Olli Etuaho853dc1a2014-11-06 17:25:48 +020046 mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
Jamie Madillb980c562018-11-27 11:34:27 -050047{}
alokp@chromium.org8b851c62012-06-15 16:25:11 +000048
Jamie Madillb980c562018-11-27 11:34:27 -050049TDirectiveHandler::~TDirectiveHandler() {}
alokp@chromium.org8b851c62012-06-15 16:25:11 +000050
Geoff Lang197d5292018-04-25 14:29:00 -040051void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000052{
Olli Etuaho77ba4082016-12-16 12:01:18 +000053 mDiagnostics.error(loc, msg.c_str(), "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000054}
55
Geoff Lang197d5292018-04-25 14:29:00 -040056void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
Jamie Madilld7b1ab52016-12-12 14:42:19 -050057 const std::string &name,
58 const std::string &value,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070059 bool stdgl)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000060{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070061 if (stdgl)
62 {
63 const char kInvariant[] = "invariant";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050064 const char kAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000065
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070066 if (name == kInvariant && value == kAll)
Olli Etuaho5f80d012016-01-11 11:16:01 +020067 {
68 if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
69 {
70 // ESSL 3.00.4 section 4.6.1
Olli Etuaho77ba4082016-12-16 12:01:18 +000071 mDiagnostics.error(
72 loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
73 name.c_str());
Olli Etuaho5f80d012016-01-11 11:16:01 +020074 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070075 mPragma.stdgl.invariantAll = true;
Olli Etuaho5f80d012016-01-11 11:16:01 +020076 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000077 // The STDGL pragma is used to reserve pragmas for use by future
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070078 // revisions of GLSL. Do not generate an error on unexpected
79 // name and value.
alokp@chromium.org8b851c62012-06-15 16:25:11 +000080 return;
81 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +000082 else
83 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050084 const char kOptimize[] = "optimize";
85 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020086 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050087 const char kOn[] = "on";
88 const char kOff[] = "off";
alokp@chromium.org8b851c62012-06-15 16:25:11 +000089
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070090 bool invalidValue = false;
91 if (name == kOptimize)
92 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050093 if (value == kOn)
94 mPragma.optimize = true;
95 else if (value == kOff)
96 mPragma.optimize = false;
97 else
98 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070099 }
100 else if (name == kDebug)
101 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500102 if (value == kOn)
103 mPragma.debug = true;
104 else if (value == kOff)
105 mPragma.debug = false;
106 else
107 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700108 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200109 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
110 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500111 if (value == kOn)
112 mPragma.debugShaderPrecision = true;
113 else if (value == kOff)
114 mPragma.debugShaderPrecision = false;
115 else
116 invalidValue = true;
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200117 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700118 else
119 {
Geoff Lang197d5292018-04-25 14:29:00 -0400120 mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700121 return;
122 }
123
124 if (invalidValue)
125 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000126 mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700127 }
128 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000129}
130
Geoff Lang197d5292018-04-25 14:29:00 -0400131void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500132 const std::string &name,
133 const std::string &behavior)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000134{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700135 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000136
137 TBehavior behaviorVal = getBehavior(behavior);
138 if (behaviorVal == EBhUndefined)
139 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000140 mDiagnostics.error(loc, "behavior invalid", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000141 return;
142 }
143
144 if (name == kExtAll)
145 {
146 if (behaviorVal == EBhRequire)
147 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000148 mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000149 }
150 else if (behaviorVal == EBhEnable)
151 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000152 mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000153 }
154 else
155 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000156 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
157 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000158 iter->second = behaviorVal;
159 }
160 return;
161 }
162
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300163 TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000164 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000165 {
166 iter->second = behaviorVal;
167 return;
168 }
169
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500170 switch (behaviorVal)
171 {
172 case EBhRequire:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000173 mDiagnostics.error(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500174 break;
175 case EBhEnable:
176 case EBhWarn:
177 case EBhDisable:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000178 mDiagnostics.warning(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500179 break;
180 default:
181 UNREACHABLE();
182 break;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000183 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000184}
185
Geoff Lang197d5292018-04-25 14:29:00 -0400186void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc, int version)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000187{
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 {
Jonah Ryan-Davis5f662c02019-01-31 13:53:59 -0500194 std::stringstream stream = sh::InitializeStream<std::stringstream>();
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000195 stream << version;
196 std::string str = stream.str();
Olli Etuaho77ba4082016-12-16 12:01:18 +0000197 mDiagnostics.error(loc, "version number not supported", str.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000198 }
199}
Jamie Madill45bcc782016-11-07 13:58:48 -0500200
201} // namespace sh