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