1cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth/*
2cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth * Copyright 2012 Google Inc.
3cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth *
4cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth * Use of this source code is governed by a BSD-style license that can be
5cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth * found in the LICENSE file.
6cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth */
7cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
8cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#ifndef GrShaderCaps_DEFINED
1094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#define GrShaderCaps_DEFINED
11cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
1294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "../private/GrSwizzle.h"
1394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon#include "../private/GrGLSL.h"
14cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
157ef4b74e57a143e4e586e577e9b7c11c3aab472dEthan Nicholasnamespace SkSL {
16f1dd677c3a4c7bb7e72dbfb77a0124c51b19aa7cBrian Salomon    class ShaderCapsFactory;
177ef4b74e57a143e4e586e577e9b7c11c3aab472dEthan Nicholas}
1894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonstruct GrContextOptions;
197ef4b74e57a143e4e586e577e9b7c11c3aab472dEthan Nicholas
2094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomonclass GrShaderCaps : public SkRefCnt {
21cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverthpublic:
2294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    /** Info about shader variable precision within a given shader stage. That is, this info
2394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        is relevant to a float (or vecNf) variable declared with a GrSLPrecision
2494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        in a given GrShaderType. The info here is hoisted from the OpenGL spec. */
2594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    struct PrecisionInfo {
2694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        PrecisionInfo() {
2794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            fLogRangeLow = 0;
2894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            fLogRangeHigh = 0;
2994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            fBits = 0;
3094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        }
3194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
3294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        /** Is this precision level allowed in the shader stage? */
3394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        bool supported() const { return 0 != fBits; }
3494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
3594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        bool operator==(const PrecisionInfo& that) const {
3694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh &&
3794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon                   fBits == that.fBits;
3894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        }
3994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        bool operator!=(const PrecisionInfo& that) const { return !(*this == that); }
4094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
4194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        /** floor(log2(|min_value|)) */
4294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        int fLogRangeLow;
4394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        /** floor(log2(|max_value|)) */
4494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        int fLogRangeHigh;
4594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this
4694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            struct) :
4794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            """
4894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            If the smallest representable value greater than 1 is 1 + e, then fBits will
4994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            contain floor(log2(e)), and every value in the range [2^fLogRangeLow,
5094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            2^fLogRangeHigh] can be represented to at least one part in 2^fBits.
5194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon            """
5294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon          */
5394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        int fBits;
5494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    };
5594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
56cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    /**
57cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    * Indicates how GLSL must interact with advanced blend equations. The KHR extension requires
58cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    * special layout qualifiers in the fragment shader.
59cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    */
60cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    enum AdvBlendEqInteraction {
61cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        kNotSupported_AdvBlendEqInteraction,     //<! No _blend_equation_advanced extension
62cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        kAutomatic_AdvBlendEqInteraction,        //<! No interaction required
63cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        kGeneralEnable_AdvBlendEqInteraction,    //<! layout(blend_support_all_equations) out
64cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        kSpecificEnables_AdvBlendEqInteraction,  //<! Specific layout qualifiers per equation
65cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
66cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        kLast_AdvBlendEqInteraction = kSpecificEnables_AdvBlendEqInteraction
67cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    };
68cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
6994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    GrShaderCaps(const GrContextOptions&);
7094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
7194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    SkString dump() const;
7294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
7394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
7494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool geometryShaderSupport() const { return fGeometryShaderSupport; }
7594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool pathRenderingSupport() const { return fPathRenderingSupport; }
7694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
7794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
7894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool integerSupport() const { return fIntegerSupport; }
7994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool texelBufferSupport() const { return fTexelBufferSupport; }
8094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    int imageLoadStoreSupport() const { return fImageLoadStoreSupport; }
8194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
8294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    /**
8394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
8494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * given shader type. If the shader type is not supported or the precision level is not
8594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * supported in that shader type then the returned struct will report false when supported() is
8694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * called.
8794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    */
8894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
8994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon                                                     GrSLPrecision precision) const {
9094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon        return fFloatPrecisions[shaderType][precision];
9194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    }
9294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
9394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    /**
9494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * Is there any difference between the float shader variable precision types? If this is true
9594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
9694efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    * report the same info for all precisions in all shader types.
9794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    */
9894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
9994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
10094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    /**
101cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth     * Some helper functions for encapsulating various extensions to read FB Buffer on openglES
102cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth     *
103cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth     * TODO(joshualitt) On desktop opengl 4.2+ we can achieve something similar to this effect
104cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth     */
105cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fbFetchSupport() const { return fFBFetchSupport; }
106cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
107cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fbFetchNeedsCustomOutput() const { return fFBFetchNeedsCustomOutput; }
108cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
109cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool bindlessTextureSupport() const { return fBindlessTextureSupport; }
110cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
111472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel    const char* versionDeclString() const { return fVersionDeclString; }
112472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel
113cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    const char* fbFetchColorName() const { return fFBFetchColorName; }
114cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
115cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    const char* fbFetchExtensionString() const { return fFBFetchExtensionString; }
116cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
117cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool dropsTileOnZeroDivide() const { return fDropsTileOnZeroDivide; }
118cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
119c08f196648463d44eb85e17c5815dbf8f709a42acdalton    bool flatInterpolationSupport() const { return fFlatInterpolationSupport; }
120c08f196648463d44eb85e17c5815dbf8f709a42acdalton
121c08f196648463d44eb85e17c5815dbf8f709a42acdalton    bool noperspectiveInterpolationSupport() const { return fNoPerspectiveInterpolationSupport; }
122c08f196648463d44eb85e17c5815dbf8f709a42acdalton
1234a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton    bool multisampleInterpolationSupport() const { return fMultisampleInterpolationSupport; }
1244a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton
12533ad701bc30387127c427fb1e38c781d5de33491cdalton    bool sampleVariablesSupport() const { return fSampleVariablesSupport; }
12633ad701bc30387127c427fb1e38c781d5de33491cdalton
12733ad701bc30387127c427fb1e38c781d5de33491cdalton    bool sampleMaskOverrideCoverageSupport() const { return fSampleMaskOverrideCoverageSupport; }
12833ad701bc30387127c427fb1e38c781d5de33491cdalton
1299c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    bool externalTextureSupport() const { return fExternalTextureSupport; }
1309c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
131f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton    bool texelFetchSupport() const { return fTexelFetchSupport; }
132c04ce676d4516a8c64e29e1f60bb72cd2c6c0a59cdalton
1331d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    bool vertexIDSupport() const { return fVertexIDSupport; }
1341d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton
135cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    AdvBlendEqInteraction advBlendEqInteraction() const { return fAdvBlendEqInteraction; }
136cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
137cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool mustEnableAdvBlendEqs() const {
138cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        return fAdvBlendEqInteraction >= kGeneralEnable_AdvBlendEqInteraction;
139cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    }
140cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
141cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool mustEnableSpecificAdvBlendEqs() const {
142cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        return fAdvBlendEqInteraction == kSpecificEnables_AdvBlendEqInteraction;
143cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    }
1449d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
145cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool mustDeclareFragmentShaderOutput() const {
146cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth        return fGLSLGeneration > k110_GrGLSLGeneration;
147cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    }
148cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
149f529439fea003851d986a0573a7e0465754b2a48egdaniel    bool usesPrecisionModifiers() const { return fUsesPrecisionModifiers; }
150f529439fea003851d986a0573a7e0465754b2a48egdaniel
15180a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    // Returns whether we can use the glsl function any() in our shader code.
152472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel    bool canUseAnyFunctionInShader() const { return fCanUseAnyFunctionInShader; }
153472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel
1548dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    bool canUseMinAndAbsTogether() const { return fCanUseMinAndAbsTogether; }
1558dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel
1568dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    bool mustForceNegatedAtanParamToFloat() const { return fMustForceNegatedAtanParamToFloat; }
1578dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel
15880a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    // Returns whether a device incorrectly implements atan(y,x) as atan(y/x)
15980a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    bool atan2ImplementedAsAtanYOverX() const { return fAtan2ImplementedAsAtanYOverX; }
16080a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel
161138c26300f2686175f68b5a3528133f5c9edb596egdaniel    bool requiresLocalOutputColorForFBFetch() const { return fRequiresLocalOutputColorForFBFetch; }
162138c26300f2686175f68b5a3528133f5c9edb596egdaniel
1632e777ead127b03a06ccc7dfc983e1b28e1aa2f86csmartdalton    // On MacBook, geometry shaders break if they have more than one invocation.
1642e777ead127b03a06ccc7dfc983e1b28e1aa2f86csmartdalton    bool mustImplementGSInvocationsWithLoop() const { return fMustImplementGSInvocationsWithLoop; }
1652e777ead127b03a06ccc7dfc983e1b28e1aa2f86csmartdalton
166ac1e4964e7816de1f4977b52fa5f2f372537468bBrian Osman    bool mustObfuscateUniformColor() const { return fMustObfuscateUniformColor; }
167ac1e4964e7816de1f4977b52fa5f2f372537468bBrian Osman
168574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    // Returns the string of an extension that must be enabled in the shader to support
169574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    // derivatives. If nullptr is returned then no extension needs to be enabled. Before calling
170574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    // this function, the caller should check that shaderDerivativeSupport exists.
171574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    const char* shaderDerivativeExtensionString() const {
172574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel        SkASSERT(this->shaderDerivativeSupport());
173574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel        return fShaderDerivativeExtensionString;
174574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    }
17533ad701bc30387127c427fb1e38c781d5de33491cdalton
1768dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // Returns the string of an extension that will do all necessary coord transfomations needed
1778dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // when reading the fragment position. If such an extension does not exisits, this function
1788dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // returns a nullptr, and all transforms of the frag position must be done manually in the
1798dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // shader.
1808dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    const char* fragCoordConventionsExtensionString() const {
1818dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        return fFragCoordConventionsExtensionString;
1828dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    }
1838dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel
1848dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // This returns the name of an extension that must be enabled in the shader, if such a thing is
1858dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // required in order to use a secondary output in the shader. This returns a nullptr if no such
1868dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // extension is required. However, the return value of this function does not say whether dual
1878dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // source blending is supported.
1888dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    const char* secondaryOutputExtensionString() const {
1898dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel        return fSecondaryOutputExtensionString;
1908dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    }
191574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel
1927ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    const char* externalTextureExtensionString() const {
1939c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton        SkASSERT(this->externalTextureSupport());
1947ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon        return fExternalTextureExtensionString;
1957ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    }
1967ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon
197f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton    const char* texelBufferExtensionString() const {
198f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton        SkASSERT(this->texelBufferSupport());
199f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton        return fTexelBufferExtensionString;
200c04ce676d4516a8c64e29e1f60bb72cd2c6c0a59cdalton    }
201c04ce676d4516a8c64e29e1f60bb72cd2c6c0a59cdalton
202c08f196648463d44eb85e17c5815dbf8f709a42acdalton    const char* noperspectiveInterpolationExtensionString() const {
203c08f196648463d44eb85e17c5815dbf8f709a42acdalton        SkASSERT(this->noperspectiveInterpolationSupport());
204c08f196648463d44eb85e17c5815dbf8f709a42acdalton        return fNoPerspectiveInterpolationExtensionString;
205c08f196648463d44eb85e17c5815dbf8f709a42acdalton    }
206c08f196648463d44eb85e17c5815dbf8f709a42acdalton
2074a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton    const char* multisampleInterpolationExtensionString() const {
2084a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton        SkASSERT(this->multisampleInterpolationSupport());
2094a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton        return fMultisampleInterpolationExtensionString;
2104a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton    }
2114a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton
21233ad701bc30387127c427fb1e38c781d5de33491cdalton    const char* sampleVariablesExtensionString() const {
21333ad701bc30387127c427fb1e38c781d5de33491cdalton        SkASSERT(this->sampleVariablesSupport());
21433ad701bc30387127c427fb1e38c781d5de33491cdalton        return fSampleVariablesExtensionString;
21533ad701bc30387127c427fb1e38c781d5de33491cdalton    }
21633ad701bc30387127c427fb1e38c781d5de33491cdalton
217f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon    const char* imageLoadStoreExtensionString() const {
218f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon        SkASSERT(this->imageLoadStoreSupport());
219f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon        return fImageLoadStoreExtensionString;
220f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon    }
221f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
2229c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    int maxVertexSamplers() const { return fMaxVertexSamplers; }
2239c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
2249c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    int maxGeometrySamplers() const { return fMaxGeometrySamplers; }
2259c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
2269c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    int maxFragmentSamplers() const { return fMaxFragmentSamplers; }
2279c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
2289c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    int maxCombinedSamplers() const { return fMaxCombinedSamplers; }
2299c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
230f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int maxVertexImageStorages() const { return fMaxVertexImageStorages; }
231f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
232f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int maxGeometryImageStorages() const { return fMaxGeometryImageStorages; }
233f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
234f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int maxFragmentImageStorages() const { return fMaxFragmentImageStorages; }
235f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
236f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int maxCombinedImageStorages() const { return fMaxCombinedImageStorages; }
237f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
238b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel    /**
239cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon     * Given a texture's config, this determines what swizzle must be appended to accesses to the
240cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon     * texture in generated shader code. Swizzling may be implemented in texture parameters or a
2417f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon     * sampler rather than in the shader. In this case the returned swizzle will always be "rgba".
242b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel     */
243cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    const GrSwizzle& configTextureSwizzle(GrPixelConfig config) const {
244cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon        return fConfigTextureSwizzle[config];
245cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    }
246b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel
2477f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    /** Swizzle that should occur on the fragment shader outputs for a given config. */
2487f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    const GrSwizzle& configOutputSwizzle(GrPixelConfig config) const {
2497f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon        return fConfigOutputSwizzle[config];
2507f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    }
2517f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon
252a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    /** Precision qualifier that should be used with a sampler, given its config and visibility. */
253a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    GrSLPrecision samplerPrecision(GrPixelConfig config, GrShaderFlags visibility) const {
254a6b92ad1f7b79106caef6a4c721903544f507a02cdalton        return static_cast<GrSLPrecision>(fSamplerPrecisions[visibility][config]);
255a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    }
256a6b92ad1f7b79106caef6a4c721903544f507a02cdalton
257cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    GrGLSLGeneration generation() const { return fGLSLGeneration; }
258cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
259cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverthprivate:
260a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    /** GrCaps subclasses must call this after filling in the shader precision table. */
261a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    void initSamplerPrecisionTable();
262a6b92ad1f7b79106caef6a4c721903544f507a02cdalton
26394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    void applyOptionsOverrides(const GrContextOptions& options);
264b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel
265cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    GrGLSLGeneration fGLSLGeneration;
2669d524f22bfde5dc3dc8f48e1be39bdebd3bb0304halcanary
26794efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fShaderDerivativeSupport   : 1;
26894efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fGeometryShaderSupport     : 1;
26994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fPathRenderingSupport      : 1;
27094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fDstReadInShaderSupport    : 1;
27194efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fDualSourceBlendingSupport : 1;
27294efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fIntegerSupport            : 1;
27394efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fTexelBufferSupport        : 1;
27494efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fImageLoadStoreSupport     : 1;
27594efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    bool fShaderPrecisionVaries     : 1;
276cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fDropsTileOnZeroDivide : 1;
277cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fFBFetchSupport : 1;
278cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fFBFetchNeedsCustomOutput : 1;
279cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    bool fBindlessTextureSupport : 1;
280f529439fea003851d986a0573a7e0465754b2a48egdaniel    bool fUsesPrecisionModifiers : 1;
281472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel    bool fCanUseAnyFunctionInShader : 1;
282c08f196648463d44eb85e17c5815dbf8f709a42acdalton    bool fFlatInterpolationSupport : 1;
283c08f196648463d44eb85e17c5815dbf8f709a42acdalton    bool fNoPerspectiveInterpolationSupport : 1;
2844a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton    bool fMultisampleInterpolationSupport : 1;
28533ad701bc30387127c427fb1e38c781d5de33491cdalton    bool fSampleVariablesSupport : 1;
28633ad701bc30387127c427fb1e38c781d5de33491cdalton    bool fSampleMaskOverrideCoverageSupport : 1;
2879c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton    bool fExternalTextureSupport : 1;
288f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton    bool fTexelFetchSupport : 1;
2891d6163577c8a4f1372208e2c9e03b1a69906d385Chris Dalton    bool fVertexIDSupport : 1;
290f529439fea003851d986a0573a7e0465754b2a48egdaniel
2918dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    // Used for specific driver bug work arounds
2928dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    bool fCanUseMinAndAbsTogether : 1;
2938dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    bool fMustForceNegatedAtanParamToFloat : 1;
29480a08dd2e5cc379100ae944b3f3fadf887d518f0Greg Daniel    bool fAtan2ImplementedAsAtanYOverX : 1;
295138c26300f2686175f68b5a3528133f5c9edb596egdaniel    bool fRequiresLocalOutputColorForFBFetch : 1;
2962e777ead127b03a06ccc7dfc983e1b28e1aa2f86csmartdalton    bool fMustImplementGSInvocationsWithLoop : 1;
297ac1e4964e7816de1f4977b52fa5f2f372537468bBrian Osman    bool fMustObfuscateUniformColor : 1;
2988dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel
29994efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon    PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
30094efbf51f5a88d9e8aa961d3fbe38c5e335d6108Brian Salomon
301472d44e8f881f87449d11ba66515d3c1c5e69891egdaniel    const char* fVersionDeclString;
302cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
303574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel    const char* fShaderDerivativeExtensionString;
3048dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    const char* fFragCoordConventionsExtensionString;
3058dcdedc4a087ea46ce1e2458d335d60918e56310egdaniel    const char* fSecondaryOutputExtensionString;
3067ea33f5e1ae9eb1fb1e7377d6edf6acdcf71d103bsalomon    const char* fExternalTextureExtensionString;
307f8a6ce8d8c54cab5456d3099fa07e460c889c2e6cdalton    const char* fTexelBufferExtensionString;
308c08f196648463d44eb85e17c5815dbf8f709a42acdalton    const char* fNoPerspectiveInterpolationExtensionString;
3094a98cdb7612493a062358cebd1141c9bcaa37ab1cdalton    const char* fMultisampleInterpolationExtensionString;
31033ad701bc30387127c427fb1e38c781d5de33491cdalton    const char* fSampleVariablesExtensionString;
311f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon    const char* fImageLoadStoreExtensionString;
312574a4c153d8a3f42b2806848f5c23cbf55e18bbbegdaniel
313cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    const char* fFBFetchColorName;
314cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    const char* fFBFetchExtensionString;
315cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
316e78d4872cf2a0914752cdc99c4ec4a499cfd4e2cjvanverth    int fMaxVertexSamplers;
317e78d4872cf2a0914752cdc99c4ec4a499cfd4e2cjvanverth    int fMaxGeometrySamplers;
318e78d4872cf2a0914752cdc99c4ec4a499cfd4e2cjvanverth    int fMaxFragmentSamplers;
319e78d4872cf2a0914752cdc99c4ec4a499cfd4e2cjvanverth    int fMaxCombinedSamplers;
3209c3f14327a38e79ab7d0cf30dfd9bf89676fde06cdalton
321f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int fMaxVertexImageStorages;
322f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int fMaxGeometryImageStorages;
323f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int fMaxFragmentImageStorages;
324f9f451213a3951d8a61568998de2ddbd643f6693Brian Salomon    int fMaxCombinedImageStorages;
325f26f7a063aae6eb29f526a54c7886538ac1e817bBrian Salomon
326cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    AdvBlendEqInteraction fAdvBlendEqInteraction;
327cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
328cdee009886babe6df7743a9b5b3e2cc0a5f21adfbsalomon    GrSwizzle fConfigTextureSwizzle[kGrPixelConfigCnt];
3297f9b2e4a45775e8cdd3f98260a66c0c6e1840550bsalomon    GrSwizzle fConfigOutputSwizzle[kGrPixelConfigCnt];
330b7e7d5748d74c7482436b33733d7770484bb62e3egdaniel
331a6b92ad1f7b79106caef6a4c721903544f507a02cdalton    uint8_t fSamplerPrecisions[(1 << kGrShaderTypeCount)][kGrPixelConfigCnt];
332a6b92ad1f7b79106caef6a4c721903544f507a02cdalton
333cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth    friend class GrGLCaps;  // For initialization.
334fa8963252e122c5288c8e92b5ecc25a8fea21c3begdaniel    friend class GrVkCaps;
335f1dd677c3a4c7bb7e72dbfb77a0124c51b19aa7cBrian Salomon    friend class SkSL::ShaderCapsFactory;
336cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth};
337cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth
338cba99b88fd5fb39def7a094dc32c0745c7a1cfeajvanverth#endif
339