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