1 | |
---|---|
2 | /* |
3 | * Copyright 2013 Google Inc. |
4 | * |
5 | * Use of this source code is governed by a BSD-style license that can be |
6 | * found in the LICENSE file. |
7 | */ |
8 | #ifndef GrCaps_DEFINED |
9 | #define GrCaps_DEFINED |
10 | |
11 | #include "include/core/SkCapabilities.h" |
12 | #include "include/core/SkRefCnt.h" |
13 | #include "include/core/SkTypes.h" |
14 | #include "include/gpu/GrDriverBugWorkarounds.h" |
15 | #include "include/gpu/GrTypes.h" |
16 | #include "include/private/base/SkTo.h" |
17 | #include "include/private/gpu/ganesh/GrTypesPriv.h" |
18 | #include "src/gpu/Blend.h" |
19 | #include "src/gpu/Swizzle.h" |
20 | #include "src/gpu/ganesh/GrSamplerState.h" |
21 | #include "src/gpu/ganesh/GrShaderCaps.h" |
22 | #include "src/gpu/ganesh/GrSurfaceProxy.h" |
23 | |
24 | #include <algorithm> |
25 | #include <cstddef> |
26 | #include <cstdint> |
27 | #include <memory> |
28 | #include <tuple> |
29 | #include <vector> |
30 | |
31 | class GrBackendFormat; |
32 | class GrBackendRenderTarget; |
33 | class GrProgramDesc; |
34 | class GrProgramInfo; |
35 | class GrRenderTarget; |
36 | class GrRenderTargetProxy; |
37 | class GrSurface; |
38 | class SkJSONWriter; |
39 | enum class SkTextureCompressionType; |
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 | |
60 | const GrShaderCaps* shaderCaps() const { return fShaderCaps.get(); } |
61 | |
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) */ |
65 | bool mipmapSupport() const { return fMipmapSupport; } |
66 | /** Is anisotropic filtering supported. */ |
67 | bool anisoSupport() const { return fAnisoSupport; } |
68 | |
69 | bool gpuTracingSupport() const { return fGpuTracingSupport; } |
70 | bool oversizedStencilSupport() const { return fOversizedStencilSupport; } |
71 | bool textureBarrierSupport() const { return fTextureBarrierSupport; } |
72 | bool sampleLocationsSupport() const { return fSampleLocationsSupport; } |
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.) |
77 | bool nativeDrawIndirectSupport() const { return fNativeDrawIndirectSupport; } |
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 | } |
88 | bool conservativeRasterSupport() const { return fConservativeRasterSupport; } |
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. |
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. |
100 | bool preferDiscardableMSAAAttachment() const { return fPreferDiscardableMSAAAttachment; } |
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. |
105 | bool usePrimitiveRestart() const { return fUsePrimitiveRestart; } |
106 | |
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. |
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.) |
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. |
126 | bool twoSidedStencilRefsAndMasksMustMatch() const { |
127 | return fTwoSidedStencilRefsAndMasksMustMatch; |
128 | } |
129 | |
130 | bool preferVRAMUseOverFlushes() const { return fPreferVRAMUseOverFlushes; } |
131 | |
132 | bool avoidStencilBuffers() const { return fAvoidStencilBuffers; } |
133 | |
134 | bool avoidWritePixelsFastPath() const { return fAvoidWritePixelsFastPath; } |
135 | |
136 | // glDrawElementsIndirect fails GrMeshTest on every Win10 Intel bot. |
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 | |
153 | BlendEquationSupport blendEquationSupport() const { return fBlendEquationSupport; } |
154 | |
155 | bool advancedBlendEquationSupport() const { |
156 | return fBlendEquationSupport >= kAdvanced_BlendEquationSupport; |
157 | } |
158 | |
159 | bool advancedCoherentBlendEquationSupport() const { |
160 | return kAdvancedCoherent_BlendEquationSupport == fBlendEquationSupport; |
161 | } |
162 | |
163 | bool isAdvancedBlendEquationDisabled(skgpu::BlendEquation equation) const { |
164 | SkASSERT(skgpu::BlendEquationIsAdvanced(equation)); |
165 | SkASSERT(this->advancedBlendEquationSupport()); |
166 | return SkToBool(x: 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. |
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. |
178 | bool mustSyncGpuDuringAbandon() const { |
179 | return fMustSyncGpuDuringAbandon; |
180 | } |
181 | |
182 | // Shortcut for shaderCaps()->fReducedShaderMode. |
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. |
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). |
210 | bool reuseScratchTextures() const { return fReuseScratchTextures; } |
211 | bool reuseScratchBuffers() const { return fReuseScratchBuffers; } |
212 | |
213 | /// maximum number of attribute values per vertex |
214 | int maxVertexAttributes() const { return fMaxVertexAttributes; } |
215 | |
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. */ |
220 | int maxPreferredRenderTargetSize() const { return fMaxPreferredRenderTargetSize; } |
221 | |
222 | int maxTextureSize() const { return fMaxTextureSize; } |
223 | |
224 | int maxWindowRectangles() const { return fMaxWindowRectangles; } |
225 | |
226 | // Returns whether window rectangles are supported for the given backend render target. |
227 | bool isWindowRectanglesSupportedForRT(const GrBackendRenderTarget& rt) const { |
228 | return this->maxWindowRectangles() > 0 && this->onIsWindowRectanglesSupportedForRT(rt); |
229 | } |
230 | |
231 | uint32_t maxPushConstantsSize() const { return fMaxPushConstantsSize; } |
232 | |
233 | // Alignment requirement for row bytes in buffer<->texture transfers. |
234 | size_t transferBufferRowBytesAlignment() const { return fTransferBufferRowBytesAlignment; } |
235 | |
236 | // Alignment requirement for offsets and size in buffer->buffer transfers. |
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. |
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. |
264 | int internalMultisampleCount(const GrBackendFormat& format) const { |
265 | return std::min(a: fInternalMultisampleCount, b: 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 | */ |
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 | */ |
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 | */ |
358 | bool readPixelsRowBytesSupport() const { return fReadPixelsRowBytesSupport; } |
359 | |
360 | bool transferFromSurfaceToBufferSupport() const { return fTransferFromSurfaceToBufferSupport; } |
361 | bool transferFromBufferToTextureSupport() const { return fTransferFromBufferToTextureSupport; } |
362 | bool transferFromBufferToBufferSupport() const { return fTransferFromBufferToBufferSupport; } |
363 | |
364 | bool suppressPrints() const { return fSuppressPrints; } |
365 | |
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). */ |
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 | */ |
379 | bool shouldInitializeTextures() const { return fShouldInitializeTextures; } |
380 | |
381 | /** |
382 | * When a new GrGpuBuffer is created is it known to contain all zero bytes? |
383 | */ |
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 | * */ |
390 | bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; } |
391 | |
392 | bool wireframeMode() const { return fWireframeMode; } |
393 | |
394 | /** Supports using GrFence. */ |
395 | bool fenceSyncSupport() const { return fFenceSyncSupport; } |
396 | |
397 | /** Supports using GrSemaphore. */ |
398 | bool semaphoreSupport() const { return fSemaphoreSupport; } |
399 | |
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 | |
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. |
413 | bool performPartialClearsAsDraws() const { |
414 | return fPerformColorClearsAsDraws || fPerformPartialClearsAsDraws; |
415 | } |
416 | |
417 | // Many drivers have issues with color clears. |
418 | bool performColorClearsAsDraws() const { return fPerformColorClearsAsDraws; } |
419 | |
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. |
425 | bool performStencilClearsAsDraws() const { return fPerformStencilClearsAsDraws; } |
426 | |
427 | // Should we disable TessellationPathRenderer due to a faulty driver? |
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 | }; |
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(SkTextureCompressionType) 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 | */ |
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 | |
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 | */ |
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. |
516 | virtual GrInternalSurfaceFlags getExtraSurfaceFlagsForDeferredRT() const { |
517 | return GrInternalSurfaceFlags::kNone; |
518 | } |
519 | |
520 | bool supportsDynamicMSAA(const GrRenderTargetProxy*) const; |
521 | |
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. |
525 | bool avoidReorderingRenderTasks() const { |
526 | return fAvoidReorderingRenderTasks; |
527 | } |
528 | |
529 | bool avoidDithering() const { |
530 | return fAvoidDithering; |
531 | } |
532 | |
533 | bool disablePerspectiveSDFText() const { |
534 | return fDisablePerspectiveSDFText; |
535 | } |
536 | |
537 | // anglebug.com/7796 |
538 | bool avoidLineDraws() const { return fAvoidLineDraws; } |
539 | |
540 | /** |
541 | * Checks whether the passed color type is renderable. If so, the same color type is passed |
542 | * back along with the default format used for the color type. If not, provides an alternative |
543 | * (perhaps lower bit depth and/or unorm instead of float) color type that is supported |
544 | * along with it's default format or kUnknown if there no renderable fallback format. |
545 | */ |
546 | std::tuple<GrColorType, GrBackendFormat> getFallbackColorTypeAndFormat(GrColorType, |
547 | int sampleCount) const; |
548 | |
549 | #if GR_TEST_UTILS |
550 | virtual std::vector<GrTest::TestFormatColorTypeCombination> getTestingCombinations() const = 0; |
551 | #endif |
552 | |
553 | protected: |
554 | // Subclasses must call this at the end of their init method in order to do final processing on |
555 | // the caps (including overrides requested by the client). |
556 | // NOTE: this method will only reduce the caps, never expand them. |
557 | void finishInitialization(const GrContextOptions& options); |
558 | |
559 | virtual bool onSupportsDynamicMSAA(const GrRenderTargetProxy*) const { return false; } |
560 | |
561 | std::unique_ptr<GrShaderCaps> fShaderCaps; |
562 | |
563 | bool fNPOTTextureTileSupport : 1; |
564 | bool fMipmapSupport : 1; |
565 | bool fAnisoSupport : 1; |
566 | bool fReuseScratchTextures : 1; |
567 | bool fReuseScratchBuffers : 1; |
568 | bool fGpuTracingSupport : 1; |
569 | bool fOversizedStencilSupport : 1; |
570 | bool fTextureBarrierSupport : 1; |
571 | bool fSampleLocationsSupport : 1; |
572 | bool fDrawInstancedSupport : 1; |
573 | bool fNativeDrawIndirectSupport : 1; |
574 | bool fUseClientSideIndirectBuffers : 1; |
575 | bool fConservativeRasterSupport : 1; |
576 | bool fWireframeSupport : 1; |
577 | bool fMSAAResolvesAutomatically : 1; |
578 | bool fPreferDiscardableMSAAAttachment : 1; |
579 | bool fUsePrimitiveRestart : 1; |
580 | bool fPreferClientSideDynamicBuffers : 1; |
581 | bool fPreferFullscreenClears : 1; |
582 | bool fTwoSidedStencilRefsAndMasksMustMatch : 1; |
583 | bool fMustClearUploadedBufferData : 1; |
584 | bool fBuffersAreInitiallyZero : 1; |
585 | bool fShouldInitializeTextures : 1; |
586 | bool fSupportsAHardwareBufferImages : 1; |
587 | bool fHalfFloatVertexAttributeSupport : 1; |
588 | bool fClampToBorderSupport : 1; |
589 | bool fPerformPartialClearsAsDraws : 1; |
590 | bool fPerformColorClearsAsDraws : 1; |
591 | bool fAvoidLargeIndexBufferDraws : 1; |
592 | bool fPerformStencilClearsAsDraws : 1; |
593 | bool fTransferFromBufferToTextureSupport : 1; |
594 | bool fTransferFromSurfaceToBufferSupport : 1; |
595 | bool fTransferFromBufferToBufferSupport : 1; |
596 | bool fWritePixelsRowBytesSupport : 1; |
597 | bool fTransferPixelsToRowBytesSupport : 1; |
598 | bool fReadPixelsRowBytesSupport : 1; |
599 | bool fShouldCollapseSrcOverToSrcWhenAble : 1; |
600 | bool fMustSyncGpuDuringAbandon : 1; |
601 | |
602 | // Driver workaround |
603 | bool fDisableTessellationPathRenderer : 1; |
604 | bool fAvoidStencilBuffers : 1; |
605 | bool fAvoidWritePixelsFastPath : 1; |
606 | bool fNativeDrawIndexedIndirectIsBroken : 1; |
607 | bool fAvoidReorderingRenderTasks : 1; |
608 | bool fAvoidDithering : 1; |
609 | bool fDisablePerspectiveSDFText : 1; |
610 | bool fAvoidLineDraws : 1; |
611 | |
612 | // ANGLE performance workaround |
613 | bool fPreferVRAMUseOverFlushes : 1; |
614 | |
615 | bool fFenceSyncSupport : 1; |
616 | bool fSemaphoreSupport : 1; |
617 | |
618 | // Requires fence sync support in GL. |
619 | bool fCrossContextTextureSupport : 1; |
620 | |
621 | // Not (yet) implemented in VK backend. |
622 | bool fDynamicStateArrayGeometryProcessorTextureSupport : 1; |
623 | |
624 | BlendEquationSupport fBlendEquationSupport; |
625 | uint32_t fAdvBlendEqDisableFlags; |
626 | static_assert(static_cast<int>(skgpu::BlendEquation::kLast) < 32); |
627 | |
628 | uint32_t fMapBufferFlags; |
629 | int fBufferMapThreshold; |
630 | |
631 | int fMaxRenderTargetSize; |
632 | int fMaxPreferredRenderTargetSize; |
633 | int fMaxVertexAttributes; |
634 | int fMaxTextureSize; |
635 | int fMaxWindowRectangles; |
636 | int fInternalMultisampleCount; |
637 | uint32_t fMaxPushConstantsSize = 0; |
638 | size_t fTransferBufferRowBytesAlignment = 1; |
639 | size_t fTransferFromBufferToBufferAlignment = 1; |
640 | size_t fBufferUpdateDataPreserveAlignment = 1; |
641 | |
642 | GrDriverBugWorkarounds fDriverBugWorkarounds; |
643 | |
644 | private: |
645 | void applyOptionsOverrides(const GrContextOptions& options); |
646 | |
647 | virtual void onApplyOptionsOverrides(const GrContextOptions&) {} |
648 | virtual void onDumpJSON(SkJSONWriter*) const {} |
649 | virtual bool onSurfaceSupportsWritePixels(const GrSurface*) const = 0; |
650 | virtual bool onCanCopySurface(const GrSurfaceProxy* dst, const SkIRect& dstRect, |
651 | const GrSurfaceProxy* src, const SkIRect& srcRect) const = 0; |
652 | virtual GrBackendFormat onGetDefaultBackendFormat(GrColorType) const = 0; |
653 | |
654 | // Backends should implement this if they have any extra requirements for use of window |
655 | // rectangles for a specific GrBackendRenderTarget outside of basic support. |
656 | virtual bool onIsWindowRectanglesSupportedForRT(const GrBackendRenderTarget&) const { |
657 | return true; |
658 | } |
659 | |
660 | virtual bool onAreColorTypeAndFormatCompatible(GrColorType, const GrBackendFormat&) const = 0; |
661 | |
662 | virtual SupportedRead onSupportedReadPixelsColorType(GrColorType srcColorType, |
663 | const GrBackendFormat& srcFormat, |
664 | GrColorType dstColorType) const = 0; |
665 | |
666 | virtual skgpu::Swizzle onGetReadSwizzle(const GrBackendFormat&, GrColorType) const = 0; |
667 | |
668 | virtual GrDstSampleFlags onGetDstSampleFlagsForProxy(const GrRenderTargetProxy*) const { |
669 | return GrDstSampleFlags::kNone; |
670 | } |
671 | |
672 | bool fSuppressPrints : 1; |
673 | bool fWireframeMode : 1; |
674 | |
675 | using INHERITED = SkRefCnt; |
676 | }; |
677 | |
678 | GR_MAKE_BITFIELD_CLASS_OPS(GrCaps::ProgramDescOverrideFlags) |
679 | |
680 | #endif |
681 |
Definitions
- GrCaps
- shaderCaps
- npotTextureTileSupport
- mipmapSupport
- anisoSupport
- gpuTracingSupport
- oversizedStencilSupport
- textureBarrierSupport
- sampleLocationsSupport
- drawInstancedSupport
- nativeDrawIndirectSupport
- useClientSideIndirectBuffers
- conservativeRasterSupport
- wireframeSupport
- msaaResolvesAutomatically
- preferDiscardableMSAAAttachment
- halfFloatVertexAttributeSupport
- usePrimitiveRestart
- preferClientSideDynamicBuffers
- preferFullscreenClears
- discardStencilValuesAfterRenderPass
- twoSidedStencilRefsAndMasksMustMatch
- preferVRAMUseOverFlushes
- avoidStencilBuffers
- avoidWritePixelsFastPath
- nativeDrawIndexedIndirectIsBroken
- BlendEquationSupport
- blendEquationSupport
- advancedBlendEquationSupport
- advancedCoherentBlendEquationSupport
- isAdvancedBlendEquationDisabled
- shouldCollapseSrcOverToSrcWhenAble
- mustSyncGpuDuringAbandon
- reducedShaderMode
- MapFlags
- mapBufferFlags
- reuseScratchTextures
- reuseScratchBuffers
- maxVertexAttributes
- maxRenderTargetSize
- maxPreferredRenderTargetSize
- maxTextureSize
- maxWindowRectangles
- isWindowRectanglesSupportedForRT
- maxPushConstantsSize
- transferBufferRowBytesAlignment
- transferFromBufferToBufferAlignment
- bufferUpdateDataPreserveAlignment
- internalMultisampleCount
- SurfaceReadPixelsSupport
- SupportedWrite
- SupportedRead
- writePixelsRowBytesSupport
- transferPixelsToRowBytesSupport
- readPixelsRowBytesSupport
- transferFromSurfaceToBufferSupport
- transferFromBufferToTextureSupport
- transferFromBufferToBufferSupport
- suppressPrints
- bufferMapThreshold
- mustClearUploadedBufferData
- shouldInitializeTextures
- buffersAreInitiallyZero
- supportsAHardwareBufferImages
- wireframeMode
- fenceSyncSupport
- semaphoreSupport
- crossContextTextureSupport
- dynamicStateArrayGeometryProcessorTextureSupport
- performPartialClearsAsDraws
- performColorClearsAsDraws
- avoidLargeIndexBufferDraws
- performStencilClearsAsDraws
- disableTessellationPathRenderer
- DstCopyRestrictions
- getDstCopyRestrictions
- clampToBorderSupport
- workarounds
- addExtraSamplerKey
- ProgramDescOverrideFlags
- getExtraSurfaceFlagsForDeferredRT
- dmsaaResolveCanBeUsedAsTextureInSameRenderPass
- avoidReorderingRenderTasks
- avoidDithering
- disablePerspectiveSDFText
- avoidLineDraws
- onSupportsDynamicMSAA
- onApplyOptionsOverrides
- onDumpJSON
- onIsWindowRectanglesSupportedForRT
Learn more about Flutter for embedded and desktop on industrialflutter.com