blob: 46e67f5f939f6056a53855a48600c472aababb60 [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)
Jamie Madillb980c562018-11-27 11:34:27 -050046{}
alokp@chromium.org8b851c62012-06-15 16:25:11 +000047
Jamie Madillb980c562018-11-27 11:34:27 -050048TDirectiveHandler::~TDirectiveHandler() {}
alokp@chromium.org8b851c62012-06-15 16:25:11 +000049
Geoff Lang197d5292018-04-25 14:29:00 -040050void TDirectiveHandler::handleError(const angle::pp::SourceLocation &loc, const std::string &msg)
alokp@chromium.org8b851c62012-06-15 16:25:11 +000051{
Olli Etuaho77ba4082016-12-16 12:01:18 +000052 mDiagnostics.error(loc, msg.c_str(), "");
alokp@chromium.org8b851c62012-06-15 16:25:11 +000053}
54
Geoff Lang197d5292018-04-25 14:29:00 -040055void TDirectiveHandler::handlePragma(const angle::pp::SourceLocation &loc,
Jamie Madilld7b1ab52016-12-12 14:42:19 -050056 const std::string &name,
57 const std::string &value,
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070058 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";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050063 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
Olli Etuaho77ba4082016-12-16 12:01:18 +000070 mDiagnostics.error(
71 loc, "#pragma STDGL invariant(all) can not be used in fragment shader",
72 name.c_str());
Olli Etuaho5f80d012016-01-11 11:16:01 +020073 }
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 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050083 const char kOptimize[] = "optimize";
84 const char kDebug[] = "debug";
Olli Etuaho853dc1a2014-11-06 17:25:48 +020085 const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
Jamie Madilld7b1ab52016-12-12 14:42:19 -050086 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 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -050092 if (value == kOn)
93 mPragma.optimize = true;
94 else if (value == kOff)
95 mPragma.optimize = false;
96 else
97 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -070098 }
99 else if (name == kDebug)
100 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500101 if (value == kOn)
102 mPragma.debug = true;
103 else if (value == kOff)
104 mPragma.debug = false;
105 else
106 invalidValue = true;
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700107 }
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200108 else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
109 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500110 if (value == kOn)
111 mPragma.debugShaderPrecision = true;
112 else if (value == kOff)
113 mPragma.debugShaderPrecision = false;
114 else
115 invalidValue = true;
Olli Etuaho853dc1a2014-11-06 17:25:48 +0200116 }
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700117 else
118 {
Geoff Lang197d5292018-04-25 14:29:00 -0400119 mDiagnostics.report(angle::pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700120 return;
121 }
122
123 if (invalidValue)
124 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000125 mDiagnostics.error(loc, "invalid pragma value - 'on' or 'off' expected", value.c_str());
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700126 }
127 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000128}
129
Geoff Lang197d5292018-04-25 14:29:00 -0400130void TDirectiveHandler::handleExtension(const angle::pp::SourceLocation &loc,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500131 const std::string &name,
132 const std::string &behavior)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000133{
Zhenyao Mo94ac7b72014-10-15 18:22:08 -0700134 const char kExtAll[] = "all";
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000135
136 TBehavior behaviorVal = getBehavior(behavior);
137 if (behaviorVal == EBhUndefined)
138 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000139 mDiagnostics.error(loc, "behavior invalid", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000140 return;
141 }
142
143 if (name == kExtAll)
144 {
145 if (behaviorVal == EBhRequire)
146 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000147 mDiagnostics.error(loc, "extension cannot have 'require' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000148 }
149 else if (behaviorVal == EBhEnable)
150 {
Olli Etuaho77ba4082016-12-16 12:01:18 +0000151 mDiagnostics.error(loc, "extension cannot have 'enable' behavior", name.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000152 }
153 else
154 {
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000155 for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
156 iter != mExtensionBehavior.end(); ++iter)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000157 iter->second = behaviorVal;
158 }
159 return;
160 }
161
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300162 TExtensionBehavior::iterator iter = mExtensionBehavior.find(GetExtensionByName(name.c_str()));
alokp@chromium.org73bc2982012-06-19 18:48:05 +0000163 if (iter != mExtensionBehavior.end())
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000164 {
165 iter->second = behaviorVal;
166 return;
167 }
168
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500169 switch (behaviorVal)
170 {
171 case EBhRequire:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000172 mDiagnostics.error(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500173 break;
174 case EBhEnable:
175 case EBhWarn:
176 case EBhDisable:
Olli Etuaho77ba4082016-12-16 12:01:18 +0000177 mDiagnostics.warning(loc, "extension is not supported", name.c_str());
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500178 break;
179 default:
180 UNREACHABLE();
181 break;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000182 }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000183}
184
Geoff Lang197d5292018-04-25 14:29:00 -0400185void TDirectiveHandler::handleVersion(const angle::pp::SourceLocation &loc, int version)
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000186{
Martin Radev1be913c2016-07-11 17:59:16 +0300187 if (version == 100 || version == 300 || version == 310)
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000188 {
shannon.woods%transgaming.com@gtempaccount.com5524db02013-04-13 03:38:16 +0000189 mShaderVersion = version;
shannon.woods%transgaming.com@gtempaccount.com0bbed382013-04-13 03:38:07 +0000190 }
191 else
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000192 {
193 std::stringstream stream;
194 stream << version;
195 std::string str = stream.str();
Olli Etuaho77ba4082016-12-16 12:01:18 +0000196 mDiagnostics.error(loc, "version number not supported", str.c_str());
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000197 }
198}
Jamie Madill45bcc782016-11-07 13:58:48 -0500199
200} // namespace sh