Line data Source code
1 : //
2 : // Copyright (c) 2012-2013 The ANGLE Project Authors. All rights reserved.
3 : // Use of this source code is governed by a BSD-style license that can be
4 : // found in the LICENSE file.
5 : //
6 :
7 : #include "compiler/translator/DirectiveHandler.h"
8 :
9 : #include <sstream>
10 :
11 : #include "angle_gl.h"
12 : #include "common/debug.h"
13 : #include "compiler/translator/Diagnostics.h"
14 :
15 : namespace sh
16 : {
17 :
18 0 : static TBehavior getBehavior(const std::string& str)
19 : {
20 0 : const char kRequire[] = "require";
21 0 : const char kEnable[] = "enable";
22 0 : const char kDisable[] = "disable";
23 0 : const char kWarn[] = "warn";
24 :
25 0 : if (str == kRequire) return EBhRequire;
26 0 : else if (str == kEnable) return EBhEnable;
27 0 : else if (str == kDisable) return EBhDisable;
28 0 : else if (str == kWarn) return EBhWarn;
29 0 : return EBhUndefined;
30 : }
31 :
32 0 : TDirectiveHandler::TDirectiveHandler(TExtensionBehavior &extBehavior,
33 : TDiagnostics &diagnostics,
34 : int &shaderVersion,
35 : sh::GLenum shaderType,
36 0 : bool debugShaderPrecisionSupported)
37 : : mExtensionBehavior(extBehavior),
38 : mDiagnostics(diagnostics),
39 : mShaderVersion(shaderVersion),
40 : mShaderType(shaderType),
41 0 : mDebugShaderPrecisionSupported(debugShaderPrecisionSupported)
42 : {
43 0 : }
44 :
45 0 : TDirectiveHandler::~TDirectiveHandler()
46 : {
47 0 : }
48 :
49 0 : void TDirectiveHandler::handleError(const pp::SourceLocation& loc,
50 : const std::string& msg)
51 : {
52 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc, msg, "", "");
53 0 : }
54 :
55 0 : void TDirectiveHandler::handlePragma(const pp::SourceLocation& loc,
56 : const std::string& name,
57 : const std::string& value,
58 : bool stdgl)
59 : {
60 0 : if (stdgl)
61 : {
62 0 : const char kInvariant[] = "invariant";
63 0 : const char kAll[] = "all";
64 :
65 0 : if (name == kInvariant && value == kAll)
66 : {
67 0 : if (mShaderVersion == 300 && mShaderType == GL_FRAGMENT_SHADER)
68 : {
69 : // ESSL 3.00.4 section 4.6.1
70 0 : mDiagnostics.writeInfo(
71 : pp::Diagnostics::PP_ERROR, loc,
72 0 : "#pragma STDGL invariant(all) can not be used in fragment shader", name, value);
73 : }
74 0 : mPragma.stdgl.invariantAll = true;
75 : }
76 : // The STDGL pragma is used to reserve pragmas for use by future
77 : // revisions of GLSL. Do not generate an error on unexpected
78 : // name and value.
79 0 : return;
80 : }
81 : else
82 : {
83 0 : const char kOptimize[] = "optimize";
84 0 : const char kDebug[] = "debug";
85 0 : const char kDebugShaderPrecision[] = "webgl_debug_shader_precision";
86 0 : const char kOn[] = "on";
87 0 : const char kOff[] = "off";
88 :
89 0 : bool invalidValue = false;
90 0 : if (name == kOptimize)
91 : {
92 0 : if (value == kOn) mPragma.optimize = true;
93 0 : else if (value == kOff) mPragma.optimize = false;
94 0 : else invalidValue = true;
95 : }
96 0 : else if (name == kDebug)
97 : {
98 0 : if (value == kOn) mPragma.debug = true;
99 0 : else if (value == kOff) mPragma.debug = false;
100 0 : else invalidValue = true;
101 : }
102 0 : else if (name == kDebugShaderPrecision && mDebugShaderPrecisionSupported)
103 : {
104 0 : if (value == kOn) mPragma.debugShaderPrecision = true;
105 0 : else if (value == kOff) mPragma.debugShaderPrecision = false;
106 0 : else invalidValue = true;
107 : }
108 : else
109 : {
110 0 : mDiagnostics.report(pp::Diagnostics::PP_UNRECOGNIZED_PRAGMA, loc, name);
111 0 : return;
112 : }
113 :
114 0 : if (invalidValue)
115 : {
116 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
117 : "invalid pragma value", value,
118 0 : "'on' or 'off' expected");
119 : }
120 : }
121 : }
122 :
123 0 : void TDirectiveHandler::handleExtension(const pp::SourceLocation& loc,
124 : const std::string& name,
125 : const std::string& behavior)
126 : {
127 0 : const char kExtAll[] = "all";
128 :
129 0 : TBehavior behaviorVal = getBehavior(behavior);
130 0 : if (behaviorVal == EBhUndefined)
131 : {
132 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
133 0 : "behavior", name, "invalid");
134 0 : return;
135 : }
136 :
137 0 : if (name == kExtAll)
138 : {
139 0 : if (behaviorVal == EBhRequire)
140 : {
141 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
142 : "extension", name,
143 0 : "cannot have 'require' behavior");
144 : }
145 0 : else if (behaviorVal == EBhEnable)
146 : {
147 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
148 : "extension", name,
149 0 : "cannot have 'enable' behavior");
150 : }
151 : else
152 : {
153 0 : for (TExtensionBehavior::iterator iter = mExtensionBehavior.begin();
154 0 : iter != mExtensionBehavior.end(); ++iter)
155 0 : iter->second = behaviorVal;
156 : }
157 0 : return;
158 : }
159 :
160 0 : TExtensionBehavior::iterator iter = mExtensionBehavior.find(name);
161 0 : if (iter != mExtensionBehavior.end())
162 : {
163 0 : iter->second = behaviorVal;
164 0 : return;
165 : }
166 :
167 0 : pp::Diagnostics::Severity severity = pp::Diagnostics::PP_ERROR;
168 0 : switch (behaviorVal) {
169 : case EBhRequire:
170 0 : severity = pp::Diagnostics::PP_ERROR;
171 0 : break;
172 : case EBhEnable:
173 : case EBhWarn:
174 : case EBhDisable:
175 0 : severity = pp::Diagnostics::PP_WARNING;
176 0 : break;
177 : default:
178 0 : UNREACHABLE();
179 : break;
180 : }
181 0 : mDiagnostics.writeInfo(severity, loc,
182 0 : "extension", name, "is not supported");
183 : }
184 :
185 0 : void TDirectiveHandler::handleVersion(const pp::SourceLocation& loc,
186 : int version)
187 : {
188 0 : if (version == 100 || version == 300 || version == 310)
189 : {
190 0 : mShaderVersion = version;
191 : }
192 : else
193 : {
194 0 : std::stringstream stream;
195 0 : stream << version;
196 0 : std::string str = stream.str();
197 0 : mDiagnostics.writeInfo(pp::Diagnostics::PP_ERROR, loc,
198 0 : "version number", str, "not supported");
199 : }
200 0 : }
201 :
202 : } // namespace sh
|