blob: ad5fb3802631a07658c1312f93ece2fd5b88b730 [file] [log] [blame]
ethannicholasb3058bd2016-07-01 08:22:01 -07001/*
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 */
Ethan Nicholas0df1b042017-03-31 13:56:23 -04007
ethannicholasb3058bd2016-07-01 08:22:01 -07008#ifndef SKSL_UTIL
9#define SKSL_UTIL
10
Ethan Nicholas0df1b042017-03-31 13:56:23 -040011#include <cstdarg>
12#include <memory>
ethannicholasb3058bd2016-07-01 08:22:01 -070013#include "stdlib.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040014#include "string.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "src/sksl/SkSLDefines.h"
16#include "src/sksl/SkSLLexer.h"
Ethan Nicholas0df1b042017-03-31 13:56:23 -040017
Ethan Nicholas842d31b2019-01-22 10:59:11 -050018#ifndef SKSL_STANDALONE
Mike Kleinc0bd9f92019-04-23 12:05:21 -050019#include "include/core/SkTypes.h"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050020#if SK_SUPPORT_GPU
Mike Kleinc0bd9f92019-04-23 12:05:21 -050021#include "include/gpu/GrContextOptions.h"
22#include "src/gpu/GrShaderCaps.h"
Ethan Nicholas842d31b2019-01-22 10:59:11 -050023#endif // SK_SUPPORT_GPU
Ethan Nicholas0df1b042017-03-31 13:56:23 -040024#endif // SKSL_STANDALONE
ethannicholasb3058bd2016-07-01 08:22:01 -070025
Brian Salomonc7fe0f72018-05-11 10:14:21 -040026class GrShaderCaps;
27
ethannicholasb3058bd2016-07-01 08:22:01 -070028namespace SkSL {
29
Ethan Nicholas842d31b2019-01-22 10:59:11 -050030class OutputStream;
31class StringStream;
32
Brian Salomonc7fe0f72018-05-11 10:14:21 -040033#if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
Ethan Nicholas0df1b042017-03-31 13:56:23 -040034
35// we're being compiled standalone, so we don't have access to caps...
36enum 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
49class StandaloneShaderCaps {
50public:
51 GrGLSLGeneration generation() const {
52 return k400_GrGLSLGeneration;
53 }
54
Michael Ludwig24d438b2018-09-12 15:22:50 -040055 bool atan2ImplementedAsAtanYOverX() const {
56 return false;
57 }
58
Ethan Nicholas0df1b042017-03-31 13:56:23 -040059 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
Ethan Nicholas0df1b042017-03-31 13:56:23 -040087 bool flatInterpolationSupport() const {
88 return true;
89 }
90
91 bool noperspectiveInterpolationSupport() const {
92 return true;
93 }
94
Robert Phillips7f861922018-01-30 13:13:42 +000095 bool multisampleInterpolationSupport() const {
96 return true;
97 }
98
Chris Daltond31b5e72019-02-26 18:02:16 -070099 bool sampleVariablesSupport() const {
100 return true;
101 }
102
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400103 bool externalTextureSupport() const {
104 return true;
105 }
106
Michael Ludwig4f94ef62018-09-12 15:22:16 -0400107 bool mustDoOpBetweenFloorAndAbs() const {
108 return false;
109 }
110
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400111 bool mustEnableAdvBlendEqs() const {
112 return false;
113 }
114
115 bool mustEnableSpecificAdvBlendEqs() const {
116 return false;
117 }
118
119 bool canUseAnyFunctionInShader() const {
120 return false;
121 }
122
Chris Dalton47c8ed32017-11-15 18:27:09 -0700123 bool floatIs32Bits() const {
124 return true;
Ethan Nicholas762466e2017-06-29 10:03:38 -0400125 }
126
Ethan Nicholas07990de2017-07-18 09:47:43 -0400127 bool integerSupport() const {
128 return false;
129 }
130
Chris Dalton07ee63d2018-11-16 11:02:34 -0500131 bool builtinFMASupport() const {
132 return true;
133 }
134
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400135 const char* shaderDerivativeExtensionString() const {
136 return nullptr;
137 }
138
139 const char* fragCoordConventionsExtensionString() const {
140 return nullptr;
141 }
142
Chris Dalton8fd79552018-01-11 00:46:14 -0500143 const char* geometryShaderExtensionString() const {
144 return nullptr;
145 }
146
Chris Dalton567d6f42017-10-06 13:13:32 -0600147 const char* gsInvocationsExtensionString() const {
148 return nullptr;
149 }
150
Brian Osman4b2f9152018-04-17 11:19:57 -0400151 const char* externalTextureExtensionString() const {
152 return nullptr;
153 }
154
Brian Osman061020e2018-04-17 14:22:15 -0400155 const char* secondExternalTextureExtensionString() const {
156 return nullptr;
157 }
158
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400159 const char* versionDeclString() const {
160 return "";
161 }
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400162
Chris Dalton567d6f42017-10-06 13:13:32 -0600163 bool gsInvocationsSupport() const {
164 return true;
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400165 }
Ethan Nicholas1af6d682017-08-08 16:42:13 -0400166
167 bool canUseFractForNegativeValues() const {
168 return true;
169 }
Brian Osmancd3261a2018-01-16 13:52:29 +0000170
171 bool canUseFragCoord() const {
172 return true;
173 }
Chris Dalton85fcfc52018-03-14 11:15:27 -0600174
175 bool incompleteShortIntPrecision() const {
176 return false;
177 }
Ethan Nicholas43f6d452018-04-13 16:53:07 -0400178
Adrienne Walkeree8295c2018-08-21 10:56:30 -0700179 bool addAndTrueToLoopCondition() const {
180 return false;
181 }
182
Adrienne Walkerc02165f2018-08-21 11:08:11 -0700183 bool unfoldShortCircuitAsTernary() const {
184 return false;
185 }
186
Adrienne Walker92b161f2018-08-22 10:41:52 -0700187 bool emulateAbsIntFunction() const {
188 return false;
189 }
190
Adrienne Walker8b23ca62018-08-22 10:45:41 -0700191 bool rewriteDoWhileLoops() const {
192 return false;
193 }
194
Adrienne Walker2f4c09b2018-08-22 16:04:57 -0700195 bool removePowWithConstantExponent() const {
196 return false;
197 }
198
Ethan Nicholas43f6d452018-04-13 16:53:07 -0400199 const char* fbFetchColorName() const {
200 return nullptr;
201 }
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400202};
203
204extern StandaloneShaderCaps standaloneCaps;
205
206#else
207
208#define SKSL_CAPS_CLASS GrShaderCaps
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500209// Various sets of caps for use in tests
Brian Salomonf1dd6772016-11-29 15:27:52 -0500210class ShaderCapsFactory {
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500211public:
Brian Salomon94efbf52016-11-29 13:43:05 -0500212 static sk_sp<GrShaderCaps> Default() {
213 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500214 result->fVersionDeclString = "#version 400";
215 result->fShaderDerivativeSupport = true;
216 return result;
217 }
218
Brian Salomon94efbf52016-11-29 13:43:05 -0500219 static sk_sp<GrShaderCaps> Version450Core() {
220 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500221 result->fVersionDeclString = "#version 450 core";
222 return result;
223 }
224
Brian Salomon94efbf52016-11-29 13:43:05 -0500225 static sk_sp<GrShaderCaps> Version110() {
226 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500227 result->fVersionDeclString = "#version 110";
228 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
229 return result;
230 }
231
Brian Salomon94efbf52016-11-29 13:43:05 -0500232 static sk_sp<GrShaderCaps> UsesPrecisionModifiers() {
233 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500234 result->fVersionDeclString = "#version 400";
235 result->fUsesPrecisionModifiers = true;
236 return result;
237 }
238
Brian Salomon94efbf52016-11-29 13:43:05 -0500239 static sk_sp<GrShaderCaps> CannotUseMinAndAbsTogether() {
240 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500241 result->fVersionDeclString = "#version 400";
242 result->fCanUseMinAndAbsTogether = false;
243 return result;
244 }
245
Florin Malita3b30c4f2017-08-08 15:47:35 -0400246 static sk_sp<GrShaderCaps> CannotUseFractForNegativeValues() {
247 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
248 result->fVersionDeclString = "#version 400";
249 result->fCanUseFractForNegativeValues = false;
250 return result;
251 }
252
Brian Salomon94efbf52016-11-29 13:43:05 -0500253 static sk_sp<GrShaderCaps> MustForceNegatedAtanParamToFloat() {
254 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500255 result->fVersionDeclString = "#version 400";
256 result->fMustForceNegatedAtanParamToFloat = true;
257 return result;
258 }
259
Brian Salomon94efbf52016-11-29 13:43:05 -0500260 static sk_sp<GrShaderCaps> ShaderDerivativeExtensionString() {
261 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500262 result->fVersionDeclString = "#version 400";
263 result->fShaderDerivativeSupport = true;
264 result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
Ethan Nicholas762466e2017-06-29 10:03:38 -0400265 result->fUsesPrecisionModifiers = true;
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500266 return result;
267 }
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500268
Ethan Nicholas941e7e22016-12-12 15:33:30 -0500269 static sk_sp<GrShaderCaps> FragCoordsOld() {
270 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
271 result->fVersionDeclString = "#version 110";
272 result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
273 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
274 return result;
275 }
276
277 static sk_sp<GrShaderCaps> FragCoordsNew() {
278 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
279 result->fVersionDeclString = "#version 400";
280 result->fFragCoordConventionsExtensionString = "GL_ARB_fragment_coord_conventions";
281 return result;
282 }
283
Chris Dalton8fd79552018-01-11 00:46:14 -0500284 static sk_sp<GrShaderCaps> GeometryShaderSupport() {
285 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
286 result->fVersionDeclString = "#version 400";
287 result->fGeometryShaderSupport = true;
288 result->fGSInvocationsSupport = true;
289 return result;
290 }
291
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600292 static sk_sp<GrShaderCaps> NoGSInvocationsSupport() {
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400293 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
294 result->fVersionDeclString = "#version 400";
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600295 result->fGeometryShaderSupport = true;
296 result->fGSInvocationsSupport = false;
297 return result;
298 }
299
Chris Dalton8fd79552018-01-11 00:46:14 -0500300 static sk_sp<GrShaderCaps> GeometryShaderExtensionString() {
301 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
302 result->fVersionDeclString = "#version 310es";
303 result->fGeometryShaderSupport = true;
304 result->fGeometryShaderExtensionString = "GL_EXT_geometry_shader";
305 result->fGSInvocationsSupport = true;
306 return result;
307 }
308
Chris Daltonf1b47bb2017-10-06 11:57:51 -0600309 static sk_sp<GrShaderCaps> GSInvocationsExtensionString() {
310 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
311 result->fVersionDeclString = "#version 400";
312 result->fGeometryShaderSupport = true;
313 result->fGSInvocationsSupport = true;
314 result->fGSInvocationsExtensionString = "GL_ARB_gpu_shader5";
Ethan Nicholas7da6dfa2017-06-21 11:25:18 -0400315 return result;
316 }
317
Brian Salomon94efbf52016-11-29 13:43:05 -0500318 static sk_sp<GrShaderCaps> VariousCaps() {
319 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500320 result->fVersionDeclString = "#version 400";
321 result->fExternalTextureSupport = true;
322 result->fFBFetchSupport = false;
Ethan Nicholas3605ace2016-11-21 15:59:48 -0500323 result->fCanUseAnyFunctionInShader = false;
324 return result;
325 }
Brian Osmancd3261a2018-01-16 13:52:29 +0000326
327 static sk_sp<GrShaderCaps> CannotUseFragCoord() {
328 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
329 result->fVersionDeclString = "#version 400";
330 result->fCanUseFragCoord = false;
331 return result;
332 }
Chris Daltonc2d0dd62018-03-07 07:46:10 -0700333
334 static sk_sp<GrShaderCaps> IncompleteShortIntPrecision() {
335 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
336 result->fVersionDeclString = "#version 310es";
337 result->fUsesPrecisionModifiers = true;
338 result->fIncompleteShortIntPrecision = true;
339 return result;
340 }
Adrienne Walkeree8295c2018-08-21 10:56:30 -0700341
342 static sk_sp<GrShaderCaps> AddAndTrueToLoopCondition() {
343 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
344 result->fVersionDeclString = "#version 400";
345 result->fAddAndTrueToLoopCondition = true;
346 return result;
347 }
Adrienne Walkerc02165f2018-08-21 11:08:11 -0700348
349 static sk_sp<GrShaderCaps> UnfoldShortCircuitAsTernary() {
350 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
351 result->fVersionDeclString = "#version 400";
352 result->fUnfoldShortCircuitAsTernary = true;
353 return result;
354 }
Adrienne Walker92b161f2018-08-22 10:41:52 -0700355
356 static sk_sp<GrShaderCaps> EmulateAbsIntFunction() {
357 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
358 result->fVersionDeclString = "#version 400";
359 result->fEmulateAbsIntFunction = true;
360 return result;
361 }
Adrienne Walker8b23ca62018-08-22 10:45:41 -0700362
363 static sk_sp<GrShaderCaps> RewriteDoWhileLoops() {
364 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
365 result->fVersionDeclString = "#version 400";
366 result->fRewriteDoWhileLoops = true;
367 return result;
368 }
Adrienne Walker2f4c09b2018-08-22 16:04:57 -0700369
370 static sk_sp<GrShaderCaps> RemovePowWithConstantExponent() {
371 sk_sp<GrShaderCaps> result = sk_make_sp<GrShaderCaps>(GrContextOptions());
372 result->fVersionDeclString = "#version 400";
373 result->fRemovePowWithConstantExponent = true;
374 return result;
375 }
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500376};
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400377#endif
Ethan Nicholas7ef4b742016-11-11 15:16:46 -0500378
Ethan Nicholas0df1b042017-03-31 13:56:23 -0400379void write_stringstream(const StringStream& d, OutputStream& out);
ethannicholasb3058bd2016-07-01 08:22:01 -0700380
Ethan Nicholas0e9401d2019-03-21 11:05:37 -0400381// Returns true if op is '=' or any compound assignment operator ('+=', '-=', etc.)
382bool is_assignment(Token::Kind op);
383
384// Given a compound assignment operator, returns the non-assignment version of the operator (e.g.
385// '+=' becomes '+')
386Token::Kind remove_assignment(Token::Kind op);
387
ethannicholasb3058bd2016-07-01 08:22:01 -0700388NORETURN void sksl_abort();
389
390} // namespace
391
ethannicholasb3058bd2016-07-01 08:22:01 -0700392#endif