1 
2 /*
3  * Copyright 2013 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #ifndef GrDrawTargetCaps_DEFINED
9 #define GrDrawTargetCaps_DEFINED
10 
11 #include "GrTypes.h"
12 #include "GrTypesPriv.h"
13 #include "GrShaderVar.h"
14 #include "SkRefCnt.h"
15 #include "SkString.h"
16 
17 class GrShaderCaps : public SkRefCnt {
18 public:
19     SK_DECLARE_INST_COUNT(GrShaderCaps)
20 
21     /** Info about shader variable precision within a given shader stage. That is, this info
22         is relevant to a float (or vecNf) variable declared with a GrSLPrecision
23         in a given GrShaderType. The info here is hoisted from the OpenGL spec. */
24     struct PrecisionInfo {
PrecisionInfoPrecisionInfo25         PrecisionInfo() {
26             fLogRangeLow = 0;
27             fLogRangeHigh = 0;
28             fBits = 0;
29         }
30 
31         /** Is this precision level allowed in the shader stage? */
supportedPrecisionInfo32         bool supported() const { return 0 != fBits; }
33 
34         bool operator==(const PrecisionInfo& that) const {
35             return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh &&
36                    fBits == that.fBits;
37         }
38         bool operator!=(const PrecisionInfo& that) const { return !(*this == that); }
39 
40         /** floor(log2(|min_value|)) */
41         int fLogRangeLow;
42         /** floor(log2(|max_value|)) */
43         int fLogRangeHigh;
44         /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this
45             struct) :
46             """
47             If the smallest representable value greater than 1 is 1 + e, then fBits will
48             contain floor(log2(e)), and every value in the range [2^fLogRangeLow,
49             2^fLogRangeHigh] can be represented to at least one part in 2^fBits.
50             """
51           */
52         int fBits;
53     };
54 
GrShaderCaps()55     GrShaderCaps() {
56         this->reset();
57     }
~GrShaderCaps()58     virtual ~GrShaderCaps() {}
GrShaderCaps(const GrShaderCaps & other)59     GrShaderCaps(const GrShaderCaps& other) : INHERITED() {
60         *this = other;
61     }
62     GrShaderCaps& operator= (const GrShaderCaps&);
63 
64     virtual void reset();
65     virtual SkString dump() const;
66 
shaderDerivativeSupport()67     bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; }
geometryShaderSupport()68     bool geometryShaderSupport() const { return fGeometryShaderSupport; }
pathRenderingSupport()69     bool pathRenderingSupport() const { return fPathRenderingSupport; }
dstReadInShaderSupport()70     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
dualSourceBlendingSupport()71     bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; }
72 
73     /**
74     * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a
75     * given shader type. If the shader type is not supported or the precision level is not
76     * supported in that shader type then the returned struct will report false when supported() is
77     * called.
78     */
getFloatShaderPrecisionInfo(GrShaderType shaderType,GrSLPrecision precision)79     const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType,
80         GrSLPrecision precision) const {
81         return fFloatPrecisions[shaderType][precision];
82     };
83 
84     /**
85     * Is there any difference between the float shader variable precision types? If this is true
86     * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would
87     * report the same info for all precisions in all shader types.
88     */
floatPrecisionVaries()89     bool floatPrecisionVaries() const { return fShaderPrecisionVaries; }
90 
91 protected:
92     bool fShaderDerivativeSupport : 1;
93     bool fGeometryShaderSupport : 1;
94     bool fPathRenderingSupport : 1;
95     bool fDstReadInShaderSupport : 1;
96     bool fDualSourceBlendingSupport : 1;
97 
98     bool fShaderPrecisionVaries;
99     PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount];
100 
101 private:
102     typedef SkRefCnt INHERITED;
103 };
104 
105 /**
106  * Represents the draw target capabilities.
107  */
108 class GrDrawTargetCaps : public SkRefCnt {
109 public:
SK_DECLARE_INST_COUNT(GrDrawTargetCaps)110     SK_DECLARE_INST_COUNT(GrDrawTargetCaps)
111 
112     GrDrawTargetCaps() {
113         fShaderCaps.reset(NULL);
114         this->reset();
115     }
GrDrawTargetCaps(const GrDrawTargetCaps & other)116     GrDrawTargetCaps(const GrDrawTargetCaps& other) : INHERITED() {
117         *this = other;
118     }
~GrDrawTargetCaps()119     virtual ~GrDrawTargetCaps() {}
120     GrDrawTargetCaps& operator= (const GrDrawTargetCaps&);
121 
122     virtual void reset();
123     virtual SkString dump() const;
124 
shaderCaps()125     GrShaderCaps* shaderCaps() const { return fShaderCaps; }
126 
npotTextureTileSupport()127     bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; }
128     /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g.
129         only for POT textures) */
mipMapSupport()130     bool mipMapSupport() const { return fMipMapSupport; }
twoSidedStencilSupport()131     bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; }
stencilWrapOpsSupport()132     bool stencilWrapOpsSupport() const { return  fStencilWrapOpsSupport; }
discardRenderTargetSupport()133     bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; }
134 #if GR_FORCE_GPU_TRACE_DEBUGGING
gpuTracingSupport()135     bool gpuTracingSupport() const { return true; }
136 #else
gpuTracingSupport()137     bool gpuTracingSupport() const { return fGpuTracingSupport; }
138 #endif
compressedTexSubImageSupport()139     bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; }
oversizedStencilSupport()140     bool oversizedStencilSupport() const { return fOversizedStencilSupport; }
textureBarrierSupport()141     bool textureBarrierSupport() const { return fTextureBarrierSupport; }
142 
useDrawInsteadOfClear()143     bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; }
144 
145     /**
146      * Indicates the capabilities of the fixed function blend unit.
147      */
148     enum BlendEquationSupport {
149         kBasic_BlendEquationSupport,             //<! Support to select the operator that
150                                                  //   combines src and dst terms.
151         kAdvanced_BlendEquationSupport,          //<! Additional fixed function support for specific
152                                                  //   SVG/PDF blend modes. Requires blend barriers.
153         kAdvancedCoherent_BlendEquationSupport,  //<! Advanced blend equation support that does not
154                                                  //   require blend barriers, and permits overlap.
155 
156         kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport
157     };
158 
blendEquationSupport()159     BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; }
160 
advancedBlendEquationSupport()161     bool advancedBlendEquationSupport() const {
162         return fBlendEquationSupport >= kAdvanced_BlendEquationSupport;
163     }
164 
advancedCoherentBlendEquationSupport()165     bool advancedCoherentBlendEquationSupport() const {
166         return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport;
167     }
168 
169     /**
170      * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and
171      * textures allows partial mappings or full mappings.
172      */
173     enum MapFlags {
174         kNone_MapFlags   = 0x0,       //<! Cannot map the resource.
175 
176         kCanMap_MapFlag  = 0x1,       //<! The resource can be mapped. Must be set for any of
177                                       //   the other flags to have meaning.k
178         kSubset_MapFlag  = 0x2,       //<! The resource can be partially mapped.
179     };
180 
mapBufferFlags()181     uint32_t mapBufferFlags() const { return fMapBufferFlags; }
182 
183     // Scratch textures not being reused means that those scratch textures
184     // that we upload to (i.e., don't have a render target) will not be
185     // recycled in the texture cache. This is to prevent ghosting by drivers
186     // (in particular for deferred architectures).
reuseScratchTextures()187     bool reuseScratchTextures() const { return fReuseScratchTextures; }
188 
maxRenderTargetSize()189     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
maxTextureSize()190     int maxTextureSize() const { return fMaxTextureSize; }
191     // Will be 0 if MSAA is not supported
maxSampleCount()192     int maxSampleCount() const { return fMaxSampleCount; }
193 
isConfigRenderable(GrPixelConfig config,bool withMSAA)194     bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
195         SkASSERT(kGrPixelConfigCnt > config);
196         return fConfigRenderSupport[config][withMSAA];
197     }
198 
isConfigTexturable(GrPixelConfig config)199     bool isConfigTexturable(GrPixelConfig config) const {
200         SkASSERT(kGrPixelConfigCnt > config);
201         return fConfigTextureSupport[config];
202     }
203 
204 protected:
205     SkAutoTUnref<GrShaderCaps>    fShaderCaps;
206 
207     bool fNPOTTextureTileSupport        : 1;
208     bool fMipMapSupport                 : 1;
209     bool fTwoSidedStencilSupport        : 1;
210     bool fStencilWrapOpsSupport         : 1;
211     bool fDiscardRenderTargetSupport    : 1;
212     bool fReuseScratchTextures          : 1;
213     bool fGpuTracingSupport             : 1;
214     bool fCompressedTexSubImageSupport  : 1;
215     bool fOversizedStencilSupport       : 1;
216     bool fTextureBarrierSupport         : 1;
217     // Driver workaround
218     bool fUseDrawInsteadOfClear         : 1;
219 
220     BlendEquationSupport fBlendEquationSupport;
221     uint32_t fMapBufferFlags;
222 
223     int fMaxRenderTargetSize;
224     int fMaxTextureSize;
225     int fMaxSampleCount;
226 
227     // The first entry for each config is without msaa and the second is with.
228     bool fConfigRenderSupport[kGrPixelConfigCnt][2];
229     bool fConfigTextureSupport[kGrPixelConfigCnt];
230 
231 private:
232     typedef SkRefCnt INHERITED;
233 };
234 
235 #endif
236