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