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