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