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