• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "include/private/SkSLDefines.h"
16 #ifdef SKSL_EXT
17 #include "src/sksl/SkSLLexerExt.h"
18 #else
19 #include "src/sksl/SkSLLexer.h"
20 #endif
21 
22 #ifndef SKSL_STANDALONE
23 #include "include/core/SkTypes.h"
24 #if SK_SUPPORT_GPU
25 #include "include/gpu/GrContextOptions.h"
26 #include "include/private/GrTypesPriv.h"
27 #include "src/gpu/GrShaderCaps.h"
28 #endif // SK_SUPPORT_GPU
29 #endif // SKSL_STANDALONE
30 
31 class GrShaderCaps;
32 
33 namespace SkSL {
34 
35 class Context;
36 class OutputStream;
37 class StringStream;
38 class Type;
39 
40 #if defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
41 
42 // we're being compiled standalone, so we don't have access to caps...
43 enum GrGLSLGeneration {
44     k110_GrGLSLGeneration,
45     k130_GrGLSLGeneration,
46     k140_GrGLSLGeneration,
47     k150_GrGLSLGeneration,
48     k330_GrGLSLGeneration,
49     k400_GrGLSLGeneration,
50     k420_GrGLSLGeneration,
51     k310es_GrGLSLGeneration,
52     k320es_GrGLSLGeneration,
53 };
54 
55 class StandaloneShaderCaps {
56 public:
57     GrGLSLGeneration fGLSLGeneration = k400_GrGLSLGeneration;
generation()58     GrGLSLGeneration generation() const {
59         return fGLSLGeneration;
60     }
61 
62     bool fAtan2ImplementedAsAtanYOverX = false;
atan2ImplementedAsAtanYOverX()63     bool atan2ImplementedAsAtanYOverX() const {
64         return fAtan2ImplementedAsAtanYOverX;
65     }
66 
67     bool fCanUseMinAndAbsTogether = true;
canUseMinAndAbsTogether()68     bool canUseMinAndAbsTogether() const {
69         return fCanUseMinAndAbsTogether;
70     }
71 
72     bool fMustForceNegatedAtanParamToFloat = false;
mustForceNegatedAtanParamToFloat()73     bool mustForceNegatedAtanParamToFloat() const {
74         return fMustForceNegatedAtanParamToFloat;
75     }
76 
77     bool fMustForceNegatedLdexpParamToMultiply = false;
mustForceNegatedLdexpParamToMultiply()78     bool mustForceNegatedLdexpParamToMultiply() const {
79         return fMustForceNegatedLdexpParamToMultiply;
80     }
81 
82     bool fShaderDerivativeSupport = true;
shaderDerivativeSupport()83     bool shaderDerivativeSupport() const {
84         return fShaderDerivativeSupport;
85     }
86 
87     bool fUsesPrecisionModifiers = false;
usesPrecisionModifiers()88     bool usesPrecisionModifiers() const {
89         return fUsesPrecisionModifiers;
90     }
91 
mustDeclareFragmentShaderOutput()92     bool mustDeclareFragmentShaderOutput() const {
93         return fGLSLGeneration > k110_GrGLSLGeneration;
94     }
95 
96     bool fFBFetchSupport = false;
fbFetchSupport()97     bool fbFetchSupport() const {
98         return fFBFetchSupport;
99     }
100 
101     bool fFBFetchNeedsCustomOutput = false;
fbFetchNeedsCustomOutput()102     bool fbFetchNeedsCustomOutput() const {
103         return fFBFetchNeedsCustomOutput;
104     }
105 
106     bool fFlatInterpolationSupport = true;
flatInterpolationSupport()107     bool flatInterpolationSupport() const {
108         return fFlatInterpolationSupport;
109     }
110 
111     bool fNoperspectiveInterpolationSupport = true;
noperspectiveInterpolationSupport()112     bool noperspectiveInterpolationSupport() const {
113         return fNoperspectiveInterpolationSupport;
114     }
115 
116     bool fMultisampleInterpolationSupport = true;
multisampleInterpolationSupport()117     bool multisampleInterpolationSupport() const {
118         return fMultisampleInterpolationSupport;
119     }
120 
121     bool fSampleMaskSupport = true;
sampleMaskSupport()122     bool sampleMaskSupport() const {
123         return fSampleMaskSupport;
124     }
125 
126     bool fExternalTextureSupport = true;
externalTextureSupport()127     bool externalTextureSupport() const {
128         return fExternalTextureSupport;
129     }
130 
131     bool fMustDoOpBetweenFloorAndAbs = false;
mustDoOpBetweenFloorAndAbs()132     bool mustDoOpBetweenFloorAndAbs() const {
133         return fMustDoOpBetweenFloorAndAbs;
134     }
135 
136     bool fMustGuardDivisionEvenAfterExplicitZeroCheck = false;
mustGuardDivisionEvenAfterExplicitZeroCheck()137     bool mustGuardDivisionEvenAfterExplicitZeroCheck() const {
138         return fMustGuardDivisionEvenAfterExplicitZeroCheck;
139     }
140 
141     bool fMustEnableAdvBlendEqs = false;
mustEnableAdvBlendEqs()142     bool mustEnableAdvBlendEqs() const {
143         return fMustEnableAdvBlendEqs;
144     }
145 
146     bool fCanUseAnyFunctionInShader = true;
canUseAnyFunctionInShader()147     bool canUseAnyFunctionInShader() const {
148         return fCanUseAnyFunctionInShader;
149     }
150 
151     bool fNoDefaultPrecisionForExternalSamplers = false;
noDefaultPrecisionForExternalSamplers()152     bool noDefaultPrecisionForExternalSamplers() const {
153         return fNoDefaultPrecisionForExternalSamplers;
154     }
155 
156     bool fFloatIs32Bits = true;
floatIs32Bits()157     bool floatIs32Bits() const {
158         return fFloatIs32Bits;
159     }
160 
161     bool fIntegerSupport = false;
integerSupport()162     bool integerSupport() const {
163         return fIntegerSupport;
164     }
165 
166     bool fNonsquareMatrixSupport = false;
nonsquareMatrixSupport()167     bool nonsquareMatrixSupport() const {
168         return fNonsquareMatrixSupport;
169     }
170 
171     bool fInverseHyperbolicSupport = false;
inverseHyperbolicSupport()172     bool inverseHyperbolicSupport() const {
173         return fInverseHyperbolicSupport;
174     }
175 
176     bool fBuiltinFMASupport = false;
builtinFMASupport()177     bool builtinFMASupport() const {
178         return fBuiltinFMASupport;
179     }
180 
181     bool fBuiltinDeterminantSupport = false;
builtinDeterminantSupport()182     bool builtinDeterminantSupport() const {
183         return fBuiltinDeterminantSupport;
184     }
185 
186     bool fCanUseDoLoops = false;
canUseDoLoops()187     bool canUseDoLoops() const {
188         // we define this to false in standalone so we don't use do loops while inlining in FP files
189         // (which would then, being baked in, end up being used even in contexts where do loops are
190         // not allowed)
191         return fCanUseDoLoops;
192     }
193 
194     bool fUseNodePools = true;
useNodePools()195     bool useNodePools() const {
196         return fUseNodePools;
197     }
198 
199     const char* fShaderDerivativeExtensionString = nullptr;
shaderDerivativeExtensionString()200     const char* shaderDerivativeExtensionString() const {
201         return fShaderDerivativeExtensionString;
202     }
203 
204     const char* fFragCoordConventionsExtensionString = nullptr;
fragCoordConventionsExtensionString()205     const char* fragCoordConventionsExtensionString() const {
206         return fFragCoordConventionsExtensionString;
207     }
208 
209     const char* fExternalTextureExtensionString = nullptr;
externalTextureExtensionString()210     const char* externalTextureExtensionString() const {
211         return fExternalTextureExtensionString;
212     }
213 
214     const char* fSecondExternalTextureExtensionString = nullptr;
secondExternalTextureExtensionString()215     const char* secondExternalTextureExtensionString() const {
216         return fSecondExternalTextureExtensionString;
217     }
218 
219     const char* fVersionDeclString = "";
versionDeclString()220     const char* versionDeclString() const {
221         return fVersionDeclString;
222     }
223 
224     bool fCanUseFractForNegativeValues = true;
canUseFractForNegativeValues()225     bool canUseFractForNegativeValues() const {
226         return fCanUseFractForNegativeValues;
227     }
228 
229     bool fCanUseFragCoord = true;
canUseFragCoord()230     bool canUseFragCoord() const {
231         return fCanUseFragCoord;
232     }
233 
234     bool fIncompleteShortIntPrecision = false;
incompleteShortIntPrecision()235     bool incompleteShortIntPrecision() const {
236         return fIncompleteShortIntPrecision;
237     }
238 
239     bool fAddAndTrueToLoopCondition = false;
addAndTrueToLoopCondition()240     bool addAndTrueToLoopCondition() const {
241         return fAddAndTrueToLoopCondition;
242     }
243 
244     bool fUnfoldShortCircuitAsTernary = false;
unfoldShortCircuitAsTernary()245     bool unfoldShortCircuitAsTernary() const {
246         return fUnfoldShortCircuitAsTernary;
247     }
248 
249     bool fEmulateAbsIntFunction = false;
emulateAbsIntFunction()250     bool emulateAbsIntFunction() const {
251         return fEmulateAbsIntFunction;
252     }
253 
254     bool fRewriteDoWhileLoops = false;
rewriteDoWhileLoops()255     bool rewriteDoWhileLoops() const {
256         return fRewriteDoWhileLoops;
257     }
258 
259     bool fRewriteSwitchStatements = false;
rewriteSwitchStatements()260     bool rewriteSwitchStatements() const {
261         return fRewriteSwitchStatements;
262     }
263 
264     bool fRemovePowWithConstantExponent = false;
removePowWithConstantExponent()265     bool removePowWithConstantExponent() const {
266         return fRemovePowWithConstantExponent;
267     }
268 
269     const char* fFBFetchColorName = nullptr;
fbFetchColorName()270     const char* fbFetchColorName() const {
271         return fFBFetchColorName;
272     }
273 
274     bool fRewriteMatrixVectorMultiply = false;
rewriteMatrixVectorMultiply()275     bool rewriteMatrixVectorMultiply() const {
276         return fRewriteMatrixVectorMultiply;
277     }
278 
279     bool fRewriteMatrixComparisons = false;
rewriteMatrixComparisons()280     bool rewriteMatrixComparisons() const {
281         return fRewriteMatrixComparisons;
282     }
283 };
284 
285 using ShaderCapsClass = StandaloneShaderCaps;
286 using ShaderCapsPointer = std::unique_ptr<StandaloneShaderCaps>;
287 
288 #else
289 
290 using ShaderCapsClass = GrShaderCaps;
291 using ShaderCapsPointer = std::unique_ptr<GrShaderCaps>;
292 
293 #endif  // defined(SKSL_STANDALONE) || !SK_SUPPORT_GPU
294 
295 // Various sets of caps for use in tests
296 class SK_API ShaderCapsFactory {
297 public:
Default()298     static ShaderCapsPointer Default() {
299         ShaderCapsPointer result = MakeShaderCaps();
300         result->fVersionDeclString = "#version 400";
301         result->fShaderDerivativeSupport = true;
302         result->fBuiltinDeterminantSupport = true;
303         result->fCanUseDoLoops = true;
304         return result;
305     }
306 
Standalone()307     static ShaderCapsPointer Standalone() {
308         return MakeShaderCaps();
309     }
310 
AddAndTrueToLoopCondition()311     static ShaderCapsPointer AddAndTrueToLoopCondition() {
312         ShaderCapsPointer result = MakeShaderCaps();
313         result->fVersionDeclString = "#version 400";
314         result->fAddAndTrueToLoopCondition = true;
315         return result;
316     }
317 
CannotUseFractForNegativeValues()318     static ShaderCapsPointer CannotUseFractForNegativeValues() {
319         ShaderCapsPointer result = MakeShaderCaps();
320         result->fVersionDeclString = "#version 400";
321         result->fCanUseFractForNegativeValues = false;
322         return result;
323     }
324 
CannotUseFragCoord()325     static ShaderCapsPointer CannotUseFragCoord() {
326         ShaderCapsPointer result = MakeShaderCaps();
327         result->fVersionDeclString = "#version 400";
328         result->fCanUseFragCoord = false;
329         return result;
330     }
331 
CannotUseMinAndAbsTogether()332     static ShaderCapsPointer CannotUseMinAndAbsTogether() {
333         ShaderCapsPointer result = MakeShaderCaps();
334         result->fVersionDeclString = "#version 400";
335         result->fCanUseMinAndAbsTogether = false;
336         return result;
337     }
338 
EmulateAbsIntFunction()339     static ShaderCapsPointer EmulateAbsIntFunction() {
340         ShaderCapsPointer result = MakeShaderCaps();
341         result->fVersionDeclString = "#version 400";
342         result->fEmulateAbsIntFunction = true;
343         return result;
344     }
345 
FramebufferFetchSupport()346     static ShaderCapsPointer FramebufferFetchSupport() {
347         ShaderCapsPointer result = MakeShaderCaps();
348         result->fFBFetchSupport = true;
349         result->fFBFetchColorName = "gl_LastFragData[0]";
350         return result;
351     }
352 
IncompleteShortIntPrecision()353     static ShaderCapsPointer IncompleteShortIntPrecision() {
354         ShaderCapsPointer result = MakeShaderCaps();
355         result->fVersionDeclString = "#version 310es";
356         result->fUsesPrecisionModifiers = true;
357         result->fIncompleteShortIntPrecision = true;
358         return result;
359     }
360 
MustForceNegatedAtanParamToFloat()361     static ShaderCapsPointer MustForceNegatedAtanParamToFloat() {
362         ShaderCapsPointer result = MakeShaderCaps();
363         result->fVersionDeclString = "#version 400";
364         result->fMustForceNegatedAtanParamToFloat = true;
365         return result;
366     }
367 
MustForceNegatedLdexpParamToMultiply()368     static ShaderCapsPointer MustForceNegatedLdexpParamToMultiply() {
369         ShaderCapsPointer result = MakeShaderCaps();
370         result->fVersionDeclString = "#version 400";
371         result->fMustForceNegatedLdexpParamToMultiply = true;
372         return result;
373     }
374 
MustGuardDivisionEvenAfterExplicitZeroCheck()375     static ShaderCapsPointer MustGuardDivisionEvenAfterExplicitZeroCheck() {
376         ShaderCapsPointer result = MakeShaderCaps();
377         result->fMustGuardDivisionEvenAfterExplicitZeroCheck = true;
378         return result;
379     }
380 
RemovePowWithConstantExponent()381     static ShaderCapsPointer RemovePowWithConstantExponent() {
382         ShaderCapsPointer result = MakeShaderCaps();
383         result->fVersionDeclString = "#version 400";
384         result->fRemovePowWithConstantExponent = true;
385         return result;
386     }
387 
RewriteDoWhileLoops()388     static ShaderCapsPointer RewriteDoWhileLoops() {
389         ShaderCapsPointer result = MakeShaderCaps();
390         result->fVersionDeclString = "#version 400";
391         result->fRewriteDoWhileLoops = true;
392         return result;
393     }
394 
RewriteMatrixComparisons()395     static ShaderCapsPointer RewriteMatrixComparisons() {
396         ShaderCapsPointer result = MakeShaderCaps();
397         result->fRewriteMatrixComparisons = true;
398         result->fUsesPrecisionModifiers = true;
399         return result;
400     }
401 
RewriteMatrixVectorMultiply()402     static ShaderCapsPointer RewriteMatrixVectorMultiply() {
403         ShaderCapsPointer result = MakeShaderCaps();
404         result->fVersionDeclString = "#version 400";
405         result->fRewriteMatrixVectorMultiply = true;
406         return result;
407     }
408 
RewriteSwitchStatements()409     static ShaderCapsPointer RewriteSwitchStatements() {
410         ShaderCapsPointer result = MakeShaderCaps();
411         result->fVersionDeclString = "#version 400";
412         result->fRewriteSwitchStatements = true;
413         return result;
414     }
415 
SampleMaskSupport()416     static ShaderCapsPointer SampleMaskSupport() {
417         ShaderCapsPointer result = Default();
418         result->fSampleMaskSupport = true;
419         return result;
420     }
421 
ShaderDerivativeExtensionString()422     static ShaderCapsPointer ShaderDerivativeExtensionString() {
423         ShaderCapsPointer result = MakeShaderCaps();
424         result->fVersionDeclString = "#version 400";
425         result->fShaderDerivativeSupport = true;
426         result->fShaderDerivativeExtensionString = "GL_OES_standard_derivatives";
427         result->fUsesPrecisionModifiers = true;
428         return result;
429     }
430 
UnfoldShortCircuitAsTernary()431     static ShaderCapsPointer UnfoldShortCircuitAsTernary() {
432         ShaderCapsPointer result = MakeShaderCaps();
433         result->fVersionDeclString = "#version 400";
434         result->fUnfoldShortCircuitAsTernary = true;
435         return result;
436     }
437 
UsesPrecisionModifiers()438     static ShaderCapsPointer UsesPrecisionModifiers() {
439         ShaderCapsPointer result = MakeShaderCaps();
440         result->fVersionDeclString = "#version 400";
441         result->fUsesPrecisionModifiers = true;
442         return result;
443     }
444 
Version110()445     static ShaderCapsPointer Version110() {
446         ShaderCapsPointer result = MakeShaderCaps();
447         result->fVersionDeclString = "#version 110";
448         result->fGLSLGeneration = GrGLSLGeneration::k110_GrGLSLGeneration;
449         return result;
450     }
451 
Version450Core()452     static ShaderCapsPointer Version450Core() {
453         ShaderCapsPointer result = MakeShaderCaps();
454         result->fVersionDeclString = "#version 450 core";
455         return result;
456     }
457 
458 private:
459     static ShaderCapsPointer MakeShaderCaps();
460 };
461 
462 #if !defined(SKSL_STANDALONE) && SK_SUPPORT_GPU
463 bool type_to_grsltype(const Context& context, const Type& type, GrSLType* outType);
464 #endif
465 
466 void write_stringstream(const StringStream& d, OutputStream& out);
467 
468 }  // namespace SkSL
469 
470 #endif  // SKSL_UTIL
471