| 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 "src/gpu/GrShaderCaps.h" |
| 10 | |
| 11 | #include "include/gpu/GrContextOptions.h" |
| 12 | #include "src/utils/SkJSONWriter.h" |
| 13 | |
| 14 | //////////////////////////////////////////////////////////////////////////////////////////// |
| 15 | |
| 16 | GrShaderCaps::GrShaderCaps(const GrContextOptions& options) { |
| 17 | fGLSLGeneration = k330_GrGLSLGeneration; |
| 18 | fShaderDerivativeSupport = false; |
| 19 | fGeometryShaderSupport = false; |
| 20 | fGSInvocationsSupport = false; |
| 21 | fPathRenderingSupport = false; |
| 22 | fDstReadInShaderSupport = false; |
| 23 | fDualSourceBlendingSupport = false; |
| 24 | fIntegerSupport = false; |
| 25 | fFBFetchSupport = false; |
| 26 | fFBFetchNeedsCustomOutput = false; |
| 27 | fUsesPrecisionModifiers = false; |
| 28 | fCanUseAnyFunctionInShader = true; |
| 29 | fCanUseMinAndAbsTogether = true; |
| 30 | fCanUseFractForNegativeValues = true; |
| 31 | fMustForceNegatedAtanParamToFloat = false; |
| 32 | fAtan2ImplementedAsAtanYOverX = false; |
| 33 | fMustDoOpBetweenFloorAndAbs = false; |
| 34 | fRequiresLocalOutputColorForFBFetch = false; |
| 35 | fMustObfuscateUniformColor = false; |
| 36 | fMustGuardDivisionEvenAfterExplicitZeroCheck = false; |
| 37 | fInBlendModesFailRandomlyForAllZeroVec = false; |
| 38 | fCanUseFragCoord = true; |
| 39 | fIncompleteShortIntPrecision = false; |
| 40 | fAddAndTrueToLoopCondition = false; |
| 41 | fUnfoldShortCircuitAsTernary = false; |
| 42 | fEmulateAbsIntFunction = false; |
| 43 | fRewriteDoWhileLoops = false; |
| 44 | fRemovePowWithConstantExponent = false; |
| 45 | fMustWriteToFragColor = false; |
| 46 | fNoDefaultPrecisionForExternalSamplers = false; |
| 47 | fCanOnlyUseSampleMaskWithStencil = false; |
| 48 | fFlatInterpolationSupport = false; |
| 49 | fPreferFlatInterpolation = false; |
| 50 | fNoPerspectiveInterpolationSupport = false; |
| 51 | fSampleMaskSupport = false; |
| 52 | fTessellationSupport = false; |
| 53 | fExternalTextureSupport = false; |
| 54 | fVertexIDSupport = false; |
| 55 | fFPManipulationSupport = false; |
| 56 | fFloatIs32Bits = true; |
| 57 | fHalfIs32Bits = false; |
| 58 | fHasLowFragmentPrecision = false; |
| 59 | fColorSpaceMathNeedsFloat = false; |
| 60 | // Backed API support is required to be able to make swizzle-neutral shaders (e.g. |
| 61 | // GL_ARB_texture_swizzle). |
| 62 | fTextureSwizzleAppliedInShader = true; |
| 63 | fBuiltinFMASupport = false; |
| 64 | |
| 65 | fVersionDeclString = nullptr; |
| 66 | fShaderDerivativeExtensionString = nullptr; |
| 67 | fGeometryShaderExtensionString = nullptr; |
| 68 | fGSInvocationsExtensionString = nullptr; |
| 69 | fFragCoordConventionsExtensionString = nullptr; |
| 70 | fSecondaryOutputExtensionString = nullptr; |
| 71 | fExternalTextureExtensionString = nullptr; |
| 72 | fSecondExternalTextureExtensionString = nullptr; |
| 73 | fNoPerspectiveInterpolationExtensionString = nullptr; |
| 74 | fSampleVariablesExtensionString = nullptr; |
| 75 | fTessellationExtensionString = nullptr; |
| 76 | fFBFetchColorName = nullptr; |
| 77 | fFBFetchExtensionString = nullptr; |
| 78 | fMaxFragmentSamplers = 0; |
| 79 | fAdvBlendEqInteraction = kNotSupported_AdvBlendEqInteraction; |
| 80 | } |
| 81 | |
| 82 | #ifdef SK_ENABLE_DUMP_GPU |
| 83 | void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { |
| 84 | writer->beginObject(); |
| 85 | |
| 86 | writer->appendBool("Shader Derivative Support" , fShaderDerivativeSupport); |
| 87 | writer->appendBool("Geometry Shader Support" , fGeometryShaderSupport); |
| 88 | writer->appendBool("Geometry Shader Invocations Support" , fGSInvocationsSupport); |
| 89 | writer->appendBool("Path Rendering Support" , fPathRenderingSupport); |
| 90 | writer->appendBool("Dst Read In Shader Support" , fDstReadInShaderSupport); |
| 91 | writer->appendBool("Dual Source Blending Support" , fDualSourceBlendingSupport); |
| 92 | writer->appendBool("Integer Support" , fIntegerSupport); |
| 93 | |
| 94 | static const char* kAdvBlendEqInteractionStr[] = { |
| 95 | "Not Supported" , |
| 96 | "Automatic" , |
| 97 | "General Enable" , |
| 98 | "Specific Enables" , |
| 99 | }; |
| 100 | static_assert(0 == kNotSupported_AdvBlendEqInteraction); |
| 101 | static_assert(1 == kAutomatic_AdvBlendEqInteraction); |
| 102 | static_assert(2 == kGeneralEnable_AdvBlendEqInteraction); |
| 103 | static_assert(3 == kSpecificEnables_AdvBlendEqInteraction); |
| 104 | static_assert(SK_ARRAY_COUNT(kAdvBlendEqInteractionStr) == kLast_AdvBlendEqInteraction + 1); |
| 105 | |
| 106 | writer->appendBool("FB Fetch Support" , fFBFetchSupport); |
| 107 | writer->appendBool("Uses precision modifiers" , fUsesPrecisionModifiers); |
| 108 | writer->appendBool("Can use any() function" , fCanUseAnyFunctionInShader); |
| 109 | writer->appendBool("Can use min() and abs() together" , fCanUseMinAndAbsTogether); |
| 110 | writer->appendBool("Can use fract() for negative values" , fCanUseFractForNegativeValues); |
| 111 | writer->appendBool("Must force negated atan param to float" , fMustForceNegatedAtanParamToFloat); |
| 112 | writer->appendBool("Must do op between floor and abs" , fMustDoOpBetweenFloorAndAbs); |
| 113 | writer->appendBool("Must use local out color for FBFetch" , fRequiresLocalOutputColorForFBFetch); |
| 114 | writer->appendBool("Must obfuscate uniform color" , fMustObfuscateUniformColor); |
| 115 | writer->appendBool("Must guard division even after explicit zero check" , |
| 116 | fMustGuardDivisionEvenAfterExplicitZeroCheck); |
| 117 | writer->appendBool( |
| 118 | "src-in and dst-in blend modes may return (0,0,0,1) when dst/src is all zeros" , |
| 119 | fInBlendModesFailRandomlyForAllZeroVec); |
| 120 | writer->appendBool("Can use gl_FragCoord" , fCanUseFragCoord); |
| 121 | writer->appendBool("Incomplete short int precision" , fIncompleteShortIntPrecision); |
| 122 | writer->appendBool("Add and true to loops workaround" , fAddAndTrueToLoopCondition); |
| 123 | writer->appendBool("Unfold short circuit as ternary" , fUnfoldShortCircuitAsTernary); |
| 124 | writer->appendBool("Emulate abs(int) function" , fEmulateAbsIntFunction); |
| 125 | writer->appendBool("Rewrite do while loops" , fRewriteDoWhileLoops); |
| 126 | writer->appendBool("Rewrite pow with constant exponent" , fRemovePowWithConstantExponent); |
| 127 | writer->appendBool("Must write to sk_FragColor [workaround]" , fMustWriteToFragColor); |
| 128 | writer->appendBool("Don't add default precision statement for samplerExternalOES" , |
| 129 | fNoDefaultPrecisionForExternalSamplers); |
| 130 | writer->appendBool("Can only use sample mask with stencil" , fCanOnlyUseSampleMaskWithStencil); |
| 131 | writer->appendBool("Flat interpolation support" , fFlatInterpolationSupport); |
| 132 | writer->appendBool("Prefer flat interpolation" , fPreferFlatInterpolation); |
| 133 | writer->appendBool("No perspective interpolation support" , fNoPerspectiveInterpolationSupport); |
| 134 | writer->appendBool("Sample mask support" , fSampleMaskSupport); |
| 135 | writer->appendBool("Tessellation Support" , fTessellationSupport); |
| 136 | writer->appendBool("External texture support" , fExternalTextureSupport); |
| 137 | writer->appendBool("sk_VertexID support" , fVertexIDSupport); |
| 138 | writer->appendBool("Floating point manipulation support" , fFPManipulationSupport); |
| 139 | writer->appendBool("float == fp32" , fFloatIs32Bits); |
| 140 | writer->appendBool("half == fp32" , fHalfIs32Bits); |
| 141 | writer->appendBool("Has poor fragment precision" , fHasLowFragmentPrecision); |
| 142 | writer->appendBool("Color space math needs float" , fColorSpaceMathNeedsFloat); |
| 143 | writer->appendBool("Texture swizzle applied in shader" , fTextureSwizzleAppliedInShader); |
| 144 | writer->appendBool("Builtin fma() support" , fBuiltinFMASupport); |
| 145 | |
| 146 | writer->appendS32("Max FS Samplers" , fMaxFragmentSamplers); |
| 147 | writer->appendString("Advanced blend equation interaction" , |
| 148 | kAdvBlendEqInteractionStr[fAdvBlendEqInteraction]); |
| 149 | |
| 150 | writer->endObject(); |
| 151 | } |
| 152 | #else |
| 153 | void GrShaderCaps::dumpJSON(SkJSONWriter* writer) const { } |
| 154 | #endif |
| 155 | |
| 156 | void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) { |
| 157 | if (options.fDisableDriverCorrectnessWorkarounds) { |
| 158 | SkASSERT(fCanUseAnyFunctionInShader); |
| 159 | SkASSERT(fCanUseMinAndAbsTogether); |
| 160 | SkASSERT(fCanUseFractForNegativeValues); |
| 161 | SkASSERT(!fMustForceNegatedAtanParamToFloat); |
| 162 | SkASSERT(!fAtan2ImplementedAsAtanYOverX); |
| 163 | SkASSERT(!fMustDoOpBetweenFloorAndAbs); |
| 164 | SkASSERT(!fRequiresLocalOutputColorForFBFetch); |
| 165 | SkASSERT(!fMustObfuscateUniformColor); |
| 166 | SkASSERT(!fMustGuardDivisionEvenAfterExplicitZeroCheck); |
| 167 | SkASSERT(!fInBlendModesFailRandomlyForAllZeroVec); |
| 168 | SkASSERT(fCanUseFragCoord); |
| 169 | SkASSERT(!fIncompleteShortIntPrecision); |
| 170 | SkASSERT(!fAddAndTrueToLoopCondition); |
| 171 | SkASSERT(!fUnfoldShortCircuitAsTernary); |
| 172 | SkASSERT(!fEmulateAbsIntFunction); |
| 173 | SkASSERT(!fRewriteDoWhileLoops); |
| 174 | SkASSERT(!fRemovePowWithConstantExponent); |
| 175 | SkASSERT(!fMustWriteToFragColor); |
| 176 | SkASSERT(!fNoDefaultPrecisionForExternalSamplers); |
| 177 | } |
| 178 | #if GR_TEST_UTILS |
| 179 | if (options.fSuppressDualSourceBlending) { |
| 180 | fDualSourceBlendingSupport = false; |
| 181 | } |
| 182 | if (options.fSuppressGeometryShaders) { |
| 183 | fGeometryShaderSupport = false; |
| 184 | } |
| 185 | #endif |
| 186 | } |
| 187 | |