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