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