Home | History | Annotate | Download | only in gpu
      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 
     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 }
     26 
     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";
     35     default:
     36         SkFAIL("Unexpected precision type.");
     37         return "";
     38     }
     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;
     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 
     96 SkString 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 
    176 void 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 
    229 void GrShaderCaps::applyOptionsOverrides(const GrContextOptions& options) {
    230     fDualSourceBlendingSupport = fDualSourceBlendingSupport && !options.fSuppressDualSourceBlending;
    231 }
    232