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