1 /*
2  * Copyright 2012 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 
9 #include "src/gpu/GrShaderCaps.h"
10 
11 #include "include/gpu/GrContextOptions.h"
12 #include "src/utils/SkJSONWriter.h"
13 
14 ////////////////////////////////////////////////////////////////////////////////////////////
15 
GrShaderCaps(const GrContextOptions & options)16 GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
17     fGLSLGeneration = k330_GrGLSLGeneration;
18     fShaderDerivativeSupport = false;
19     fGeometryShaderSupport = false;
20     fGSInvocationsSupport = false;
21     fDstReadInShaderSupport = false;
22     fDualSourceBlendingSupport = false;
23     fIntegerSupport = false;
24     fNonsquareMatrixSupport = false;
25     fFBFetchSupport = false;
26     fFBFetchNeedsCustomOutput = false;
27     fUsesPrecisionModifiers = false;
28     fCanUseAnyFunctionInShader = true;
29     fCanUseMinAndAbsTogether = true;
30     fCanUseFractForNegativeValues = true;
31     fMustForceNegatedAtanParamToFloat = false;
32     fAtan2ImplementedAsAtanYOverX = false;
33     fMustDoOpBetweenFloorAndAbs = false;
34     fRequiresLocalOutputColorForFBFetch = false;
35     fMustObfuscateUniformColor = false;
36     fMustGuardDivisionEvenAfterExplicitZeroCheck = false;
37     fInBlendModesFailRandomlyForAllZeroVec = false;
38     fCanUseFragCoord = true;
39     fIncompleteShortIntPrecision = false;
40     fAddAndTrueToLoopCondition = false;
41     fUnfoldShortCircuitAsTernary = false;
42     fEmulateAbsIntFunction = false;
43     fRewriteDoWhileLoops = false;
44     fRemovePowWithConstantExponent = false;
45     fMustWriteToFragColor = false;
46     fNoDefaultPrecisionForExternalSamplers = false;
47     fRewriteMatrixVectorMultiply = false;
48     fFlatInterpolationSupport = false;
49     fPreferFlatInterpolation = false;
50     fNoPerspectiveInterpolationSupport = false;
51     fSampleMaskSupport = false;
52     fExternalTextureSupport = false;
53     fVertexIDSupport = false;
54     fFPManipulationSupport = false;
55     fFloatIs32Bits = true;
56     fHalfIs32Bits = false;
57     fHasLowFragmentPrecision = false;
58     fReducedShaderMode = false;
59     fColorSpaceMathNeedsFloat = false;
60     fBuiltinFMASupport = false;
61     fBuiltinDeterminantSupport = false;
62     fCanUseDoLoops = true;
63     fCanUseFastMath = false;
64     fUseNodePools = true;
65     fAvoidDfDxForGradientsWhenPossible = false;
66 
67     fVersionDeclString = nullptr;
68     fShaderDerivativeExtensionString = nullptr;
69     fGeometryShaderExtensionString = nullptr;
70     fGSInvocationsExtensionString = nullptr;
71     fFragCoordConventionsExtensionString = nullptr;
72     fSecondaryOutputExtensionString = nullptr;
73     fExternalTextureExtensionString = nullptr;
74     fSecondExternalTextureExtensionString = nullptr;
75     fNoPerspectiveInterpolationExtensionString = nullptr;
76     fSampleVariablesExtensionString = nullptr;
77     fTessellationExtensionString = nullptr;
78     fFBFetchColorName = nullptr;
79     fFBFetchExtensionString = nullptr;
80     fMaxFragmentSamplers = 0;
81     fMaxTessellationSegments = 0;
82     fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
83 }
84 
85 #ifdef SK_ENABLE_DUMP_GPU
dumpJSON(SkJSONWriter * writer) const86 void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
87     writer->beginObject();
88 
89     writer->appendBool("Shader Derivative Support", fShaderDerivativeSupport);
90     writer->appendBool("Geometry Shader Support", fGeometryShaderSupport);
91     writer->appendBool("Geometry Shader Invocations Support", fGSInvocationsSupport);
92     writer->appendBool("Dst Read In Shader Support", fDstReadInShaderSupport);
93     writer->appendBool("Dual Source Blending Support", fDualSourceBlendingSupport);
94     writer->appendBool("Integer Support", fIntegerSupport);
95     writer->appendBool("Nonsquare Matrix Support", fNonsquareMatrixSupport);
96 
97     static const char* kAdvBlendEqInteractionStr[] = {
98         "Not Supported",
99         "Automatic",
100         "General Enable",
101     };
102     static_assert(0 == kNotSupported_AdvBlendEqInteraction);
103     static_assert(1 == kAutomatic_AdvBlendEqInteraction);
104     static_assert(2 == kGeneralEnable_AdvBlendEqInteraction);
105     static_assert(SK_ARRAY_COUNT(kAdvBlendEqInteractionStr) == kLast_AdvBlendEqInteraction + 1);
106 
107     writer->appendBool("FB Fetch Support", fFBFetchSupport);
108     writer->appendBool("Uses precision modifiers", fUsesPrecisionModifiers);
109     writer->appendBool("Can use any() function", fCanUseAnyFunctionInShader);
110     writer->appendBool("Can use min() and abs() together", fCanUseMinAndAbsTogether);
111     writer->appendBool("Can use fract() for negative values", fCanUseFractForNegativeValues);
112     writer->appendBool("Must force negated atan param to float", fMustForceNegatedAtanParamToFloat);
113     writer->appendBool("Must do op between floor and abs", fMustDoOpBetweenFloorAndAbs);
114     writer->appendBool("Must use local out color for FBFetch", fRequiresLocalOutputColorForFBFetch);
115     writer->appendBool("Must obfuscate uniform color", fMustObfuscateUniformColor);
116     writer->appendBool("Must guard division even after explicit zero check",
117                        fMustGuardDivisionEvenAfterExplicitZeroCheck);
118     writer->appendBool(
119             "src-in and dst-in blend modes may return (0,0,0,1) when dst/src is all zeros",
120             fInBlendModesFailRandomlyForAllZeroVec);
121     writer->appendBool("Can use gl_FragCoord", fCanUseFragCoord);
122     writer->appendBool("Incomplete short int precision", fIncompleteShortIntPrecision);
123     writer->appendBool("Add and true to loops workaround", fAddAndTrueToLoopCondition);
124     writer->appendBool("Unfold short circuit as ternary", fUnfoldShortCircuitAsTernary);
125     writer->appendBool("Emulate abs(int) function", fEmulateAbsIntFunction);
126     writer->appendBool("Rewrite do while loops", fRewriteDoWhileLoops);
127     writer->appendBool("Rewrite pow with constant exponent", fRemovePowWithConstantExponent);
128     writer->appendBool("Must write to sk_FragColor [workaround]", fMustWriteToFragColor);
129     writer->appendBool("Don't add default precision statement for samplerExternalOES",
130                        fNoDefaultPrecisionForExternalSamplers);
131     writer->appendBool("Rewrite matrix-vector multiply", fRewriteMatrixVectorMultiply);
132     writer->appendBool("Flat interpolation support", fFlatInterpolationSupport);
133     writer->appendBool("Prefer flat interpolation", fPreferFlatInterpolation);
134     writer->appendBool("No perspective interpolation support", fNoPerspectiveInterpolationSupport);
135     writer->appendBool("Sample mask support", fSampleMaskSupport);
136     writer->appendBool("External texture support", fExternalTextureSupport);
137     writer->appendBool("sk_VertexID support", fVertexIDSupport);
138     writer->appendBool("Floating point manipulation support", fFPManipulationSupport);
139     writer->appendBool("float == fp32", fFloatIs32Bits);
140     writer->appendBool("half == fp32", fHalfIs32Bits);
141     writer->appendBool("Has poor fragment precision", fHasLowFragmentPrecision);
142     writer->appendBool("Color space math needs float", fColorSpaceMathNeedsFloat);
143     writer->appendBool("Builtin fma() support", fBuiltinFMASupport);
144     writer->appendBool("Builtin determinant() support", fBuiltinDeterminantSupport);
145     writer->appendBool("Can use do-while loops", fCanUseDoLoops);
146     writer->appendBool("Use node pools", fUseNodePools);
147 
148     writer->appendS32("Max FS Samplers", fMaxFragmentSamplers);
149     writer->appendS32("Max Tessellation Segments", fMaxTessellationSegments);
150     writer->appendString("Advanced blend equation interaction",
151                          kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
152 
153     writer->endObject();
154 }
155 #else
dumpJSON(SkJSONWriter * writer) const156 void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { }
157 #endif
158 
applyOptionsOverrides(const GrContextOptions & options)159 void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
160     if (options.fDisableDriverCorrectnessWorkarounds) {
161         SkASSERT(fCanUseAnyFunctionInShader);
162         SkASSERT(fCanUseMinAndAbsTogether);
163         SkASSERT(fCanUseFractForNegativeValues);
164         SkASSERT(!fMustForceNegatedAtanParamToFloat);
165         SkASSERT(!fAtan2ImplementedAsAtanYOverX);
166         SkASSERT(!fMustDoOpBetweenFloorAndAbs);
167         SkASSERT(!fRequiresLocalOutputColorForFBFetch);
168         SkASSERT(!fMustObfuscateUniformColor);
169         SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck);
170         SkASSERT(!fInBlendModesFailRandomlyForAllZeroVec);
171         SkASSERT(fCanUseFragCoord);
172         SkASSERT(!fIncompleteShortIntPrecision);
173         SkASSERT(!fAddAndTrueToLoopCondition);
174         SkASSERT(!fUnfoldShortCircuitAsTernary);
175         SkASSERT(!fEmulateAbsIntFunction);
176         SkASSERT(!fRewriteDoWhileLoops);
177         SkASSERT(!fRemovePowWithConstantExponent);
178         SkASSERT(!fMustWriteToFragColor);
179         SkASSERT(!fNoDefaultPrecisionForExternalSamplers);
180         SkASSERT(!fRewriteMatrixVectorMultiply);
181     }
182     if (!options.fEnableExperimentalHardwareTessellation) {
183         fMaxTessellationSegments = 0;
184     }
185     if (options.fReducedShaderVariations) {
186         fReducedShaderMode = true;
187     }
188 #if GR_TEST_UTILS
189     if (options.fSuppressDualSourceBlending) {
190         fDualSourceBlendingSupport = false;
191     }
192     if (options.fSuppressGeometryShaders) {
193         fGeometryShaderSupport = false;
194     }
195     if (options.fMaxTessellationSegmentsOverride > 0) {
196         fMaxTessellationSegments = std::min(options.fMaxTessellationSegmentsOverride,
197                                             fMaxTessellationSegments);
198     }
199 #endif
200 }
201