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 GrCaps_DEFINED 9 #define GrCaps_DEFINED 10 11 #include "GrTypes.h" 12 #include "GrTypesPriv.h" 13 #include "GrBlend.h" 14 #include "GrShaderVar.h" 15 #include "SkRefCnt.h" 16 #include "SkString.h" 17 18 struct GrContextOptions; 19 20 class GrShaderCaps : public SkRefCnt { 21 public: 22 /** Info about shader variable precision within a given shader stage. That is, this info 23 is relevant to a float (or vecNf) variable declared with a GrSLPrecision 24 in a given GrShaderType. The info here is hoisted from the OpenGL spec. */ 25 struct PrecisionInfo { PrecisionInfoPrecisionInfo26 PrecisionInfo() { 27 fLogRangeLow = 0; 28 fLogRangeHigh = 0; 29 fBits = 0; 30 } 31 32 /** Is this precision level allowed in the shader stage? */ supportedPrecisionInfo33 bool supported() const { return 0 != fBits; } 34 35 bool operator==(const PrecisionInfo& that) const { 36 return fLogRangeLow == that.fLogRangeLow && fLogRangeHigh == that.fLogRangeHigh && 37 fBits == that.fBits; 38 } 39 bool operator!=(const PrecisionInfo& that) const { return !(*this == that); } 40 41 /** floor(log2(|min_value|)) */ 42 int fLogRangeLow; 43 /** floor(log2(|max_value|)) */ 44 int fLogRangeHigh; 45 /** Number of bits of precision. As defined in OpenGL (with names modified to reflect this 46 struct) : 47 """ 48 If the smallest representable value greater than 1 is 1 + e, then fBits will 49 contain floor(log2(e)), and every value in the range [2^fLogRangeLow, 50 2^fLogRangeHigh] can be represented to at least one part in 2^fBits. 51 """ 52 */ 53 int fBits; 54 }; 55 56 GrShaderCaps(); 57 58 virtual SkString dump() const; 59 shaderDerivativeSupport()60 bool shaderDerivativeSupport() const { return fShaderDerivativeSupport; } geometryShaderSupport()61 bool geometryShaderSupport() const { return fGeometryShaderSupport; } pathRenderingSupport()62 bool pathRenderingSupport() const { return fPathRenderingSupport; } dstReadInShaderSupport()63 bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; } dualSourceBlendingSupport()64 bool dualSourceBlendingSupport() const { return fDualSourceBlendingSupport; } integerSupport()65 bool integerSupport() const { return fIntegerSupport; } 66 67 /** 68 * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a 69 * given shader type. If the shader type is not supported or the precision level is not 70 * supported in that shader type then the returned struct will report false when supported() is 71 * called. 72 */ getFloatShaderPrecisionInfo(GrShaderType shaderType,GrSLPrecision precision)73 const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType, 74 GrSLPrecision precision) const { 75 return fFloatPrecisions[shaderType][precision]; 76 }; 77 78 /** 79 * Is there any difference between the float shader variable precision types? If this is true 80 * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would 81 * report the same info for all precisions in all shader types. 82 */ floatPrecisionVaries()83 bool floatPrecisionVaries() const { return fShaderPrecisionVaries; } 84 85 /** 86 * PLS storage size in bytes (0 when not supported). The PLS spec defines a minimum size of 16 87 * bytes whenever PLS is supported. 88 */ pixelLocalStorageSize()89 int pixelLocalStorageSize() const { return fPixelLocalStorageSize; } 90 91 /** 92 * True if this context supports the necessary extensions and features to enable the PLS path 93 * renderer. 94 */ plsPathRenderingSupport()95 bool plsPathRenderingSupport() const { 96 #if GR_ENABLE_PLS_PATH_RENDERING 97 return fPLSPathRenderingSupport; 98 #else 99 return false; 100 #endif 101 } 102 103 protected: 104 /** Subclasses must call this after initialization in order to apply caps overrides requested by 105 the client. Note that overrides will only reduce the caps never expand them. */ 106 void applyOptionsOverrides(const GrContextOptions& options); 107 108 bool fShaderDerivativeSupport : 1; 109 bool fGeometryShaderSupport : 1; 110 bool fPathRenderingSupport : 1; 111 bool fDstReadInShaderSupport : 1; 112 bool fDualSourceBlendingSupport : 1; 113 bool fIntegerSupport : 1; 114 115 bool fShaderPrecisionVaries; 116 PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount]; 117 int fPixelLocalStorageSize; 118 bool fPLSPathRenderingSupport; 119 120 private: onApplyOptionsOverrides(const GrContextOptions &)121 virtual void onApplyOptionsOverrides(const GrContextOptions&) {}; 122 typedef SkRefCnt INHERITED; 123 }; 124 125 /** 126 * Represents the capabilities of a GrContext. 127 */ 128 class GrCaps : public SkRefCnt { 129 public: 130 GrCaps(const GrContextOptions&); 131 132 virtual SkString dump() const; 133 shaderCaps()134 GrShaderCaps* shaderCaps() const { return fShaderCaps; } 135 npotTextureTileSupport()136 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 137 /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. 138 only for POT textures) */ mipMapSupport()139 bool mipMapSupport() const { return fMipMapSupport; } twoSidedStencilSupport()140 bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; } stencilWrapOpsSupport()141 bool stencilWrapOpsSupport() const { return fStencilWrapOpsSupport; } discardRenderTargetSupport()142 bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } gpuTracingSupport()143 bool gpuTracingSupport() const { return fGpuTracingSupport; } compressedTexSubImageSupport()144 bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } oversizedStencilSupport()145 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } textureBarrierSupport()146 bool textureBarrierSupport() const { return fTextureBarrierSupport; } usesMixedSamples()147 bool usesMixedSamples() const { return fUsesMixedSamples; } 148 useDrawInsteadOfClear()149 bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } useDrawInsteadOfPartialRenderTargetWrite()150 bool useDrawInsteadOfPartialRenderTargetWrite() const { 151 return fUseDrawInsteadOfPartialRenderTargetWrite; 152 } 153 useDrawInsteadOfAllRenderTargetWrites()154 bool useDrawInsteadOfAllRenderTargetWrites() const { 155 return fUseDrawInsteadOfAllRenderTargetWrites; 156 } 157 preferVRAMUseOverFlushes()158 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 159 160 /** 161 * Indicates the capabilities of the fixed function blend unit. 162 */ 163 enum BlendEquationSupport { 164 kBasic_BlendEquationSupport, //<! Support to select the operator that 165 // combines src and dst terms. 166 kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific 167 // SVG/PDF blend modes. Requires blend barriers. 168 kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not 169 // require blend barriers, and permits overlap. 170 171 kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport 172 }; 173 blendEquationSupport()174 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 175 advancedBlendEquationSupport()176 bool advancedBlendEquationSupport() const { 177 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 178 } 179 advancedCoherentBlendEquationSupport()180 bool advancedCoherentBlendEquationSupport() const { 181 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 182 } 183 canUseAdvancedBlendEquation(GrBlendEquation equation)184 bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { 185 SkASSERT(GrBlendEquationIsAdvanced(equation)); 186 return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); 187 } 188 189 /** 190 * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and 191 * textures allows partial mappings or full mappings. 192 */ 193 enum MapFlags { 194 kNone_MapFlags = 0x0, //<! Cannot map the resource. 195 196 kCanMap_MapFlag = 0x1, //<! The resource can be mapped. Must be set for any of 197 // the other flags to have meaning.k 198 kSubset_MapFlag = 0x2, //<! The resource can be partially mapped. 199 }; 200 mapBufferFlags()201 uint32_t mapBufferFlags() const { return fMapBufferFlags; } 202 203 // Scratch textures not being reused means that those scratch textures 204 // that we upload to (i.e., don't have a render target) will not be 205 // recycled in the texture cache. This is to prevent ghosting by drivers 206 // (in particular for deferred architectures). reuseScratchTextures()207 bool reuseScratchTextures() const { return fReuseScratchTextures; } reuseScratchBuffers()208 bool reuseScratchBuffers() const { return fReuseScratchBuffers; } 209 maxRenderTargetSize()210 int maxRenderTargetSize() const { return fMaxRenderTargetSize; } maxTextureSize()211 int maxTextureSize() const { return fMaxTextureSize; } 212 /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps. 213 It is usually the max texture size, unless we're overriding it for testing. */ maxTileSize()214 int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; } 215 216 // Will be 0 if MSAA is not supported maxColorSampleCount()217 int maxColorSampleCount() const { return fMaxColorSampleCount; } 218 // Will be 0 if MSAA is not supported maxStencilSampleCount()219 int maxStencilSampleCount() const { return fMaxStencilSampleCount; } 220 // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode 221 // where the rasterizer runs with more samples than are in the target framebuffer. maxRasterSamples()222 int maxRasterSamples() const { return fMaxRasterSamples; } 223 // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount. 224 // If we are using mixed samples, we only care about stencil. maxSampleCount()225 int maxSampleCount() const { 226 if (this->usesMixedSamples()) { 227 return this->maxStencilSampleCount(); 228 } else { 229 return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount()); 230 } 231 } 232 233 234 virtual bool isConfigTexturable(GrPixelConfig config) const = 0; 235 virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0; 236 suppressPrints()237 bool suppressPrints() const { return fSuppressPrints; } 238 immediateFlush()239 bool immediateFlush() const { return fImmediateFlush; } 240 drawPathMasksToCompressedTexturesSupport()241 bool drawPathMasksToCompressedTexturesSupport() const { 242 return fDrawPathMasksToCompressedTextureSupport; 243 } 244 geometryBufferMapThreshold()245 size_t geometryBufferMapThreshold() const { 246 SkASSERT(fGeometryBufferMapThreshold >= 0); 247 return fGeometryBufferMapThreshold; 248 } 249 supportsInstancedDraws()250 bool supportsInstancedDraws() const { 251 return fSupportsInstancedDraws; 252 } 253 fullClearIsFree()254 bool fullClearIsFree() const { return fFullClearIsFree; } 255 256 /** True in environments that will issue errors if memory uploaded to buffers 257 is not initialized (even if not read by draw calls). */ mustClearUploadedBufferData()258 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 259 260 protected: 261 /** Subclasses must call this at the end of their constructors in order to apply caps 262 overrides requested by the client. Note that overrides will only reduce the caps never 263 expand them. */ 264 void applyOptionsOverrides(const GrContextOptions& options); 265 266 SkAutoTUnref<GrShaderCaps> fShaderCaps; 267 268 bool fNPOTTextureTileSupport : 1; 269 bool fMipMapSupport : 1; 270 bool fTwoSidedStencilSupport : 1; 271 bool fStencilWrapOpsSupport : 1; 272 bool fDiscardRenderTargetSupport : 1; 273 bool fReuseScratchTextures : 1; 274 bool fReuseScratchBuffers : 1; 275 bool fGpuTracingSupport : 1; 276 bool fCompressedTexSubImageSupport : 1; 277 bool fOversizedStencilSupport : 1; 278 bool fTextureBarrierSupport : 1; 279 bool fUsesMixedSamples : 1; 280 bool fSupportsInstancedDraws : 1; 281 bool fFullClearIsFree : 1; 282 bool fMustClearUploadedBufferData : 1; 283 284 // Driver workaround 285 bool fUseDrawInsteadOfClear : 1; 286 bool fUseDrawInsteadOfPartialRenderTargetWrite : 1; 287 bool fUseDrawInsteadOfAllRenderTargetWrites : 1; 288 289 // ANGLE workaround 290 bool fPreferVRAMUseOverFlushes : 1; 291 292 BlendEquationSupport fBlendEquationSupport; 293 uint32_t fAdvBlendEqBlacklist; 294 GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); 295 296 uint32_t fMapBufferFlags; 297 int fGeometryBufferMapThreshold; 298 299 int fMaxRenderTargetSize; 300 int fMaxTextureSize; 301 int fMaxTileSize; 302 int fMaxColorSampleCount; 303 int fMaxStencilSampleCount; 304 int fMaxRasterSamples; 305 306 private: onApplyOptionsOverrides(const GrContextOptions &)307 virtual void onApplyOptionsOverrides(const GrContextOptions&) {}; 308 309 bool fSuppressPrints : 1; 310 bool fImmediateFlush: 1; 311 bool fDrawPathMasksToCompressedTextureSupport : 1; 312 313 typedef SkRefCnt INHERITED; 314 }; 315 316 #endif 317