• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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