xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrCaps.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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