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
15static 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
27static 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
41GrShaderCaps::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
96SkString 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
176void 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
229void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
230    fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
231}
232