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 "include/core/SkImageInfo.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/core/SkString.h" 14 #include "include/gpu/GrDriverBugWorkarounds.h" 15 #include "include/private/GrTypesPriv.h" 16 #include "src/core/SkCompressedDataUtils.h" 17 #include "src/gpu/GrBlend.h" 18 #include "src/gpu/GrSamplerState.h" 19 #include "src/gpu/GrShaderCaps.h" 20 #include "src/gpu/GrSurfaceProxy.h" 21 #include "src/gpu/Swizzle.h" 22 23 class GrBackendFormat; 24 class GrBackendRenderTarget; 25 class GrBackendTexture; 26 struct GrContextOptions; 27 class GrProgramDesc; 28 class GrProgramInfo; 29 class GrRenderTargetProxy; 30 class GrSurface; 31 class SkJSONWriter; 32 33 namespace skgpu { 34 class KeyBuilder; 35 } 36 37 /** 38 * Represents the capabilities of a GrContext. 39 */ 40 class GrCaps : public SkRefCnt { 41 public: 42 GrCaps(const GrContextOptions&); 43 44 void dumpJSON(SkJSONWriter*) const; 45 shaderCaps()46 const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } 47 npotTextureTileSupport()48 bool npotTextureTileSupport() const { return fNPOTTextureTileSupport; } 49 /** To avoid as-yet-unnecessary complexity we don't allow any partial support of MIP Maps (e.g. 50 only for POT textures) */ mipmapSupport()51 bool mipmapSupport() const { return fMipmapSupport; } 52 gpuTracingSupport()53 bool gpuTracingSupport() const { return fGpuTracingSupport; } oversizedStencilSupport()54 bool oversizedStencilSupport() const { return fOversizedStencilSupport; } textureBarrierSupport()55 bool textureBarrierSupport() const { return fTextureBarrierSupport; } sampleLocationsSupport()56 bool sampleLocationsSupport() const { return fSampleLocationsSupport; } drawInstancedSupport()57 bool drawInstancedSupport() const { return fDrawInstancedSupport; } 58 // Is there hardware support for indirect draws? (Ganesh always supports indirect draws as long 59 // as it can polyfill them with instanced calls, but this cap tells us if they are supported 60 // natively.) nativeDrawIndirectSupport()61 bool nativeDrawIndirectSupport() const { return fNativeDrawIndirectSupport; } useClientSideIndirectBuffers()62 bool useClientSideIndirectBuffers() const { 63 #ifdef SK_DEBUG 64 if (!fNativeDrawIndirectSupport || fNativeDrawIndexedIndirectIsBroken) { 65 // We might implement indirect draws with a polyfill, so the commands need to reside in 66 // CPU memory. 67 SkASSERT(fUseClientSideIndirectBuffers); 68 } 69 #endif 70 return fUseClientSideIndirectBuffers; 71 } conservativeRasterSupport()72 bool conservativeRasterSupport() const { return fConservativeRasterSupport; } wireframeSupport()73 bool wireframeSupport() const { return fWireframeSupport; } 74 // This flag indicates that we never have to resolve MSAA. In practice, it means that we have 75 // an MSAA-render-to-texture extension: Any render target we create internally will use the 76 // extension, and any wrapped render target is the client's responsibility. msaaResolvesAutomatically()77 bool msaaResolvesAutomatically() const { return fMSAAResolvesAutomatically; } 78 // If true then when doing MSAA draws, we will prefer to discard the msaa attachment on load 79 // and stores. The use of this feature for specific draws depends on the render target having a 80 // resolve attachment, and if we need to load previous data the resolve attachment must be 81 // usable as an input attachment/texture. Otherwise we will just write out and store the msaa 82 // attachment like normal. 83 // This flag is similar to enabling gl render to texture for msaa rendering. preferDiscardableMSAAAttachment()84 bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; } halfFloatVertexAttributeSupport()85 bool halfFloatVertexAttributeSupport() const { return fHalfFloatVertexAttributeSupport; } 86 87 // Primitive restart functionality is core in ES 3.0, but using it will cause slowdowns on some 88 // systems. This cap is only set if primitive restart will improve performance. usePrimitiveRestart()89 bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } 90 preferClientSideDynamicBuffers()91 bool preferClientSideDynamicBuffers() const { return fPreferClientSideDynamicBuffers; } 92 93 // On tilers, an initial fullscreen clear is an OPTIMIZATION. It allows the hardware to 94 // initialize each tile with a constant value rather than loading each pixel from memory. preferFullscreenClears()95 bool preferFullscreenClears() const { return fPreferFullscreenClears; } 96 97 // Should we discard stencil values after a render pass? (Tilers get better performance if we 98 // always load stencil buffers with a "clear" op, and then discard the content when finished.) discardStencilValuesAfterRenderPass()99 bool discardStencilValuesAfterRenderPass() const { 100 // b/160958008 101 return false; 102 #if 0 103 // This method is actually just a duplicate of preferFullscreenClears(), with a descriptive 104 // name for the sake of readability. 105 return this->preferFullscreenClears(); 106 #endif 107 } 108 109 // D3D does not allow the refs or masks to differ on a two-sided stencil draw. twoSidedStencilRefsAndMasksMustMatch()110 bool twoSidedStencilRefsAndMasksMustMatch() const { 111 return fTwoSidedStencilRefsAndMasksMustMatch; 112 } 113 preferVRAMUseOverFlushes()114 bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } 115 avoidStencilBuffers()116 bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } 117 avoidWritePixelsFastPath()118 bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; } 119 120 // http://skbug.com/9739 requiresManualFBBarrierAfterTessellatedStencilDraw()121 bool requiresManualFBBarrierAfterTessellatedStencilDraw() const { 122 return fRequiresManualFBBarrierAfterTessellatedStencilDraw; 123 } 124 125 // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot. nativeDrawIndexedIndirectIsBroken()126 bool nativeDrawIndexedIndirectIsBroken() const { return fNativeDrawIndexedIndirectIsBroken; } 127 128 /** 129 * Indicates the capabilities of the fixed function blend unit. 130 */ 131 enum BlendEquationSupport { 132 kBasic_BlendEquationSupport, //<! Support to select the operator that 133 // combines src and dst terms. 134 kAdvanced_BlendEquationSupport, //<! Additional fixed function support for specific 135 // SVG/PDF blend modes. Requires blend barriers. 136 kAdvancedCoherent_BlendEquationSupport, //<! Advanced blend equation support that does not 137 // require blend barriers, and permits overlap. 138 139 kLast_BlendEquationSupport = kAdvancedCoherent_BlendEquationSupport 140 }; 141 blendEquationSupport()142 BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } 143 advancedBlendEquationSupport()144 bool advancedBlendEquationSupport() const { 145 return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; 146 } 147 advancedCoherentBlendEquationSupport()148 bool advancedCoherentBlendEquationSupport() const { 149 return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; 150 } 151 isAdvancedBlendEquationDisabled(GrBlendEquation equation)152 bool isAdvancedBlendEquationDisabled(GrBlendEquation equation) const { 153 SkASSERT(GrBlendEquationIsAdvanced(equation)); 154 SkASSERT(this->advancedBlendEquationSupport()); 155 return SkToBool(fAdvBlendEqDisableFlags & (1 << equation)); 156 } 157 158 // On some GPUs it is a performance win to disable blending instead of doing src-over with a src 159 // alpha equal to 1. To disable blending we collapse src-over to src and the backends will 160 // handle the disabling of blending. shouldCollapseSrcOverToSrcWhenAble()161 bool shouldCollapseSrcOverToSrcWhenAble() const { 162 return fShouldCollapseSrcOverToSrcWhenAble; 163 } 164 165 // When abandoning the GrDirectContext do we need to sync the GPU before we start abandoning 166 // resources. mustSyncGpuDuringAbandon()167 bool mustSyncGpuDuringAbandon() const { 168 return fMustSyncGpuDuringAbandon; 169 } 170 171 // Shortcut for shaderCaps()->reducedShaderMode(). reducedShaderMode()172 bool reducedShaderMode() const { return this->shaderCaps()->reducedShaderMode(); } 173 174 /** 175 * Indicates whether GPU->CPU memory mapping for GPU resources such as vertex buffers and 176 * textures allows partial mappings or full mappings. 177 */ 178 enum MapFlags { 179 kNone_MapFlags = 0x0, //<! Cannot map the resource. 180 181 kCanMap_MapFlag = 0x1, //<! The resource can be mapped. Must be set for any of 182 // the other flags to have meaning. 183 kSubset_MapFlag = 0x2, //<! The resource can be partially mapped. 184 kAsyncRead_MapFlag = 0x4, //<! Are maps for reading asynchronous WRT GrOpsRenderPass 185 // submitted to GrGpu. 186 }; 187 188 // This returns the general mapping support for the GPU. However, even if this returns a flag 189 // that says buffers can be mapped, it does NOT mean that every buffer will be mappable. Thus 190 // calls of map should still check to see if a valid pointer was returned from the map call and 191 // handle fallbacks appropriately. If this does return kNone_MapFlags then all calls to map() on 192 // any buffer will fail. mapBufferFlags()193 uint32_t mapBufferFlags() const { return fMapBufferFlags; } 194 195 // Scratch textures not being reused means that those scratch textures 196 // that we upload to (i.e., don't have a render target) will not be 197 // recycled in the texture cache. This is to prevent ghosting by drivers 198 // (in particular for deferred architectures). reuseScratchTextures()199 bool reuseScratchTextures() const { return fReuseScratchTextures; } reuseScratchBuffers()200 bool reuseScratchBuffers() const { return fReuseScratchBuffers; } 201 202 /// maximum number of attribute values per vertex maxVertexAttributes()203 int maxVertexAttributes() const { return fMaxVertexAttributes; } 204 maxRenderTargetSize()205 int maxRenderTargetSize() const { return fMaxRenderTargetSize; } 206 207 /** This is the largest render target size that can be used without incurring extra perfomance 208 cost. It is usually the max RT size, unless larger render targets are known to be slower. */ maxPreferredRenderTargetSize()209 int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; } 210 maxTextureSize()211 int maxTextureSize() const { return fMaxTextureSize; } 212 maxWindowRectangles()213 int maxWindowRectangles() const { return fMaxWindowRectangles; } 214 215 // Returns whether window rectangles are supported for the given backend render target. isWindowRectanglesSupportedForRT(const GrBackendRenderTarget & rt)216 bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { 217 return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); 218 } 219 220 // Hardware tessellation seems to have a fixed upfront cost. If there is a somewhat small number 221 // of verbs, we seem to be faster emulating tessellation with instanced draws instead. minPathVerbsForHwTessellation()222 int minPathVerbsForHwTessellation() const { return fMinPathVerbsForHwTessellation; } minStrokeVerbsForHwTessellation()223 int minStrokeVerbsForHwTessellation() const { return fMinStrokeVerbsForHwTessellation; } 224 maxPushConstantsSize()225 uint32_t maxPushConstantsSize() const { return fMaxPushConstantsSize; } 226 transferBufferAlignment()227 size_t transferBufferAlignment() const { return fTransferBufferAlignment; } 228 229 virtual bool isFormatSRGB(const GrBackendFormat&) const = 0; 230 231 bool isFormatCompressed(const GrBackendFormat& format) const; 232 233 // Can a texture be made with the GrBackendFormat and texture type, and then be bound and 234 // sampled in a shader. 235 virtual bool isFormatTexturable(const GrBackendFormat&, GrTextureType) const = 0; 236 237 // Returns whether a texture of the given format can be copied to a texture of the same format. 238 virtual bool isFormatCopyable(const GrBackendFormat&) const = 0; 239 240 // Returns the maximum supported sample count for a format. 0 means the format is not renderable 241 // 1 means the format is renderable but doesn't support MSAA. 242 virtual int maxRenderTargetSampleCount(const GrBackendFormat&) const = 0; 243 244 // Returns the number of samples to use when performing draws to the given config with internal 245 // MSAA. If 0, Ganesh should not attempt to use internal multisampling. internalMultisampleCount(const GrBackendFormat & format)246 int internalMultisampleCount(const GrBackendFormat& format) const { 247 return std::min(fInternalMultisampleCount, this->maxRenderTargetSampleCount(format)); 248 } 249 250 virtual bool isFormatAsColorTypeRenderable(GrColorType ct, const GrBackendFormat& format, 251 int sampleCount = 1) const = 0; 252 253 virtual bool isFormatRenderable(const GrBackendFormat& format, int sampleCount) const = 0; 254 255 // Find a sample count greater than or equal to the requested count which is supported for a 256 // render target of the given format or 0 if no such sample count is supported. If the requested 257 // sample count is 1 then 1 will be returned if non-MSAA rendering is supported, otherwise 0. 258 // For historical reasons requestedCount==0 is handled identically to requestedCount==1. 259 virtual int getRenderTargetSampleCount(int requestedCount, const GrBackendFormat&) const = 0; 260 261 /** 262 * Backends may have restrictions on what types of surfaces support GrGpu::writePixels(). 263 * If this returns false then the caller should implement a fallback where a temporary texture 264 * is created, pixels are written to it, and then that is copied or drawn into the the surface. 265 */ 266 bool surfaceSupportsWritePixels(const GrSurface*) const; 267 268 /** 269 * Indicates whether surface supports GrGpu::readPixels, must be copied, or cannot be read. 270 */ 271 enum class SurfaceReadPixelsSupport { 272 /** GrGpu::readPixels is supported by the surface. */ 273 kSupported, 274 /** 275 * GrGpu::readPixels is not supported by this surface but this surface can be drawn 276 * or copied to a Ganesh-created GrTextureType::kTexture2D and then that surface will be 277 * readable. 278 */ 279 kCopyToTexture2D, 280 /** 281 * Not supported 282 */ 283 kUnsupported, 284 }; 285 /** 286 * Backends may have restrictions on what types of surfaces support GrGpu::readPixels(). We may 287 * either be able to read directly from the surface, read from a copy of the surface, or not 288 * read at all. 289 */ 290 virtual SurfaceReadPixelsSupport surfaceSupportsReadPixels(const GrSurface*) const = 0; 291 292 struct SupportedWrite { 293 GrColorType fColorType; 294 // If the write is occurring using GrGpu::transferPixelsTo then this provides the 295 // minimum alignment of the offset into the transfer buffer. 296 size_t fOffsetAlignmentForTransferBuffer; 297 }; 298 299 /** 300 * Given a dst pixel config and a src color type what color type must the caller coax the 301 * the data into in order to use GrGpu::writePixels(). 302 */ 303 virtual SupportedWrite supportedWritePixelsColorType(GrColorType surfaceColorType, 304 const GrBackendFormat& surfaceFormat, 305 GrColorType srcColorType) const = 0; 306 307 struct SupportedRead { 308 GrColorType fColorType; 309 // If the read is occurring using GrGpu::transferPixelsFrom then this provides the 310 // minimum alignment of the offset into the transfer buffer. 311 size_t fOffsetAlignmentForTransferBuffer; 312 }; 313 314 /** 315 * Given a src surface's color type and its backend format as well as a color type the caller 316 * would like read into, this provides a legal color type that the caller may pass to 317 * GrGpu::readPixels(). The returned color type may differ from the passed dstColorType, in 318 * which case the caller must convert the read pixel data (see GrConvertPixels). When converting 319 * to dstColorType the swizzle in the returned struct should be applied. The caller must check 320 * the returned color type for kUnknown. 321 */ 322 SupportedRead supportedReadPixelsColorType(GrColorType srcColorType, 323 const GrBackendFormat& srcFormat, 324 GrColorType dstColorType) const; 325 326 /** 327 * Does GrGpu::writePixels() support a src buffer where the row bytes is not equal to bpp * w? 328 */ writePixelsRowBytesSupport()329 bool writePixelsRowBytesSupport() const { return fWritePixelsRowBytesSupport; } 330 331 /** 332 * Does GrGpu::transferPixelsTo() support a src buffer where the row bytes is not equal to 333 * bpp * w? 334 */ transferPixelsToRowBytesSupport()335 bool transferPixelsToRowBytesSupport() const { return fTransferPixelsToRowBytesSupport; } 336 337 /** 338 * Does GrGpu::readPixels() support a dst buffer where the row bytes is not equal to bpp * w? 339 */ readPixelsRowBytesSupport()340 bool readPixelsRowBytesSupport() const { return fReadPixelsRowBytesSupport; } 341 transferFromSurfaceToBufferSupport()342 bool transferFromSurfaceToBufferSupport() const { return fTransferFromSurfaceToBufferSupport; } transferFromBufferToTextureSupport()343 bool transferFromBufferToTextureSupport() const { return fTransferFromBufferToTextureSupport; } 344 suppressPrints()345 bool suppressPrints() const { return fSuppressPrints; } 346 bufferMapThreshold()347 size_t bufferMapThreshold() const { 348 SkASSERT(fBufferMapThreshold >= 0); 349 return fBufferMapThreshold; 350 } 351 352 /** True in environments that will issue errors if memory uploaded to buffers 353 is not initialized (even if not read by draw calls). */ mustClearUploadedBufferData()354 bool mustClearUploadedBufferData() const { return fMustClearUploadedBufferData; } 355 356 /** For some environments, there is a performance or safety concern to not 357 initializing textures. For example, with WebGL and Firefox, there is a large 358 performance hit to not doing it. 359 */ shouldInitializeTextures()360 bool shouldInitializeTextures() const { return fShouldInitializeTextures; } 361 362 /** Returns true if the given backend supports importing AHardwareBuffers via the 363 * GrAHardwarebufferImageGenerator. This will only ever be supported on Android devices with API 364 * level >= 26. 365 * */ supportsAHardwareBufferImages()366 bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; } 367 wireframeMode()368 bool wireframeMode() const { return fWireframeMode; } 369 370 /** Supports using GrFence. */ fenceSyncSupport()371 bool fenceSyncSupport() const { return fFenceSyncSupport; } 372 373 /** Supports using GrSemaphore. */ semaphoreSupport()374 bool semaphoreSupport() const { return fSemaphoreSupport; } 375 crossContextTextureSupport()376 bool crossContextTextureSupport() const { return fCrossContextTextureSupport; } 377 /** 378 * Returns whether or not we will be able to do a copy given the passed in params 379 */ 380 bool canCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 381 const SkIRect& srcRect, const SkIPoint& dstPoint) const; 382 dynamicStateArrayGeometryProcessorTextureSupport()383 bool dynamicStateArrayGeometryProcessorTextureSupport() const { 384 return fDynamicStateArrayGeometryProcessorTextureSupport; 385 } 386 387 // Not all backends support clearing with a scissor test (e.g. Metal), this will always 388 // return true if performColorClearsAsDraws() returns true. performPartialClearsAsDraws()389 bool performPartialClearsAsDraws() const { 390 return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws; 391 } 392 393 // Many drivers have issues with color clears. performColorClearsAsDraws()394 bool performColorClearsAsDraws() const { return fPerformColorClearsAsDraws; } 395 avoidLargeIndexBufferDraws()396 bool avoidLargeIndexBufferDraws() const { return fAvoidLargeIndexBufferDraws; } 397 398 /// Adreno 4xx devices experience an issue when there are a large number of stencil clip bit 399 /// clears. The minimal repro steps are not precisely known but drawing a rect with a stencil 400 /// op instead of using glClear seems to resolve the issue. performStencilClearsAsDraws()401 bool performStencilClearsAsDraws() const { return fPerformStencilClearsAsDraws; } 402 403 // Should we disable the clip mask atlas due to a faulty driver? driverDisableMSAAClipAtlas()404 bool driverDisableMSAAClipAtlas() const { return fDriverDisableMSAAClipAtlas; } 405 406 // Should we disable TessellationPathRenderer due to a faulty driver? disableTessellationPathRenderer()407 bool disableTessellationPathRenderer() const { return fDisableTessellationPathRenderer; } 408 409 // Returns how to sample the dst values for the passed in GrRenderTargetProxy. 410 GrDstSampleFlags getDstSampleFlagsForProxy(const GrRenderTargetProxy*, bool drawUsesMSAA) const; 411 412 /** 413 * This is used to try to ensure a successful copy a dst in order to perform shader-based 414 * blending. 415 * 416 * fRectsMustMatch will be set to true if the copy operation must ensure that the src and dest 417 * rects are identical. 418 * 419 * fMustCopyWholeSrc will be set to true if copy rect must equal src's bounds. 420 * 421 * Caller will detect cases when copy cannot succeed and try copy-as-draw as a fallback. 422 */ 423 struct DstCopyRestrictions { 424 GrSurfaceProxy::RectsMustMatch fRectsMustMatch = GrSurfaceProxy::RectsMustMatch::kNo; 425 bool fMustCopyWholeSrc = false; 426 }; getDstCopyRestrictions(const GrRenderTargetProxy * src,GrColorType ct)427 virtual DstCopyRestrictions getDstCopyRestrictions(const GrRenderTargetProxy* src, 428 GrColorType ct) const { 429 return {}; 430 } 431 432 bool validateSurfaceParams(const SkISize&, const GrBackendFormat&, GrRenderable renderable, 433 int renderTargetSampleCnt, GrMipmapped, GrTextureType) const; 434 435 bool areColorTypeAndFormatCompatible(GrColorType grCT, const GrBackendFormat& format) const; 436 437 /** These are used when creating a new texture internally. */ 438 GrBackendFormat getDefaultBackendFormat(GrColorType, GrRenderable) const; 439 440 virtual GrBackendFormat getBackendFormatFromCompressionType(SkImage::CompressionType) const = 0; 441 442 /** 443 * The CLAMP_TO_BORDER wrap mode for texture coordinates was added to desktop GL in 1.3, and 444 * GLES 3.2, but is also available in extensions. Vulkan and Metal always have support. 445 */ clampToBorderSupport()446 bool clampToBorderSupport() const { return fClampToBorderSupport; } 447 448 /** 449 * Returns the skgpu::Swizzle to use when sampling or reading back from a texture with the 450 * passed in GrBackendFormat and GrColorType. 451 */ 452 skgpu::Swizzle getReadSwizzle(const GrBackendFormat& format, GrColorType colorType) const; 453 454 /** 455 * Returns the skgpu::Swizzle to use when writing colors to a surface with the passed in 456 * GrBackendFormat and GrColorType. 457 */ 458 virtual skgpu::Swizzle getWriteSwizzle(const GrBackendFormat&, GrColorType) const = 0; 459 460 virtual uint64_t computeFormatKey(const GrBackendFormat&) const = 0; 461 workarounds()462 const GrDriverBugWorkarounds& workarounds() const { return fDriverBugWorkarounds; } 463 464 /** 465 * Adds fields to the key to represent the sampler that will be created for the passed 466 * in parameters. Currently this extra keying is only needed when building a vulkan pipeline 467 * with immutable samplers. 468 */ addExtraSamplerKey(skgpu::KeyBuilder *,GrSamplerState,const GrBackendFormat &)469 virtual void addExtraSamplerKey(skgpu::KeyBuilder*, 470 GrSamplerState, 471 const GrBackendFormat&) const {} 472 473 enum class ProgramDescOverrideFlags { 474 kNone = 0, 475 // If using discardable msaa surfaces in vulkan, when we break up a render pass for an 476 // inline upload, we must do a load msaa subpass for the second render pass. However, if the 477 // original render pass did not have this load subpass (e.g. clear or discard load op), then 478 // all the GrProgramInfos for draws that end up in the second render pass will have been 479 // recorded thinking they will be in a render pass with only 1 subpass. Thus we add an 480 // override flag to the makeDesc call to force the actually VkPipeline that gets created to 481 // be created using a render pass with 2 subpasses. We do miss on the pre-compile with this 482 // approach, but inline uploads are very rare and already slow. 483 kVulkanHasResolveLoadSubpass = 0x1, 484 }; 485 GR_DECL_BITFIELD_CLASS_OPS_FRIENDS(ProgramDescOverrideFlags); 486 487 488 virtual GrProgramDesc makeDesc( 489 GrRenderTarget*, const GrProgramInfo&, 490 ProgramDescOverrideFlags overrideFlags = ProgramDescOverrideFlags::kNone) const = 0; 491 492 // This method specifies, for each backend, the extra properties of a RT when Ganesh creates one 493 // internally. For example, for Vulkan, Ganesh always creates RTs that can be used as input 494 // attachments. getExtraSurfaceFlagsForDeferredRT()495 virtual GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const { 496 return GrInternalSurfaceFlags::kNone; 497 } 498 499 bool supportsDynamicMSAA(const GrRenderTargetProxy*) const; 500 dmsaaResolveCanBeUsedAsTextureInSameRenderPass()501 virtual bool dmsaaResolveCanBeUsedAsTextureInSameRenderPass() const { return true; } 502 503 // skbug.com/11935. Task reordering is disabled for some GPUs on GL due to driver bugs. avoidReorderingRenderTasks()504 bool avoidReorderingRenderTasks() const { 505 return fAvoidReorderingRenderTasks; 506 } 507 avoidDithering()508 bool avoidDithering() const { 509 return fAvoidDithering; 510 } 511 512 /** 513 * Checks whether the passed color type is renderable. If so, the same color type is passed 514 * back along with the default format used for the color type. If not, provides an alternative 515 * (perhaps lower bit depth and/or unorm instead of float) color type that is supported 516 * along with it's default format or kUnknown if there no renderable fallback format. 517 */ 518 std::tuple<GrColorType, GrBackendFormat> getFallbackColorTypeAndFormat(GrColorType, 519 int sampleCount) const; 520 521 #if GR_TEST_UTILS 522 struct TestFormatColorTypeCombination { 523 GrColorType fColorType; 524 GrBackendFormat fFormat; 525 }; 526 527 virtual std::vector<TestFormatColorTypeCombination> getTestingCombinations() const = 0; 528 #endif 529 530 protected: 531 // Subclasses must call this at the end of their init method in order to do final processing on 532 // the caps (including overrides requested by the client). 533 // NOTE: this method will only reduce the caps, never expand them. 534 void finishInitialization(const GrContextOptions& options); 535 onSupportsDynamicMSAA(const GrRenderTargetProxy *)536 virtual bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const { return false; } 537 538 std::unique_ptr<GrShaderCaps> fShaderCaps; 539 540 bool fNPOTTextureTileSupport : 1; 541 bool fMipmapSupport : 1; 542 bool fReuseScratchTextures : 1; 543 bool fReuseScratchBuffers : 1; 544 bool fGpuTracingSupport : 1; 545 bool fOversizedStencilSupport : 1; 546 bool fTextureBarrierSupport : 1; 547 bool fSampleLocationsSupport : 1; 548 bool fDrawInstancedSupport : 1; 549 bool fNativeDrawIndirectSupport : 1; 550 bool fUseClientSideIndirectBuffers : 1; 551 bool fConservativeRasterSupport : 1; 552 bool fWireframeSupport : 1; 553 bool fMSAAResolvesAutomatically : 1; 554 bool fPreferDiscardableMSAAAttachment : 1; 555 bool fUsePrimitiveRestart : 1; 556 bool fPreferClientSideDynamicBuffers : 1; 557 bool fPreferFullscreenClears : 1; 558 bool fTwoSidedStencilRefsAndMasksMustMatch : 1; 559 bool fMustClearUploadedBufferData : 1; 560 bool fShouldInitializeTextures : 1; 561 bool fSupportsAHardwareBufferImages : 1; 562 bool fHalfFloatVertexAttributeSupport : 1; 563 bool fClampToBorderSupport : 1; 564 bool fPerformPartialClearsAsDraws : 1; 565 bool fPerformColorClearsAsDraws : 1; 566 bool fAvoidLargeIndexBufferDraws : 1; 567 bool fPerformStencilClearsAsDraws : 1; 568 bool fTransferFromBufferToTextureSupport : 1; 569 bool fTransferFromSurfaceToBufferSupport : 1; 570 bool fWritePixelsRowBytesSupport : 1; 571 bool fTransferPixelsToRowBytesSupport : 1; 572 bool fReadPixelsRowBytesSupport : 1; 573 bool fShouldCollapseSrcOverToSrcWhenAble : 1; 574 bool fMustSyncGpuDuringAbandon : 1; 575 576 // Driver workaround 577 bool fDriverDisableMSAAClipAtlas : 1; 578 bool fDisableTessellationPathRenderer : 1; 579 bool fAvoidStencilBuffers : 1; 580 bool fAvoidWritePixelsFastPath : 1; 581 bool fRequiresManualFBBarrierAfterTessellatedStencilDraw : 1; 582 bool fNativeDrawIndexedIndirectIsBroken : 1; 583 bool fAvoidReorderingRenderTasks : 1; 584 bool fAvoidDithering : 1; 585 586 // ANGLE performance workaround 587 bool fPreferVRAMUseOverFlushes : 1; 588 589 bool fFenceSyncSupport : 1; 590 bool fSemaphoreSupport : 1; 591 592 // Requires fence sync support in GL. 593 bool fCrossContextTextureSupport : 1; 594 595 // Not (yet) implemented in VK backend. 596 bool fDynamicStateArrayGeometryProcessorTextureSupport : 1; 597 598 BlendEquationSupport fBlendEquationSupport; 599 uint32_t fAdvBlendEqDisableFlags; 600 static_assert(kLast_GrBlendEquation < 32); 601 602 uint32_t fMapBufferFlags; 603 int fBufferMapThreshold; 604 605 int fMaxRenderTargetSize; 606 int fMaxPreferredRenderTargetSize; 607 int fMaxVertexAttributes; 608 int fMaxTextureSize; 609 int fMaxWindowRectangles; 610 int fInternalMultisampleCount; 611 int fMinPathVerbsForHwTessellation = 25; 612 int fMinStrokeVerbsForHwTessellation = 50; 613 uint32_t fMaxPushConstantsSize = 0; 614 size_t fTransferBufferAlignment = 1; 615 616 GrDriverBugWorkarounds fDriverBugWorkarounds; 617 618 private: 619 void applyOptionsOverrides(const GrContextOptions& options); 620 onApplyOptionsOverrides(const GrContextOptions &)621 virtual void onApplyOptionsOverrides(const GrContextOptions&) {} onDumpJSON(SkJSONWriter *)622 virtual void onDumpJSON(SkJSONWriter*) const {} 623 virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0; 624 virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const GrSurfaceProxy* src, 625 const SkIRect& srcRect, const SkIPoint& dstPoint) const = 0; 626 virtual GrBackendFormat onGetDefaultBackendFormat(GrColorType) const = 0; 627 628 // Backends should implement this if they have any extra requirements for use of window 629 // rectangles for a specific GrBackendRenderTarget outside of basic support. onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget &)630 virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { 631 return true; 632 } 633 634 virtual bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const = 0; 635 636 virtual SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType, 637 const GrBackendFormat& srcFormat, 638 GrColorType dstColorType) const = 0; 639 640 virtual skgpu::Swizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const = 0; 641 onGetDstSampleFlagsForProxy(const GrRenderTargetProxy *)642 virtual GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const { 643 return GrDstSampleFlags::kNone; 644 } 645 646 bool fSuppressPrints : 1; 647 bool fWireframeMode : 1; 648 649 using INHERITED = SkRefCnt; 650 }; 651 652 GR_MAKE_BITFIELD_CLASS_OPS(GrCaps::ProgramDescOverrideFlags) 653 654 #endif 655