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 "GrShaderCaps.h"
10
11 #include "GrContextOptions.h"
12
13 ////////////////////////////////////////////////////////////////////////////////////////////
14
shader_type_to_string(GrShaderType type)15 static const char* shader_type_to_string(GrShaderType type) {
16 switch (type) {
17 case kVertex_GrShaderType:
18 return "vertex";
19 case kGeometry_GrShaderType:
20 return "geometry";
21 case kFragment_GrShaderType:
22 return "fragment";
23 }
24 return "";
25 }
26
precision_to_string(GrSLPrecision p)27 static const char* precision_to_string(GrSLPrecision p) {
28 switch (p) {
29 case kLow_GrSLPrecision:
30 return "low";
31 case kMedium_GrSLPrecision:
32 return "medium";
33 case kHigh_GrSLPrecision:
34 return "high";
35 default:
36 SkFAIL("Unexpected precision type.");
37 return "";
38 }
39 }
40
GrShaderCaps(const GrContextOptions & options)41 GrShaderCaps::GrShaderCaps(const GrContextOptions& options) {
42 fGLSLGeneration = k330_GrGLSLGeneration;
43 fShaderDerivativeSupport = false;
44 fGeometryShaderSupport = false;
45 fPathRenderingSupport = false;
46 fDstReadInShaderSupport = false;
47 fDualSourceBlendingSupport = false;
48 fIntegerSupport = false;
49 fTexelBufferSupport = false;
50 fImageLoadStoreSupport = false;
51 fShaderPrecisionVaries = false;
52 fDropsTileOnZeroDivide = false;
53 fFBFetchSupport = false;
54 fFBFetchNeedsCustomOutput = false;
55 fBindlessTextureSupport = false;
56 fUsesPrecisionModifiers = false;
57 fCanUseAnyFunctionInShader = true;
58 fCanUseMinAndAbsTogether = true;
59 fMustForceNegatedAtanParamToFloat = false;
60 fAtan2ImplementedAsAtanYOverX = false;
61 fRequiresLocalOutputColorForFBFetch = false;
62 fMustImplementGSInvocationsWithLoop = false;
63 fMustObfuscateUniformColor = false;
64 fFlatInterpolationSupport = false;
65 fNoPerspectiveInterpolationSupport = false;
66 fMultisampleInterpolationSupport = false;
67 fSampleVariablesSupport = false;
68 fSampleMaskOverrideCoverageSupport = false;
69 fExternalTextureSupport = false;
70 fTexelFetchSupport = false;
71 fVertexIDSupport = false;
72
73 fVersionDeclString = nullptr;
74 fShaderDerivativeExtensionString = nullptr;
75 fFragCoordConventionsExtensionString = nullptr;
76 fSecondaryOutputExtensionString = nullptr;
77 fExternalTextureExtensionString = nullptr;
78 fTexelBufferExtensionString = nullptr;
79 fNoPerspectiveInterpolationExtensionString = nullptr;
80 fMultisampleInterpolationExtensionString = nullptr;
81 fSampleVariablesExtensionString = nullptr;
82 fFBFetchColorName = nullptr;
83 fFBFetchExtensionString = nullptr;
84 fImageLoadStoreExtensionString = nullptr;
85 fMaxVertexSamplers = 0;
86 fMaxGeometrySamplers = 0;
87 fMaxFragmentSamplers = 0;
88 fMaxCombinedSamplers = 0;
89 fMaxVertexImageStorages = 0;
90 fMaxGeometryImageStorages = 0;
91 fMaxFragmentImageStorages = 0;
92 fMaxCombinedImageStorages = 0;
93 fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction;
94 }
95
dump() const96 SkString GrShaderCaps::dump() const {
97 SkString r;
98 static const char* gNY[] = { "NO", "YES" };
99 r.appendf("Shader Derivative Support : %s\n", gNY[fShaderDerivativeSupport]);
100 r.appendf("Geometry Shader Support : %s\n", gNY[fGeometryShaderSupport]);
101 r.appendf("Path Rendering Support : %s\n", gNY[fPathRenderingSupport]);
102 r.appendf("Dst Read In Shader Support : %s\n", gNY[fDstReadInShaderSupport]);
103 r.appendf("Dual Source Blending Support : %s\n", gNY[fDualSourceBlendingSupport]);
104 r.appendf("Integer Support : %s\n", gNY[fIntegerSupport]);
105 r.appendf("Texel Buffer Support : %s\n", gNY[fTexelBufferSupport]);
106 r.appendf("Image Load Store Support : %s\n", gNY[fImageLoadStoreSupport]);
107
108 r.appendf("Shader Float Precisions (varies: %s):\n", gNY[fShaderPrecisionVaries]);
109
110 for (int s = 0; s < kGrShaderTypeCount; ++s) {
111 GrShaderType shaderType = static_cast<GrShaderType>(s);
112 r.appendf("\t%s:\n", shader_type_to_string(shaderType));
113 for (int p = 0; p < kGrSLPrecisionCount; ++p) {
114 if (fFloatPrecisions[s][p].supported()) {
115 GrSLPrecision precision = static_cast<GrSLPrecision>(p);
116 r.appendf("\t\t%s: log_low: %d log_high: %d bits: %d\n",
117 precision_to_string(precision),
118 fFloatPrecisions[s][p].fLogRangeLow,
119 fFloatPrecisions[s][p].fLogRangeHigh,
120 fFloatPrecisions[s][p].fBits);
121 }
122 }
123 }
124
125 static const char* kAdvBlendEqInteractionStr[] = {
126 "Not Supported",
127 "Automatic",
128 "General Enable",
129 "Specific Enables",
130 };
131 GR_STATIC_ASSERT(0 == kNotSupported_AdvBlendEqInteraction);
132 GR_STATIC_ASSERT(1 == kAutomatic_AdvBlendEqInteraction);
133 GR_STATIC_ASSERT(2 == kGeneralEnable_AdvBlendEqInteraction);
134 GR_STATIC_ASSERT(3 == kSpecificEnables_AdvBlendEqInteraction);
135 GR_STATIC_ASSERT(SK_ARRAY_COUNT(kAdvBlendEqInteractionStr) == kLast_AdvBlendEqInteraction + 1);
136
137 r.appendf("--- GLSL-Specific ---\n");
138
139 r.appendf("FB Fetch Support: %s\n", (fFBFetchSupport ? "YES" : "NO"));
140 r.appendf("Drops tile on zero divide: %s\n", (fDropsTileOnZeroDivide ? "YES" : "NO"));
141 r.appendf("Bindless texture support: %s\n", (fBindlessTextureSupport ? "YES" : "NO"));
142 r.appendf("Uses precision modifiers: %s\n", (fUsesPrecisionModifiers ? "YES" : "NO"));
143 r.appendf("Can use any() function: %s\n", (fCanUseAnyFunctionInShader ? "YES" : "NO"));
144 r.appendf("Can use min() and abs() together: %s\n", (fCanUseMinAndAbsTogether ? "YES" : "NO"));
145 r.appendf("Must force negated atan param to float: %s\n", (fMustForceNegatedAtanParamToFloat ?
146 "YES" : "NO"));
147 r.appendf("Must use local out color for FBFetch: %s\n", (fRequiresLocalOutputColorForFBFetch ?
148 "YES" : "NO"));
149 r.appendf("Must implement geo shader invocations with loop : %s\n",
150 (fMustImplementGSInvocationsWithLoop ? "YES" : "NO"));
151 r.appendf("Must obfuscate uniform color: %s\n", (fMustObfuscateUniformColor ? "YES" : "NO"));
152 r.appendf("Flat interpolation support: %s\n", (fFlatInterpolationSupport ? "YES" : "NO"));
153 r.appendf("No perspective interpolation support: %s\n", (fNoPerspectiveInterpolationSupport ?
154 "YES" : "NO"));
155 r.appendf("Multisample interpolation support: %s\n", (fMultisampleInterpolationSupport ?
156 "YES" : "NO"));
157 r.appendf("Sample variables support: %s\n", (fSampleVariablesSupport ? "YES" : "NO"));
158 r.appendf("Sample mask override coverage support: %s\n", (fSampleMaskOverrideCoverageSupport ?
159 "YES" : "NO"));
160 r.appendf("External texture support: %s\n", (fExternalTextureSupport ? "YES" : "NO"));
161 r.appendf("texelFetch support: %s\n", (fTexelFetchSupport ? "YES" : "NO"));
162 r.appendf("sk_VertexID support: %s\n", (fVertexIDSupport ? "YES" : "NO"));
163 r.appendf("Max VS Samplers: %d\n", fMaxVertexSamplers);
164 r.appendf("Max GS Samplers: %d\n", fMaxGeometrySamplers);
165 r.appendf("Max FS Samplers: %d\n", fMaxFragmentSamplers);
166 r.appendf("Max Combined Samplers: %d\n", fMaxFragmentSamplers);
167 r.appendf("Max VS Image Storages: %d\n", fMaxVertexImageStorages);
168 r.appendf("Max GS Image Storages: %d\n", fMaxGeometryImageStorages);
169 r.appendf("Max FS Image Storages: %d\n", fMaxFragmentImageStorages);
170 r.appendf("Max Combined Image Storages: %d\n", fMaxFragmentImageStorages);
171 r.appendf("Advanced blend equation interaction: %s\n",
172 kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]);
173 return r;
174 }
175
initSamplerPrecisionTable()176 void GrShaderCaps::initSamplerPrecisionTable() {
177 // Determine the largest precision qualifiers that are effectively the same as lowp/mediump.
178 // e.g. if lowp == mediump, then use mediump instead of lowp.
179 GrSLPrecision effectiveMediumP[kGrShaderTypeCount];
180 GrSLPrecision effectiveLowP[kGrShaderTypeCount];
181 for (int s = 0; s < kGrShaderTypeCount; ++s) {
182 const PrecisionInfo* info = fFloatPrecisions[s];
183 effectiveMediumP[s] = info[kHigh_GrSLPrecision] == info[kMedium_GrSLPrecision] ?
184 kHigh_GrSLPrecision : kMedium_GrSLPrecision;
185 effectiveLowP[s] = info[kMedium_GrSLPrecision] == info[kLow_GrSLPrecision] ?
186 effectiveMediumP[s] : kLow_GrSLPrecision;
187 }
188
189 // Determine which precision qualifiers should be used with samplers.
190 for (int visibility = 0; visibility < (1 << kGrShaderTypeCount); ++visibility) {
191 GrSLPrecision mediump = kHigh_GrSLPrecision;
192 GrSLPrecision lowp = kHigh_GrSLPrecision;
193 for (int s = 0; s < kGrShaderTypeCount; ++s) {
194 if (visibility & (1 << s)) {
195 mediump = SkTMin(mediump, effectiveMediumP[s]);
196 lowp = SkTMin(lowp, effectiveLowP[s]);
197 }
198
199 GR_STATIC_ASSERT(0 == kLow_GrSLPrecision);
200 GR_STATIC_ASSERT(1 == kMedium_GrSLPrecision);
201 GR_STATIC_ASSERT(2 == kHigh_GrSLPrecision);
202
203 GR_STATIC_ASSERT((1 << kVertex_GrShaderType) == kVertex_GrShaderFlag);
204 GR_STATIC_ASSERT((1 << kGeometry_GrShaderType) == kGeometry_GrShaderFlag);
205 GR_STATIC_ASSERT((1 << kFragment_GrShaderType) == kFragment_GrShaderFlag);
206 GR_STATIC_ASSERT(3 == kGrShaderTypeCount);
207 }
208
209 uint8_t* table = fSamplerPrecisions[visibility];
210 table[kUnknown_GrPixelConfig] = lowp;
211 table[kAlpha_8_GrPixelConfig] = lowp;
212 table[kGray_8_GrPixelConfig] = lowp;
213 table[kRGB_565_GrPixelConfig] = lowp;
214 table[kRGBA_4444_GrPixelConfig] = lowp;
215 table[kRGBA_8888_GrPixelConfig] = lowp;
216 table[kBGRA_8888_GrPixelConfig] = lowp;
217 table[kSRGBA_8888_GrPixelConfig] = lowp;
218 table[kSBGRA_8888_GrPixelConfig] = lowp;
219 table[kRGBA_8888_sint_GrPixelConfig] = lowp;
220 table[kRGBA_float_GrPixelConfig] = kHigh_GrSLPrecision;
221 table[kRG_float_GrPixelConfig] = kHigh_GrSLPrecision;
222 table[kAlpha_half_GrPixelConfig] = mediump;
223 table[kRGBA_half_GrPixelConfig] = mediump;
224
225 GR_STATIC_ASSERT(14 == kGrPixelConfigCnt);
226 }
227 }
228
applyOptionsOverrides(const GrContextOptions & options)229 void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
230 fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
231 }
232