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