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; } texelBufferSupport()66 bool texelBufferSupport() const { return fTexelBufferSupport; } 67 68 /** 69 * Get the precision info for a variable of type kFloat_GrSLType, kVec2f_GrSLType, etc in a 70 * given shader type. If the shader type is not supported or the precision level is not 71 * supported in that shader type then the returned struct will report false when supported() is 72 * called. 73 */ getFloatShaderPrecisionInfo(GrShaderType shaderType,GrSLPrecision precision)74 const PrecisionInfo& getFloatShaderPrecisionInfo(GrShaderType shaderType, 75 GrSLPrecision precision) const { 76 return fFloatPrecisions[shaderType][precision]; 77 } 78 79 /** 80 * Is there any difference between the float shader variable precision types? If this is true 81 * then unless the shader type is not supported, any call to getFloatShaderPrecisionInfo() would 82 * report the same info for all precisions in all shader types. 83 */ floatPrecisionVaries()84 bool floatPrecisionVaries() const { return fShaderPrecisionVaries; } 85 86 /** 87 * PLS storage size in bytes (0 when not supported). The PLS spec defines a minimum size of 16 88 * bytes whenever PLS is supported. 89 */ pixelLocalStorageSize()90 int pixelLocalStorageSize() const { return fPixelLocalStorageSize; } 91 92 /** 93 * True if this context supports the necessary extensions and features to enable the PLS path 94 * renderer. 95 */ plsPathRenderingSupport()96 bool plsPathRenderingSupport() const { 97 #if GR_ENABLE_PLS_PATH_RENDERING 98 return fPLSPathRenderingSupport; 99 #else 100 return false; 101 #endif 102 } 103 104 protected: 105 /** Subclasses must call this after initialization in order to apply caps overrides requested by 106 the client. Note that overrides will only reduce the caps never expand them. */ 107 void applyOptionsOverrides(const GrContextOptions& options); 108 109 bool fShaderDerivativeSupport : 1; 110 bool fGeometryShaderSupport : 1; 111 bool fPathRenderingSupport : 1; 112 bool fDstReadInShaderSupport : 1; 113 bool fDualSourceBlendingSupport : 1; 114 bool fIntegerSupport : 1; 115 bool fTexelBufferSupport : 1; 116 117 bool fShaderPrecisionVaries; 118 PrecisionInfo fFloatPrecisions[kGrShaderTypeCount][kGrSLPrecisionCount]; 119 int fPixelLocalStorageSize; 120 bool fPLSPathRenderingSupport; 121 122 private: onApplyOptionsOverrides(const GrContextOptions &)123 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} 124 typedef SkRefCnt INHERITED; 125 }; 126 127 /** 128 * Represents the capabilities of a GrContext. 129 */ 130 class GrCaps : public SkRefCnt { 131 public: 132 GrCaps(const GrContextOptions&); 133 134 virtual SkString dump() const; 135 shaderCaps()136 GrShaderCaps* shaderCaps() const { return fShaderCaps; } 137 npotTextureTileSupport()138 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 139 /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. 140 only for POT textures) */ mipMapSupport()141 bool mipMapSupport() const { return fMipMapSupport; } 142 143 /** 144 * Skia convention is that a device only has sRGB support if it supports sRGB formats for both 145 * textures and framebuffers. In addition: 146 * Decoding to linear of an sRGB texture can be disabled. 147 */ srgbSupport()148 bool srgbSupport() const { return fSRGBSupport; } 149 /** 150 * Is there support for enabling/disabling sRGB writes for sRGB-capable color buffers? 151 */ srgbWriteControl()152 bool srgbWriteControl() const { return fSRGBWriteControl; } twoSidedStencilSupport()153 bool twoSidedStencilSupport() const { return fTwoSidedStencilSupport; } stencilWrapOpsSupport()154 bool stencilWrapOpsSupport() const { return fStencilWrapOpsSupport; } discardRenderTargetSupport()155 bool discardRenderTargetSupport() const { return fDiscardRenderTargetSupport; } gpuTracingSupport()156 bool gpuTracingSupport() const { return fGpuTracingSupport; } compressedTexSubImageSupport()157 bool compressedTexSubImageSupport() const { return fCompressedTexSubImageSupport; } oversizedStencilSupport()158 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } textureBarrierSupport()159 bool textureBarrierSupport() const { return fTextureBarrierSupport; } sampleLocationsSupport()160 bool sampleLocationsSupport() const { return fSampleLocationsSupport; } multisampleDisableSupport()161 bool multisampleDisableSupport() const { return fMultisampleDisableSupport; } usesMixedSamples()162 bool usesMixedSamples() const { return fUsesMixedSamples; } preferClientSideDynamicBuffers()163 bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } 164 useDrawInsteadOfClear()165 bool useDrawInsteadOfClear() const { return fUseDrawInsteadOfClear; } useDrawInsteadOfPartialRenderTargetWrite()166 bool useDrawInsteadOfPartialRenderTargetWrite() const { 167 return fUseDrawInsteadOfPartialRenderTargetWrite; 168 } 169 useDrawInsteadOfAllRenderTargetWrites()170 bool useDrawInsteadOfAllRenderTargetWrites() const { 171 return fUseDrawInsteadOfAllRenderTargetWrites; 172 } 173 preferVRAMUseOverFlushes()174 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 175 176 /** 177 * Indicates the level of support for gr_instanced::* functionality. A higher level includes 178 * all functionality from the levels below it. 179 */ 180 enum class InstancedSupport { 181 kNone, 182 kBasic, 183 kMultisampled, 184 kMixedSampled 185 }; 186 instancedSupport()187 InstancedSupport instancedSupport() const { return fInstancedSupport; } 188 avoidInstancedDrawsToFPTargets()189 bool avoidInstancedDrawsToFPTargets() const { return fAvoidInstancedDrawsToFPTargets; } 190 191 /** 192 * Indicates the capabilities of the fixed function blend unit. 193 */ 194 enum BlendEquationSupport { 195 kBasic_BlendEquationSupport, //<! Support to select the operator that 196 // combines src and dst terms. 197 kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific 198 // SVG/PDF blend modes. Requires blend barriers. 199 kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not 200 // require blend barriers, and permits overlap. 201 202 kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport 203 }; 204 blendEquationSupport()205 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 206 advancedBlendEquationSupport()207 bool advancedBlendEquationSupport() const { 208 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 209 } 210 advancedCoherentBlendEquationSupport()211 bool advancedCoherentBlendEquationSupport() const { 212 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 213 } 214 canUseAdvancedBlendEquation(GrBlendEquation equation)215 bool canUseAdvancedBlendEquation(GrBlendEquation equation) const { 216 SkASSERT(GrBlendEquationIsAdvanced(equation)); 217 return SkToBool(fAdvBlendEqBlacklist & (1 << equation)); 218 } 219 220 /** 221 * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and 222 * textures allows partial mappings or full mappings. 223 */ 224 enum MapFlags { 225 kNone_MapFlags = 0x0, //<! Cannot map the resource. 226 227 kCanMap_MapFlag = 0x1, //<! The resource can be mapped. Must be set for any of 228 // the other flags to have meaning.k 229 kSubset_MapFlag = 0x2, //<! The resource can be partially mapped. 230 }; 231 mapBufferFlags()232 uint32_t mapBufferFlags() const { return fMapBufferFlags; } 233 234 // Scratch textures not being reused means that those scratch textures 235 // that we upload to (i.e., don't have a render target) will not be 236 // recycled in the texture cache. This is to prevent ghosting by drivers 237 // (in particular for deferred architectures). reuseScratchTextures()238 bool reuseScratchTextures() const { return fReuseScratchTextures; } reuseScratchBuffers()239 bool reuseScratchBuffers() const { return fReuseScratchBuffers; } 240 241 /// maximum number of attribute values per vertex maxVertexAttributes()242 int maxVertexAttributes() const { return fMaxVertexAttributes; } 243 maxRenderTargetSize()244 int maxRenderTargetSize() const { return fMaxRenderTargetSize; } maxTextureSize()245 int maxTextureSize() const { return fMaxTextureSize; } 246 /** This is the maximum tile size to use by GPU devices for rendering sw-backed images/bitmaps. 247 It is usually the max texture size, unless we're overriding it for testing. */ maxTileSize()248 int maxTileSize() const { SkASSERT(fMaxTileSize <= fMaxTextureSize); return fMaxTileSize; } 249 250 // Will be 0 if MSAA is not supported maxColorSampleCount()251 int maxColorSampleCount() const { return fMaxColorSampleCount; } 252 // Will be 0 if MSAA is not supported maxStencilSampleCount()253 int maxStencilSampleCount() const { return fMaxStencilSampleCount; } 254 // Will be 0 if raster multisample is not supported. Raster multisample is a special HW mode 255 // where the rasterizer runs with more samples than are in the target framebuffer. maxRasterSamples()256 int maxRasterSamples() const { return fMaxRasterSamples; } 257 // We require the sample count to be less than maxColorSampleCount and maxStencilSampleCount. 258 // If we are using mixed samples, we only care about stencil. maxSampleCount()259 int maxSampleCount() const { 260 if (this->usesMixedSamples()) { 261 return this->maxStencilSampleCount(); 262 } else { 263 return SkTMin(this->maxColorSampleCount(), this->maxStencilSampleCount()); 264 } 265 } 266 maxWindowRectangles()267 int maxWindowRectangles() const { return fMaxWindowRectangles; } 268 269 virtual bool isConfigTexturable(GrPixelConfig config) const = 0; 270 virtual bool isConfigRenderable(GrPixelConfig config, bool withMSAA) const = 0; 271 suppressPrints()272 bool suppressPrints() const { return fSuppressPrints; } 273 immediateFlush()274 bool immediateFlush() const { return fImmediateFlush; } 275 bufferMapThreshold()276 size_t bufferMapThreshold() const { 277 SkASSERT(fBufferMapThreshold >= 0); 278 return fBufferMapThreshold; 279 } 280 fullClearIsFree()281 bool fullClearIsFree() const { return fFullClearIsFree; } 282 283 /** True in environments that will issue errors if memory uploaded to buffers 284 is not initialized (even if not read by draw calls). */ mustClearUploadedBufferData()285 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 286 sampleShadingSupport()287 bool sampleShadingSupport() const { return fSampleShadingSupport; } 288 fenceSyncSupport()289 bool fenceSyncSupport() const { return fFenceSyncSupport; } 290 291 protected: 292 /** Subclasses must call this at the end of their constructors in order to apply caps 293 overrides requested by the client. Note that overrides will only reduce the caps never 294 expand them. */ 295 void applyOptionsOverrides(const GrContextOptions& options); 296 297 SkAutoTUnref<GrShaderCaps> fShaderCaps; 298 299 bool fNPOTTextureTileSupport : 1; 300 bool fMipMapSupport : 1; 301 bool fSRGBSupport : 1; 302 bool fSRGBWriteControl : 1; 303 bool fTwoSidedStencilSupport : 1; 304 bool fStencilWrapOpsSupport : 1; 305 bool fDiscardRenderTargetSupport : 1; 306 bool fReuseScratchTextures : 1; 307 bool fReuseScratchBuffers : 1; 308 bool fGpuTracingSupport : 1; 309 bool fCompressedTexSubImageSupport : 1; 310 bool fOversizedStencilSupport : 1; 311 bool fTextureBarrierSupport : 1; 312 bool fSampleLocationsSupport : 1; 313 bool fMultisampleDisableSupport : 1; 314 bool fUsesMixedSamples : 1; 315 bool fPreferClientSideDynamicBuffers : 1; 316 bool fFullClearIsFree : 1; 317 bool fMustClearUploadedBufferData : 1; 318 319 // Driver workaround 320 bool fUseDrawInsteadOfClear : 1; 321 bool fUseDrawInsteadOfPartialRenderTargetWrite : 1; 322 bool fUseDrawInsteadOfAllRenderTargetWrites : 1; 323 bool fAvoidInstancedDrawsToFPTargets : 1; 324 325 // ANGLE workaround 326 bool fPreferVRAMUseOverFlushes : 1; 327 328 bool fSampleShadingSupport : 1; 329 // TODO: this may need to be an enum to support different fence types 330 bool fFenceSyncSupport : 1; 331 332 InstancedSupport fInstancedSupport; 333 334 BlendEquationSupport fBlendEquationSupport; 335 uint32_t fAdvBlendEqBlacklist; 336 GR_STATIC_ASSERT(kLast_GrBlendEquation < 32); 337 338 uint32_t fMapBufferFlags; 339 int fBufferMapThreshold; 340 341 int fMaxRenderTargetSize; 342 int fMaxVertexAttributes; 343 int fMaxTextureSize; 344 int fMaxTileSize; 345 int fMaxColorSampleCount; 346 int fMaxStencilSampleCount; 347 int fMaxRasterSamples; 348 int fMaxWindowRectangles; 349 350 private: onApplyOptionsOverrides(const GrContextOptions &)351 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} 352 353 bool fSuppressPrints : 1; 354 bool fImmediateFlush: 1; 355 356 typedef SkRefCnt INHERITED; 357 }; 358 359 #endif 360