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