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
16GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
17 fGLSLGeneration = k330_GrGLSLGeneration;
18 fShaderDerivativeSupport = false;
19 fGeometryShaderSupport = false;
20 fGSInvocationsSupport = false;
21 fPathRenderingSupport = false;
22 fDstReadInShaderSupport = false;
23 fDualSourceBlendingSupport = false;
24 fIntegerSupport = 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 fCanOnlyUseSampleMaskWithStencil = 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 fColorSpaceMathNeedsFloat = false;
59 // Backed API support is required to be able to make swizzle-neutral shaders (e.g.
60 // GL_ARB_texture_swizzle).
61 fTextureSwizzleAppliedInShader = true;
62 fBuiltinFMASupport = false;
63 fCanUseDoLoops = true;
64
65 fVersionDeclString = nullptr;
66 fShaderDerivativeExtensionString = nullptr;
67 fGeometryShaderExtensionString = nullptr;
68 fGSInvocationsExtensionString = nullptr;
69 fFragCoordConventionsExtensionString = nullptr;
70 fSecondaryOutputExtensionString = nullptr;
71 fExternalTextureExtensionString = nullptr;
72 fSecondExternalTextureExtensionString = nullptr;
73 fNoPerspectiveInterpolationExtensionString = nullptr;
74 fSampleVariablesExtensionString = nullptr;
75 fTessellationExtensionString = nullptr;
76 fFBFetchColorName = nullptr;
77 fFBFetchExtensionString = nullptr;
78 fMaxFragmentSamplers = 0;
79 fMaxTessellationSegments = 0;
80 fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
81}
82
83#ifdef SK_ENABLE_DUMP_GPU
84void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const {
85 writer->beginObject();
86
87 writer->appendBool("Shader Derivative Support", fShaderDerivativeSupport);
88 writer->appendBool("Geometry Shader Support", fGeometryShaderSupport);
89 writer->appendBool("Geometry Shader Invocations Support", fGSInvocationsSupport);
90 writer->appendBool("Path Rendering Support", fPathRenderingSupport);
91 writer->appendBool("Dst Read In Shader Support", fDstReadInShaderSupport);
92 writer->appendBool("Dual Source Blending Support", fDualSourceBlendingSupport);
93 writer->appendBool("Integer Support", fIntegerSupport);
94
95 static const char* kAdvBlendEqInteractionStr[] = {
96 "Not Supported",
97 "Automatic",
98 "General Enable",
99 "Specific Enables",
100 };
101 static_assert(0 == kNotSupported_AdvBlendEqInteraction);
102 static_assert(1 == kAutomatic_AdvBlendEqInteraction);
103 static_assert(2 == kGeneralEnable_AdvBlendEqInteraction);
104 static_assert(3 == kSpecificEnables_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("Can only use sample mask with stencil", fCanOnlyUseSampleMaskWithStencil);
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("Texture swizzle applied in shader", fTextureSwizzleAppliedInShader);
144 writer->appendBool("Builtin fma() support", fBuiltinFMASupport);
145 writer->appendBool("Can use do-while loops", fCanUseDoLoops);
146
147 writer->appendS32("Max FS Samplers", fMaxFragmentSamplers);
148 writer->appendS32("Max Tessellation Segments", fMaxTessellationSegments);
149 writer->appendString("Advanced blend equation interaction",
150 kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
151
152 writer->endObject();
153}
154#else
155void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { }
156#endif
157
158void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
159 if (options.fDisableDriverCorrectnessWorkarounds) {
160 SkASSERT(fCanUseAnyFunctionInShader);
161 SkASSERT(fCanUseMinAndAbsTogether);
162 SkASSERT(fCanUseFractForNegativeValues);
163 SkASSERT(!fMustForceNegatedAtanParamToFloat);
164 SkASSERT(!fAtan2ImplementedAsAtanYOverX);
165 SkASSERT(!fMustDoOpBetweenFloorAndAbs);
166 SkASSERT(!fRequiresLocalOutputColorForFBFetch);
167 SkASSERT(!fMustObfuscateUniformColor);
168 SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck);
169 SkASSERT(!fInBlendModesFailRandomlyForAllZeroVec);
170 SkASSERT(fCanUseFragCoord);
171 SkASSERT(!fIncompleteShortIntPrecision);
172 SkASSERT(!fAddAndTrueToLoopCondition);
173 SkASSERT(!fUnfoldShortCircuitAsTernary);
174 SkASSERT(!fEmulateAbsIntFunction);
175 SkASSERT(!fRewriteDoWhileLoops);
176 SkASSERT(!fRemovePowWithConstantExponent);
177 SkASSERT(!fMustWriteToFragColor);
178 SkASSERT(!fNoDefaultPrecisionForExternalSamplers);
179 }
180#if GR_TEST_UTILS
181 if (options.fSuppressDualSourceBlending) {
182 fDualSourceBlendingSupport = false;
183 }
184 if (options.fSuppressGeometryShaders) {
185 fGeometryShaderSupport = false;
186 }
187 if (options.fSuppressTessellationShaders) {
188 fMaxTessellationSegments = 0;
189 }
190#endif
191}
192