1 | /* |
2 | * Copyright 2016 Google Inc. |
3 | * |
4 | * Use of this source code is governed by a BSD-style license that can be |
5 | * found in the LICENSE file. |
6 | */ |
7 | |
8 | #ifndef SKSL_UTIL |
9 | #define SKSL_UTIL |
10 | |
11 | #include <cstdarg> |
12 | #include <memory> |
13 | #include "stdlib.h" |
14 | #include "string.h" |
15 | #include "src/sksl/SkSLDefines.h" |
16 | #include "src/sksl/SkSLLexer.h" |
17 | |
18 | #ifndef SKSL_STANDALONE |
19 | #include "include/core/SkTypes.h" |
20 | #if SK_SUPPORT_GPU |
21 | #include "include/gpu/GrContextOptions.h" |
22 | #include "src/gpu/GrShaderCaps.h" |
23 | #endif // SK_SUPPORT_GPU |
24 | #endif // SKSL_STANDALONE |
25 | |
26 | class GrShaderCaps; |
27 | |
28 | namespace SkSL { |
29 | |
30 | class OutputStream; |
31 | class StringStream; |
32 | |
33 | #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU |
34 | |
35 | // we're being compiled standalone, so we don't have access to caps... |
36 | enum GrGLSLGeneration { |
37 | k110_GrGLSLGeneration, |
38 | k130_GrGLSLGeneration, |
39 | k140_GrGLSLGeneration, |
40 | k150_GrGLSLGeneration, |
41 | k330_GrGLSLGeneration, |
42 | k400_GrGLSLGeneration, |
43 | k420_GrGLSLGeneration, |
44 | k310es_GrGLSLGeneration, |
45 | k320es_GrGLSLGeneration, |
46 | }; |
47 | |
48 | #define SKSL_CAPS_CLASS StandaloneShaderCaps |
49 | class StandaloneShaderCaps { |
50 | public: |
51 | GrGLSLGeneration generation() const { |
52 | return k400_GrGLSLGeneration; |
53 | } |
54 | |
55 | bool atan2ImplementedAsAtanYOverX() const { |
56 | return false; |
57 | } |
58 | |
59 | bool canUseMinAndAbsTogether() const { |
60 | return true; |
61 | } |
62 | |
63 | bool mustForceNegatedAtanParamToFloat() const { |
64 | return false; |
65 | } |
66 | |
67 | bool shaderDerivativeSupport() const { |
68 | return true; |
69 | } |
70 | |
71 | bool usesPrecisionModifiers() const { |
72 | return true; |
73 | } |
74 | |
75 | bool mustDeclareFragmentShaderOutput() const { |
76 | return true; |
77 | } |
78 | |
79 | bool fbFetchSupport() const { |
80 | return true; |
81 | } |
82 | |
83 | bool fbFetchNeedsCustomOutput() const { |
84 | return false; |
85 | } |
86 | |
87 | bool flatInterpolationSupport() const { |
88 | return true; |
89 | } |
90 | |
91 | bool noperspectiveInterpolationSupport() const { |
92 | return true; |
93 | } |
94 | |
95 | bool multisampleInterpolationSupport() const { |
96 | return true; |
97 | } |
98 | |
99 | bool sampleMaskSupport() const { |
100 | return true; |
101 | } |
102 | |
103 | bool externalTextureSupport() const { |
104 | return true; |
105 | } |
106 | |
107 | bool mustDoOpBetweenFloorAndAbs() const { |
108 | return false; |
109 | } |
110 | |
111 | bool mustGuardDivisionEvenAfterExplicitZeroCheck() const { |
112 | return false; |
113 | } |
114 | |
115 | bool inBlendModesFailRandomlyForAllZeroVec() const { |
116 | return false; |
117 | } |
118 | |
119 | bool mustEnableAdvBlendEqs() const { |
120 | return false; |
121 | } |
122 | |
123 | bool mustEnableSpecificAdvBlendEqs() const { |
124 | return false; |
125 | } |
126 | |
127 | bool canUseAnyFunctionInShader() const { |
128 | return false; |
129 | } |
130 | |
131 | bool noDefaultPrecisionForExternalSamplers() const { |
132 | return false; |
133 | } |
134 | |
135 | bool floatIs32Bits() const { |
136 | return true; |
137 | } |
138 | |
139 | bool integerSupport() const { |
140 | return false; |
141 | } |
142 | |
143 | bool builtinFMASupport() const { |
144 | return true; |
145 | } |
146 | |
147 | const char* shaderDerivativeExtensionString() const { |
148 | return nullptr; |
149 | } |
150 | |
151 | const char* fragCoordConventionsExtensionString() const { |
152 | return nullptr; |
153 | } |
154 | |
155 | const char* geometryShaderExtensionString() const { |
156 | return nullptr; |
157 | } |
158 | |
159 | const char* gsInvocationsExtensionString() const { |
160 | return nullptr; |
161 | } |
162 | |
163 | const char* externalTextureExtensionString() const { |
164 | return nullptr; |
165 | } |
166 | |
167 | const char* secondExternalTextureExtensionString() const { |
168 | return nullptr; |
169 | } |
170 | |
171 | const char* versionDeclString() const { |
172 | return "" ; |
173 | } |
174 | |
175 | bool gsInvocationsSupport() const { |
176 | return true; |
177 | } |
178 | |
179 | bool canUseFractForNegativeValues() const { |
180 | return true; |
181 | } |
182 | |
183 | bool canUseFragCoord() const { |
184 | return true; |
185 | } |
186 | |
187 | bool incompleteShortIntPrecision() const { |
188 | return false; |
189 | } |
190 | |
191 | bool addAndTrueToLoopCondition() const { |
192 | return false; |
193 | } |
194 | |
195 | bool unfoldShortCircuitAsTernary() const { |
196 | return false; |
197 | } |
198 | |
199 | bool emulateAbsIntFunction() const { |
200 | return false; |
201 | } |
202 | |
203 | bool rewriteDoWhileLoops() const { |
204 | return false; |
205 | } |
206 | |
207 | bool removePowWithConstantExponent() const { |
208 | return false; |
209 | } |
210 | |
211 | const char* fbFetchColorName() const { |
212 | return nullptr; |
213 | } |
214 | }; |
215 | |
216 | extern StandaloneShaderCaps standaloneCaps; |
217 | |
218 | #else |
219 | |
220 | #define SKSL_CAPS_CLASS GrShaderCaps |
221 | // Various sets of caps for use in tests |
222 | class ShaderCapsFactory { |
223 | public: |
224 | static sk_sp<GrShaderCaps> Default() { |
225 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
226 | result->fVersionDeclString = "#version 400" ; |
227 | result->fShaderDerivativeSupport = true; |
228 | return result; |
229 | } |
230 | |
231 | static sk_sp<GrShaderCaps> Version450Core() { |
232 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
233 | result->fVersionDeclString = "#version 450 core" ; |
234 | return result; |
235 | } |
236 | |
237 | static sk_sp<GrShaderCaps> Version110() { |
238 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
239 | result->fVersionDeclString = "#version 110" ; |
240 | result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; |
241 | return result; |
242 | } |
243 | |
244 | static sk_sp<GrShaderCaps> UsesPrecisionModifiers() { |
245 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
246 | result->fVersionDeclString = "#version 400" ; |
247 | result->fUsesPrecisionModifiers = true; |
248 | return result; |
249 | } |
250 | |
251 | static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() { |
252 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
253 | result->fVersionDeclString = "#version 400" ; |
254 | result->fCanUseMinAndAbsTogether = false; |
255 | return result; |
256 | } |
257 | |
258 | static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() { |
259 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
260 | result->fVersionDeclString = "#version 400" ; |
261 | result->fCanUseFractForNegativeValues = false; |
262 | return result; |
263 | } |
264 | |
265 | static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() { |
266 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
267 | result->fVersionDeclString = "#version 400" ; |
268 | result->fMustForceNegatedAtanParamToFloat = true; |
269 | return result; |
270 | } |
271 | |
272 | static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() { |
273 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
274 | result->fVersionDeclString = "#version 400" ; |
275 | result->fShaderDerivativeSupport = true; |
276 | result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives" ; |
277 | result->fUsesPrecisionModifiers = true; |
278 | return result; |
279 | } |
280 | |
281 | static sk_sp<GrShaderCaps> FragCoordsOld() { |
282 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
283 | result->fVersionDeclString = "#version 110" ; |
284 | result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration; |
285 | result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions" ; |
286 | return result; |
287 | } |
288 | |
289 | static sk_sp<GrShaderCaps> FragCoordsNew() { |
290 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
291 | result->fVersionDeclString = "#version 400" ; |
292 | result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions" ; |
293 | return result; |
294 | } |
295 | |
296 | static sk_sp<GrShaderCaps> GeometryShaderSupport() { |
297 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
298 | result->fVersionDeclString = "#version 400" ; |
299 | result->fGeometryShaderSupport = true; |
300 | result->fGSInvocationsSupport = true; |
301 | return result; |
302 | } |
303 | |
304 | static sk_sp<GrShaderCaps> NoGSInvocationsSupport() { |
305 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
306 | result->fVersionDeclString = "#version 400" ; |
307 | result->fGeometryShaderSupport = true; |
308 | result->fGSInvocationsSupport = false; |
309 | return result; |
310 | } |
311 | |
312 | static sk_sp<GrShaderCaps> GeometryShaderExtensionString() { |
313 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
314 | result->fVersionDeclString = "#version 310es" ; |
315 | result->fGeometryShaderSupport = true; |
316 | result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader" ; |
317 | result->fGSInvocationsSupport = true; |
318 | return result; |
319 | } |
320 | |
321 | static sk_sp<GrShaderCaps> GSInvocationsExtensionString() { |
322 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
323 | result->fVersionDeclString = "#version 400" ; |
324 | result->fGeometryShaderSupport = true; |
325 | result->fGSInvocationsSupport = true; |
326 | result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5" ; |
327 | return result; |
328 | } |
329 | |
330 | static sk_sp<GrShaderCaps> VariousCaps() { |
331 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
332 | result->fVersionDeclString = "#version 400" ; |
333 | result->fExternalTextureSupport = true; |
334 | result->fFBFetchSupport = false; |
335 | result->fCanUseAnyFunctionInShader = false; |
336 | return result; |
337 | } |
338 | |
339 | static sk_sp<GrShaderCaps> CannotUseFragCoord() { |
340 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
341 | result->fVersionDeclString = "#version 400" ; |
342 | result->fCanUseFragCoord = false; |
343 | return result; |
344 | } |
345 | |
346 | static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() { |
347 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
348 | result->fVersionDeclString = "#version 310es" ; |
349 | result->fUsesPrecisionModifiers = true; |
350 | result->fIncompleteShortIntPrecision = true; |
351 | return result; |
352 | } |
353 | |
354 | static sk_sp<GrShaderCaps> AddAndTrueToLoopCondition() { |
355 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
356 | result->fVersionDeclString = "#version 400" ; |
357 | result->fAddAndTrueToLoopCondition = true; |
358 | return result; |
359 | } |
360 | |
361 | static sk_sp<GrShaderCaps> UnfoldShortCircuitAsTernary() { |
362 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
363 | result->fVersionDeclString = "#version 400" ; |
364 | result->fUnfoldShortCircuitAsTernary = true; |
365 | return result; |
366 | } |
367 | |
368 | static sk_sp<GrShaderCaps> EmulateAbsIntFunction() { |
369 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
370 | result->fVersionDeclString = "#version 400" ; |
371 | result->fEmulateAbsIntFunction = true; |
372 | return result; |
373 | } |
374 | |
375 | static sk_sp<GrShaderCaps> RewriteDoWhileLoops() { |
376 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
377 | result->fVersionDeclString = "#version 400" ; |
378 | result->fRewriteDoWhileLoops = true; |
379 | return result; |
380 | } |
381 | |
382 | static sk_sp<GrShaderCaps> RemovePowWithConstantExponent() { |
383 | sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions()); |
384 | result->fVersionDeclString = "#version 400" ; |
385 | result->fRemovePowWithConstantExponent = true; |
386 | return result; |
387 | } |
388 | |
389 | static sk_sp<GrShaderCaps> SampleMaskSupport() { |
390 | sk_sp<GrShaderCaps> result = Default(); |
391 | result->fSampleMaskSupport = true; |
392 | return result; |
393 | } |
394 | }; |
395 | #endif |
396 | |
397 | void write_stringstream(const StringStream& d, OutputStream& out); |
398 | |
399 | // Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.) |
400 | bool is_assignment(Token::Kind op); |
401 | |
402 | // Given a compound assignment operator, returns the non-assignment version of the operator (e.g. |
403 | // '+=' becomes '+') |
404 | Token::Kind remove_assignment(Token::Kind op); |
405 | |
406 | NORETURN void sksl_abort(); |
407 | |
408 | } // namespace |
409 | |
410 | #endif |
411 | |