xref: /aosp_15_r20/external/skia/src/gpu/graphite/Caps.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2021 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #ifndef skgpu_graphite_Caps_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_graphite_Caps_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include <optional>
12*c8dee2aaSAndroid Build Coastguard Worker #include <string>
13*c8dee2aaSAndroid Build Coastguard Worker #include <string_view>
14*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
15*c8dee2aaSAndroid Build Coastguard Worker 
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkImageInfo.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRefCnt.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAlign.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkEnumBitMask.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Swizzle.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceTypes.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/TextureProxy.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunControl.h"
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ContextOptionsPriv.h"
28*c8dee2aaSAndroid Build Coastguard Worker #endif
29*c8dee2aaSAndroid Build Coastguard Worker 
30*c8dee2aaSAndroid Build Coastguard Worker enum class SkBlendMode;
31*c8dee2aaSAndroid Build Coastguard Worker enum class SkTextureCompressionType;
32*c8dee2aaSAndroid Build Coastguard Worker class SkCapabilities;
33*c8dee2aaSAndroid Build Coastguard Worker 
34*c8dee2aaSAndroid Build Coastguard Worker namespace SkSL { struct ShaderCaps; }
35*c8dee2aaSAndroid Build Coastguard Worker 
36*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu { class ShaderErrorHandler; }
37*c8dee2aaSAndroid Build Coastguard Worker 
38*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker enum class BufferType : int;
41*c8dee2aaSAndroid Build Coastguard Worker struct ContextOptions;
42*c8dee2aaSAndroid Build Coastguard Worker class ComputePipelineDesc;
43*c8dee2aaSAndroid Build Coastguard Worker class GraphicsPipelineDesc;
44*c8dee2aaSAndroid Build Coastguard Worker class GraphiteResourceKey;
45*c8dee2aaSAndroid Build Coastguard Worker class RendererProvider;
46*c8dee2aaSAndroid Build Coastguard Worker struct RenderPassDesc;
47*c8dee2aaSAndroid Build Coastguard Worker class TextureInfo;
48*c8dee2aaSAndroid Build Coastguard Worker 
49*c8dee2aaSAndroid Build Coastguard Worker struct ResourceBindingRequirements {
50*c8dee2aaSAndroid Build Coastguard Worker     // The required data layout rules for the contents of a uniform buffer.
51*c8dee2aaSAndroid Build Coastguard Worker     Layout fUniformBufferLayout = Layout::kInvalid;
52*c8dee2aaSAndroid Build Coastguard Worker 
53*c8dee2aaSAndroid Build Coastguard Worker     // The required data layout rules for the contents of a storage buffer.
54*c8dee2aaSAndroid Build Coastguard Worker     Layout fStorageBufferLayout = Layout::kInvalid;
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     // Whether combined texture-sampler types are supported. Backends that do not support
57*c8dee2aaSAndroid Build Coastguard Worker     // combined image samplers (i.e. sampler2D) require a texture and sampler object to be bound
58*c8dee2aaSAndroid Build Coastguard Worker     // separately and their binding indices explicitly specified in the shader text.
59*c8dee2aaSAndroid Build Coastguard Worker     bool fSeparateTextureAndSamplerBinding = false;
60*c8dee2aaSAndroid Build Coastguard Worker 
61*c8dee2aaSAndroid Build Coastguard Worker     // Whether buffer, texture, and sampler resource bindings use distinct index ranges.
62*c8dee2aaSAndroid Build Coastguard Worker     bool fDistinctIndexRanges = false;
63*c8dee2aaSAndroid Build Coastguard Worker 
64*c8dee2aaSAndroid Build Coastguard Worker     int fIntrinsicBufferBinding = -1;
65*c8dee2aaSAndroid Build Coastguard Worker     int fRenderStepBufferBinding = -1;
66*c8dee2aaSAndroid Build Coastguard Worker     int fPaintParamsBufferBinding = -1;
67*c8dee2aaSAndroid Build Coastguard Worker     int fGradientBufferBinding = -1;
68*c8dee2aaSAndroid Build Coastguard Worker };
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker enum class DstReadRequirement {
71*c8dee2aaSAndroid Build Coastguard Worker     kNone,
72*c8dee2aaSAndroid Build Coastguard Worker     kTextureCopy,
73*c8dee2aaSAndroid Build Coastguard Worker     kTextureSample,
74*c8dee2aaSAndroid Build Coastguard Worker     kFramebufferFetch,
75*c8dee2aaSAndroid Build Coastguard Worker };
76*c8dee2aaSAndroid Build Coastguard Worker 
77*c8dee2aaSAndroid Build Coastguard Worker class Caps {
78*c8dee2aaSAndroid Build Coastguard Worker public:
79*c8dee2aaSAndroid Build Coastguard Worker     virtual ~Caps();
80*c8dee2aaSAndroid Build Coastguard Worker 
shaderCaps()81*c8dee2aaSAndroid Build Coastguard Worker     const SkSL::ShaderCaps* shaderCaps() const { return fShaderCaps.get(); }
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkCapabilities> capabilities() const;
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
deviceName()86*c8dee2aaSAndroid Build Coastguard Worker     std::string_view deviceName() const { return fDeviceName; }
87*c8dee2aaSAndroid Build Coastguard Worker 
requestedPathRendererStrategy()88*c8dee2aaSAndroid Build Coastguard Worker     PathRendererStrategy requestedPathRendererStrategy() const {
89*c8dee2aaSAndroid Build Coastguard Worker         return fRequestedPathRendererStrategy;
90*c8dee2aaSAndroid Build Coastguard Worker     }
91*c8dee2aaSAndroid Build Coastguard Worker #endif
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getDefaultSampledTextureInfo(SkColorType,
94*c8dee2aaSAndroid Build Coastguard Worker                                                      Mipmapped mipmapped,
95*c8dee2aaSAndroid Build Coastguard Worker                                                      Protected,
96*c8dee2aaSAndroid Build Coastguard Worker                                                      Renderable) const = 0;
97*c8dee2aaSAndroid Build Coastguard Worker 
98*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getTextureInfoForSampledCopy(const TextureInfo& textureInfo,
99*c8dee2aaSAndroid Build Coastguard Worker                                                      Mipmapped mipmapped) const = 0;
100*c8dee2aaSAndroid Build Coastguard Worker 
101*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getDefaultCompressedTextureInfo(SkTextureCompressionType,
102*c8dee2aaSAndroid Build Coastguard Worker                                                         Mipmapped mipmapped,
103*c8dee2aaSAndroid Build Coastguard Worker                                                         Protected) const = 0;
104*c8dee2aaSAndroid Build Coastguard Worker 
105*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
106*c8dee2aaSAndroid Build Coastguard Worker                                                   Discardable discardable) const = 0;
107*c8dee2aaSAndroid Build Coastguard Worker 
108*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>,
109*c8dee2aaSAndroid Build Coastguard Worker                                                           uint32_t sampleCount,
110*c8dee2aaSAndroid Build Coastguard Worker                                                           Protected) const = 0;
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     virtual TextureInfo getDefaultStorageTextureInfo(SkColorType) const = 0;
113*c8dee2aaSAndroid Build Coastguard Worker 
114*c8dee2aaSAndroid Build Coastguard Worker     // Get required depth attachment dimensions for a givin color attachment info and dimensions.
115*c8dee2aaSAndroid Build Coastguard Worker     virtual SkISize getDepthAttachmentDimensions(const TextureInfo&,
116*c8dee2aaSAndroid Build Coastguard Worker                                                  const SkISize colorAttachmentDimensions) const;
117*c8dee2aaSAndroid Build Coastguard Worker 
118*c8dee2aaSAndroid Build Coastguard Worker     virtual UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&,
119*c8dee2aaSAndroid Build Coastguard Worker                                               const RenderPassDesc&) const = 0;
120*c8dee2aaSAndroid Build Coastguard Worker     virtual UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const = 0;
121*c8dee2aaSAndroid Build Coastguard Worker 
122*c8dee2aaSAndroid Build Coastguard Worker     // Returns a GraphiteResourceKey based upon a SamplerDesc with any additional information that
123*c8dee2aaSAndroid Build Coastguard Worker     // backends append within their implementation. By default, simply returns a key based upon
124*c8dee2aaSAndroid Build Coastguard Worker     // the SamplerDesc with no extra info.
125*c8dee2aaSAndroid Build Coastguard Worker     // TODO: Rather than going through a GraphiteResourceKey, migrate to having a cache of samplers
126*c8dee2aaSAndroid Build Coastguard Worker     // keyed off of SamplerDesc to minimize heap allocations.
127*c8dee2aaSAndroid Build Coastguard Worker     virtual GraphiteResourceKey makeSamplerKey(const SamplerDesc& samplerDesc) const;
128*c8dee2aaSAndroid Build Coastguard Worker 
129*c8dee2aaSAndroid Build Coastguard Worker     // Backends can optionally override this method to return meaningful sampler conversion info.
130*c8dee2aaSAndroid Build Coastguard Worker     // By default, simply return a default ImmutableSamplerInfo.
getImmutableSamplerInfo(const TextureProxy *)131*c8dee2aaSAndroid Build Coastguard Worker     virtual ImmutableSamplerInfo getImmutableSamplerInfo(const TextureProxy*) const {
132*c8dee2aaSAndroid Build Coastguard Worker         return {};
133*c8dee2aaSAndroid Build Coastguard Worker     }
134*c8dee2aaSAndroid Build Coastguard Worker 
extractGraphicsDescs(const UniqueKey &,GraphicsPipelineDesc *,RenderPassDesc *,const RendererProvider *)135*c8dee2aaSAndroid Build Coastguard Worker     virtual bool extractGraphicsDescs(const UniqueKey&,
136*c8dee2aaSAndroid Build Coastguard Worker                                       GraphicsPipelineDesc*,
137*c8dee2aaSAndroid Build Coastguard Worker                                       RenderPassDesc*,
138*c8dee2aaSAndroid Build Coastguard Worker                                       const RendererProvider*) const { return false; }
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker     bool areColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo&) const;
141*c8dee2aaSAndroid Build Coastguard Worker     virtual uint32_t channelMask(const TextureInfo&) const = 0;
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker     bool isTexturable(const TextureInfo&) const;
144*c8dee2aaSAndroid Build Coastguard Worker     virtual bool isRenderable(const TextureInfo&) const = 0;
145*c8dee2aaSAndroid Build Coastguard Worker     virtual bool isStorage(const TextureInfo&) const = 0;
146*c8dee2aaSAndroid Build Coastguard Worker 
loadOpAffectsMSAAPipelines()147*c8dee2aaSAndroid Build Coastguard Worker     virtual bool loadOpAffectsMSAAPipelines() const { return false; }
148*c8dee2aaSAndroid Build Coastguard Worker 
maxTextureSize()149*c8dee2aaSAndroid Build Coastguard Worker     int maxTextureSize() const { return fMaxTextureSize; }
defaultMSAASamplesCount()150*c8dee2aaSAndroid Build Coastguard Worker     int defaultMSAASamplesCount() const { return fDefaultMSAASamples; }
151*c8dee2aaSAndroid Build Coastguard Worker 
152*c8dee2aaSAndroid Build Coastguard Worker     virtual void buildKeyForTexture(SkISize dimensions,
153*c8dee2aaSAndroid Build Coastguard Worker                                     const TextureInfo&,
154*c8dee2aaSAndroid Build Coastguard Worker                                     ResourceType,
155*c8dee2aaSAndroid Build Coastguard Worker                                     Shareable,
156*c8dee2aaSAndroid Build Coastguard Worker                                     GraphiteResourceKey*) const = 0;
157*c8dee2aaSAndroid Build Coastguard Worker 
resourceBindingRequirements()158*c8dee2aaSAndroid Build Coastguard Worker     const ResourceBindingRequirements& resourceBindingRequirements() const {
159*c8dee2aaSAndroid Build Coastguard Worker         return fResourceBindingReqs;
160*c8dee2aaSAndroid Build Coastguard Worker     }
161*c8dee2aaSAndroid Build Coastguard Worker 
162*c8dee2aaSAndroid Build Coastguard Worker     // Returns the required alignment in bytes for the offset into a uniform buffer when binding it
163*c8dee2aaSAndroid Build Coastguard Worker     // to a draw.
requiredUniformBufferAlignment()164*c8dee2aaSAndroid Build Coastguard Worker     size_t requiredUniformBufferAlignment() const { return fRequiredUniformBufferAlignment; }
165*c8dee2aaSAndroid Build Coastguard Worker 
166*c8dee2aaSAndroid Build Coastguard Worker     // Returns the required alignment in bytes for the offset into a storage buffer when binding it
167*c8dee2aaSAndroid Build Coastguard Worker     // to a draw.
requiredStorageBufferAlignment()168*c8dee2aaSAndroid Build Coastguard Worker     size_t requiredStorageBufferAlignment() const { return fRequiredStorageBufferAlignment; }
169*c8dee2aaSAndroid Build Coastguard Worker 
170*c8dee2aaSAndroid Build Coastguard Worker     // Returns the required alignment in bytes for the offset and size of copies involving a buffer.
requiredTransferBufferAlignment()171*c8dee2aaSAndroid Build Coastguard Worker     size_t requiredTransferBufferAlignment() const { return fRequiredTransferBufferAlignment; }
172*c8dee2aaSAndroid Build Coastguard Worker 
173*c8dee2aaSAndroid Build Coastguard Worker     // Returns the aligned rowBytes when transfering to or from a Texture
getAlignedTextureDataRowBytes(size_t rowBytes)174*c8dee2aaSAndroid Build Coastguard Worker     size_t getAlignedTextureDataRowBytes(size_t rowBytes) const {
175*c8dee2aaSAndroid Build Coastguard Worker         return SkAlignTo(rowBytes, fTextureDataRowBytesAlignment);
176*c8dee2aaSAndroid Build Coastguard Worker     }
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker     /**
179*c8dee2aaSAndroid Build Coastguard Worker      * Backends may have restrictions on what types of textures support Device::writePixels().
180*c8dee2aaSAndroid Build Coastguard Worker      * If this returns false then the caller should implement a fallback where a temporary texture
181*c8dee2aaSAndroid Build Coastguard Worker      * is created, pixels are written to it, and then that is copied or drawn into the the surface.
182*c8dee2aaSAndroid Build Coastguard Worker      */
183*c8dee2aaSAndroid Build Coastguard Worker     virtual bool supportsWritePixels(const TextureInfo& textureInfo) const = 0;
184*c8dee2aaSAndroid Build Coastguard Worker 
185*c8dee2aaSAndroid Build Coastguard Worker     /**
186*c8dee2aaSAndroid Build Coastguard Worker      * Backends may have restrictions on what types of textures support Device::readPixels().
187*c8dee2aaSAndroid Build Coastguard Worker      * If this returns false then the caller should implement a fallback where a temporary texture
188*c8dee2aaSAndroid Build Coastguard Worker      * is created, the original texture is copied or drawn into it, and then pixels read from
189*c8dee2aaSAndroid Build Coastguard Worker      * the temporary texture.
190*c8dee2aaSAndroid Build Coastguard Worker      */
191*c8dee2aaSAndroid Build Coastguard Worker     virtual bool supportsReadPixels(const TextureInfo& textureInfo) const = 0;
192*c8dee2aaSAndroid Build Coastguard Worker 
193*c8dee2aaSAndroid Build Coastguard Worker     /**
194*c8dee2aaSAndroid Build Coastguard Worker      * Given a dst pixel config and a src color type what color type must the caller coax the
195*c8dee2aaSAndroid Build Coastguard Worker      * the data into in order to use writePixels.
196*c8dee2aaSAndroid Build Coastguard Worker      *
197*c8dee2aaSAndroid Build Coastguard Worker      * We currently don't have an SkColorType for a 3 channel RGB format. Additionally the current
198*c8dee2aaSAndroid Build Coastguard Worker      * implementation of raster pipeline requires power of 2 channels, so it is not easy to add such
199*c8dee2aaSAndroid Build Coastguard Worker      * an SkColorType. Thus we need to check for data that is 3 channels using the isRGBFormat
200*c8dee2aaSAndroid Build Coastguard Worker      * return value and handle it manually
201*c8dee2aaSAndroid Build Coastguard Worker      */
202*c8dee2aaSAndroid Build Coastguard Worker     virtual std::pair<SkColorType, bool /*isRGB888Format*/> supportedWritePixelsColorType(
203*c8dee2aaSAndroid Build Coastguard Worker             SkColorType dstColorType,
204*c8dee2aaSAndroid Build Coastguard Worker             const TextureInfo& dstTextureInfo,
205*c8dee2aaSAndroid Build Coastguard Worker             SkColorType srcColorType) const = 0;
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     /**
208*c8dee2aaSAndroid Build Coastguard Worker      * Given a src surface's color type and its texture info as well as a color type the caller
209*c8dee2aaSAndroid Build Coastguard Worker      * would like read into, this provides a legal color type that the caller can use for
210*c8dee2aaSAndroid Build Coastguard Worker      * readPixels. The returned color type may differ from the passed dstColorType, in
211*c8dee2aaSAndroid Build Coastguard Worker      * which case the caller must convert the read pixel data (see GrConvertPixels). When converting
212*c8dee2aaSAndroid Build Coastguard Worker      * to dstColorType the swizzle in the returned struct should be applied. The caller must check
213*c8dee2aaSAndroid Build Coastguard Worker      * the returned color type for kUnknown.
214*c8dee2aaSAndroid Build Coastguard Worker      *
215*c8dee2aaSAndroid Build Coastguard Worker      * We currently don't have an SkColorType for a 3 channel RGB format. Additionally the current
216*c8dee2aaSAndroid Build Coastguard Worker      * implementation of raster pipeline requires power of 2 channels, so it is not easy to add such
217*c8dee2aaSAndroid Build Coastguard Worker      * an SkColorType. Thus we need to check for data that is 3 channels using the isRGBFormat
218*c8dee2aaSAndroid Build Coastguard Worker      * return value and handle it manually
219*c8dee2aaSAndroid Build Coastguard Worker      */
220*c8dee2aaSAndroid Build Coastguard Worker     virtual std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType(
221*c8dee2aaSAndroid Build Coastguard Worker             SkColorType srcColorType,
222*c8dee2aaSAndroid Build Coastguard Worker             const TextureInfo& srcTextureInfo,
223*c8dee2aaSAndroid Build Coastguard Worker             SkColorType dstColorType) const = 0;
224*c8dee2aaSAndroid Build Coastguard Worker 
225*c8dee2aaSAndroid Build Coastguard Worker     /**
226*c8dee2aaSAndroid Build Coastguard Worker      * Checks whether the passed color type is renderable. If so, the same color type is passed
227*c8dee2aaSAndroid Build Coastguard Worker      * back. If not, provides an alternative (perhaps lower bit depth and/or unorm instead of float)
228*c8dee2aaSAndroid Build Coastguard Worker      * color type that is supported or kUnknown if there no renderable fallback format.
229*c8dee2aaSAndroid Build Coastguard Worker      */
230*c8dee2aaSAndroid Build Coastguard Worker     SkColorType getRenderableColorType(SkColorType) const;
231*c8dee2aaSAndroid Build Coastguard Worker 
232*c8dee2aaSAndroid Build Coastguard Worker     // Determines the orientation of the NDC coordinates emitted by the vertex stage relative to
233*c8dee2aaSAndroid Build Coastguard Worker     // both Skia's presumed top-left Y-down system and the viewport coordinates (which are also
234*c8dee2aaSAndroid Build Coastguard Worker     // always top-left, Y-down for all supported backends).)
235*c8dee2aaSAndroid Build Coastguard Worker     //
236*c8dee2aaSAndroid Build Coastguard Worker     // If true is returned, then (-1,-1) in normalized device coords maps to the top-left of the
237*c8dee2aaSAndroid Build Coastguard Worker     // configured viewport and positive Y points down. This aligns with Skia's conventions.
238*c8dee2aaSAndroid Build Coastguard Worker     // If false is returned, then (-1,-1) in NDC maps to the bottom-left of the viewport and
239*c8dee2aaSAndroid Build Coastguard Worker     // positive Y points up (so NDC is flipped relative to sk_Position and the viewport coords).
240*c8dee2aaSAndroid Build Coastguard Worker     //
241*c8dee2aaSAndroid Build Coastguard Worker     // There is no backend difference in handling the X axis so it's assumed -1 maps to the left
242*c8dee2aaSAndroid Build Coastguard Worker     // edge and +1 maps to the right edge.
ndcYAxisPointsDown()243*c8dee2aaSAndroid Build Coastguard Worker     bool ndcYAxisPointsDown() const { return fNDCYAxisPointsDown; }
244*c8dee2aaSAndroid Build Coastguard Worker 
clampToBorderSupport()245*c8dee2aaSAndroid Build Coastguard Worker     bool clampToBorderSupport() const { return fClampToBorderSupport; }
246*c8dee2aaSAndroid Build Coastguard Worker 
protectedSupport()247*c8dee2aaSAndroid Build Coastguard Worker     bool protectedSupport() const { return fProtectedSupport; }
248*c8dee2aaSAndroid Build Coastguard Worker 
249*c8dee2aaSAndroid Build Coastguard Worker     // Supports BackendSemaphores
semaphoreSupport()250*c8dee2aaSAndroid Build Coastguard Worker     bool semaphoreSupport() const { return fSemaphoreSupport; }
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker     // If false then calling Context::submit with SyncToCpu::kYes is an error.
allowCpuSync()253*c8dee2aaSAndroid Build Coastguard Worker     bool allowCpuSync() const { return fAllowCpuSync; }
254*c8dee2aaSAndroid Build Coastguard Worker 
255*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether storage buffers are supported and to be preferred over uniform buffers.
storageBufferSupport()256*c8dee2aaSAndroid Build Coastguard Worker     bool storageBufferSupport() const { return fStorageBufferSupport; }
257*c8dee2aaSAndroid Build Coastguard Worker 
258*c8dee2aaSAndroid Build Coastguard Worker     // The gradient buffer is an unsized float array so it is only optimal memory-wise to use it if
259*c8dee2aaSAndroid Build Coastguard Worker     // the storage buffer memory layout is std430 or in metal, which is also the only supported
260*c8dee2aaSAndroid Build Coastguard Worker     // way the data is packed.
gradientBufferSupport()261*c8dee2aaSAndroid Build Coastguard Worker     bool gradientBufferSupport() const {
262*c8dee2aaSAndroid Build Coastguard Worker         return fStorageBufferSupport &&
263*c8dee2aaSAndroid Build Coastguard Worker                (fResourceBindingReqs.fStorageBufferLayout == Layout::kStd430 ||
264*c8dee2aaSAndroid Build Coastguard Worker                 fResourceBindingReqs.fStorageBufferLayout == Layout::kMetal);
265*c8dee2aaSAndroid Build Coastguard Worker     }
266*c8dee2aaSAndroid Build Coastguard Worker 
267*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether a draw buffer can be mapped.
drawBufferCanBeMapped()268*c8dee2aaSAndroid Build Coastguard Worker     bool drawBufferCanBeMapped() const { return fDrawBufferCanBeMapped; }
269*c8dee2aaSAndroid Build Coastguard Worker 
270*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
drawBufferCanBeMappedForReadback()271*c8dee2aaSAndroid Build Coastguard Worker     bool drawBufferCanBeMappedForReadback() const { return fDrawBufferCanBeMappedForReadback; }
272*c8dee2aaSAndroid Build Coastguard Worker #endif
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether using Buffer::asyncMap() must be used to map buffers. map() may only be
275*c8dee2aaSAndroid Build Coastguard Worker     // called after asyncMap() is called and will fail if the asynchronous map is not complete. This
276*c8dee2aaSAndroid Build Coastguard Worker     // excludes premapped buffers for which map() can be called freely until the first unmap() call.
bufferMapsAreAsync()277*c8dee2aaSAndroid Build Coastguard Worker     bool bufferMapsAreAsync() const { return fBufferMapsAreAsync; }
278*c8dee2aaSAndroid Build Coastguard Worker 
279*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether multisampled render to single sampled is supported.
msaaRenderToSingleSampledSupport()280*c8dee2aaSAndroid Build Coastguard Worker     bool msaaRenderToSingleSampledSupport() const { return fMSAARenderToSingleSampledSupport; }
281*c8dee2aaSAndroid Build Coastguard Worker 
282*c8dee2aaSAndroid Build Coastguard Worker     // Returns whether compute shaders are supported.
computeSupport()283*c8dee2aaSAndroid Build Coastguard Worker     bool computeSupport() const { return fComputeSupport; }
284*c8dee2aaSAndroid Build Coastguard Worker 
285*c8dee2aaSAndroid Build Coastguard Worker     /**
286*c8dee2aaSAndroid Build Coastguard Worker      * Returns true if the given backend supports importing AHardwareBuffers. This will only
287*c8dee2aaSAndroid Build Coastguard Worker      * ever be supported on Android devices with API level >= 26.
288*c8dee2aaSAndroid Build Coastguard Worker      */
supportsAHardwareBufferImages()289*c8dee2aaSAndroid Build Coastguard Worker     bool supportsAHardwareBufferImages() const { return fSupportsAHardwareBufferImages; }
290*c8dee2aaSAndroid Build Coastguard Worker 
291*c8dee2aaSAndroid Build Coastguard Worker     // Returns the skgpu::Swizzle to use when sampling or reading back from a texture with the
292*c8dee2aaSAndroid Build Coastguard Worker     // passed in SkColorType and TextureInfo.
293*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle getReadSwizzle(SkColorType, const TextureInfo&) const;
294*c8dee2aaSAndroid Build Coastguard Worker 
295*c8dee2aaSAndroid Build Coastguard Worker     // Returns the skgpu::Swizzle to use when writing colors to a surface with the passed in
296*c8dee2aaSAndroid Build Coastguard Worker     // SkColorType and TextureInfo.
297*c8dee2aaSAndroid Build Coastguard Worker     skgpu::Swizzle getWriteSwizzle(SkColorType, const TextureInfo&) const;
298*c8dee2aaSAndroid Build Coastguard Worker 
shaderErrorHandler()299*c8dee2aaSAndroid Build Coastguard Worker     skgpu::ShaderErrorHandler* shaderErrorHandler() const { return fShaderErrorHandler; }
300*c8dee2aaSAndroid Build Coastguard Worker 
301*c8dee2aaSAndroid Build Coastguard Worker     // Returns what method of dst read is required for a draw using the dst color.
302*c8dee2aaSAndroid Build Coastguard Worker     DstReadRequirement getDstReadRequirement() const;
303*c8dee2aaSAndroid Build Coastguard Worker 
minDistanceFieldFontSize()304*c8dee2aaSAndroid Build Coastguard Worker     float minDistanceFieldFontSize() const { return fMinDistanceFieldFontSize; }
glyphsAsPathsFontSize()305*c8dee2aaSAndroid Build Coastguard Worker     float glyphsAsPathsFontSize() const { return fGlyphsAsPathsFontSize; }
306*c8dee2aaSAndroid Build Coastguard Worker 
glyphCacheTextureMaximumBytes()307*c8dee2aaSAndroid Build Coastguard Worker     size_t glyphCacheTextureMaximumBytes() const { return fGlyphCacheTextureMaximumBytes; }
maxPathAtlasTextureSize()308*c8dee2aaSAndroid Build Coastguard Worker     int maxPathAtlasTextureSize() const { return fMaxPathAtlasTextureSize; }
309*c8dee2aaSAndroid Build Coastguard Worker 
allowMultipleAtlasTextures()310*c8dee2aaSAndroid Build Coastguard Worker     bool allowMultipleAtlasTextures() const { return fAllowMultipleAtlasTextures; }
supportBilerpFromGlyphAtlas()311*c8dee2aaSAndroid Build Coastguard Worker     bool supportBilerpFromGlyphAtlas() const { return fSupportBilerpFromGlyphAtlas; }
312*c8dee2aaSAndroid Build Coastguard Worker 
requireOrderedRecordings()313*c8dee2aaSAndroid Build Coastguard Worker     bool requireOrderedRecordings() const { return fRequireOrderedRecordings; }
314*c8dee2aaSAndroid Build Coastguard Worker 
315*c8dee2aaSAndroid Build Coastguard Worker     // When uploading to a full compressed texture do we need to pad the size out to a multiple of
316*c8dee2aaSAndroid Build Coastguard Worker     // the block width and height.
fullCompressedUploadSizeMustAlignToBlockDims()317*c8dee2aaSAndroid Build Coastguard Worker     bool fullCompressedUploadSizeMustAlignToBlockDims() const {
318*c8dee2aaSAndroid Build Coastguard Worker         return fFullCompressedUploadSizeMustAlignToBlockDims;
319*c8dee2aaSAndroid Build Coastguard Worker     }
320*c8dee2aaSAndroid Build Coastguard Worker 
321*c8dee2aaSAndroid Build Coastguard Worker     sktext::gpu::SubRunControl getSubRunControl(bool useSDFTForSmallText) const;
322*c8dee2aaSAndroid Build Coastguard Worker 
setBackendLabels()323*c8dee2aaSAndroid Build Coastguard Worker     bool setBackendLabels() const { return fSetBackendLabels; }
324*c8dee2aaSAndroid Build Coastguard Worker 
supportedGpuStats()325*c8dee2aaSAndroid Build Coastguard Worker     GpuStatsFlags supportedGpuStats() const { return fSupportedGpuStats; }
326*c8dee2aaSAndroid Build Coastguard Worker 
327*c8dee2aaSAndroid Build Coastguard Worker protected:
328*c8dee2aaSAndroid Build Coastguard Worker     Caps();
329*c8dee2aaSAndroid Build Coastguard Worker 
330*c8dee2aaSAndroid Build Coastguard Worker     // Subclasses must call this at the end of their init method in order to do final processing on
331*c8dee2aaSAndroid Build Coastguard Worker     // the caps.
332*c8dee2aaSAndroid Build Coastguard Worker     void finishInitialization(const ContextOptions&);
333*c8dee2aaSAndroid Build Coastguard Worker 
334*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
setDeviceName(std::string n)335*c8dee2aaSAndroid Build Coastguard Worker     void setDeviceName(std::string n) {
336*c8dee2aaSAndroid Build Coastguard Worker         fDeviceName = std::move(n);
337*c8dee2aaSAndroid Build Coastguard Worker     }
338*c8dee2aaSAndroid Build Coastguard Worker #endif
339*c8dee2aaSAndroid Build Coastguard Worker 
340*c8dee2aaSAndroid Build Coastguard Worker     // There are only a few possible valid sample counts (1, 2, 4, 8, 16). So we can key on those 5
341*c8dee2aaSAndroid Build Coastguard Worker     // options instead of the actual sample value.
SamplesToKey(uint32_t numSamples)342*c8dee2aaSAndroid Build Coastguard Worker     static inline uint32_t SamplesToKey(uint32_t numSamples) {
343*c8dee2aaSAndroid Build Coastguard Worker         switch (numSamples) {
344*c8dee2aaSAndroid Build Coastguard Worker             case 1:
345*c8dee2aaSAndroid Build Coastguard Worker                 return 0;
346*c8dee2aaSAndroid Build Coastguard Worker             case 2:
347*c8dee2aaSAndroid Build Coastguard Worker                 return 1;
348*c8dee2aaSAndroid Build Coastguard Worker             case 4:
349*c8dee2aaSAndroid Build Coastguard Worker                 return 2;
350*c8dee2aaSAndroid Build Coastguard Worker             case 8:
351*c8dee2aaSAndroid Build Coastguard Worker                 return 3;
352*c8dee2aaSAndroid Build Coastguard Worker             case 16:
353*c8dee2aaSAndroid Build Coastguard Worker                 return 4;
354*c8dee2aaSAndroid Build Coastguard Worker             default:
355*c8dee2aaSAndroid Build Coastguard Worker                 SkUNREACHABLE;
356*c8dee2aaSAndroid Build Coastguard Worker         }
357*c8dee2aaSAndroid Build Coastguard Worker     }
358*c8dee2aaSAndroid Build Coastguard Worker 
359*c8dee2aaSAndroid Build Coastguard Worker     // ColorTypeInfo for a specific format. Used in format tables.
360*c8dee2aaSAndroid Build Coastguard Worker     struct ColorTypeInfo {
361*c8dee2aaSAndroid Build Coastguard Worker         ColorTypeInfo() = default;
ColorTypeInfoColorTypeInfo362*c8dee2aaSAndroid Build Coastguard Worker         ColorTypeInfo(SkColorType ct, SkColorType transferCt, uint32_t flags,
363*c8dee2aaSAndroid Build Coastguard Worker                       skgpu::Swizzle readSwizzle, skgpu::Swizzle writeSwizzle)
364*c8dee2aaSAndroid Build Coastguard Worker                 : fColorType(ct)
365*c8dee2aaSAndroid Build Coastguard Worker                 , fTransferColorType(transferCt)
366*c8dee2aaSAndroid Build Coastguard Worker                 , fFlags(flags)
367*c8dee2aaSAndroid Build Coastguard Worker                 , fReadSwizzle(readSwizzle)
368*c8dee2aaSAndroid Build Coastguard Worker                 , fWriteSwizzle(writeSwizzle) {}
369*c8dee2aaSAndroid Build Coastguard Worker 
370*c8dee2aaSAndroid Build Coastguard Worker         SkColorType fColorType = kUnknown_SkColorType;
371*c8dee2aaSAndroid Build Coastguard Worker         SkColorType fTransferColorType = kUnknown_SkColorType;
372*c8dee2aaSAndroid Build Coastguard Worker         enum {
373*c8dee2aaSAndroid Build Coastguard Worker             kUploadData_Flag = 0x1,
374*c8dee2aaSAndroid Build Coastguard Worker             // Does Graphite itself support rendering to this colorType & format pair. Renderability
375*c8dee2aaSAndroid Build Coastguard Worker             // still additionally depends on if the format itself is renderable.
376*c8dee2aaSAndroid Build Coastguard Worker             kRenderable_Flag = 0x2,
377*c8dee2aaSAndroid Build Coastguard Worker         };
378*c8dee2aaSAndroid Build Coastguard Worker         uint32_t fFlags = 0;
379*c8dee2aaSAndroid Build Coastguard Worker 
380*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Swizzle fReadSwizzle;
381*c8dee2aaSAndroid Build Coastguard Worker         skgpu::Swizzle fWriteSwizzle;
382*c8dee2aaSAndroid Build Coastguard Worker     };
383*c8dee2aaSAndroid Build Coastguard Worker 
384*c8dee2aaSAndroid Build Coastguard Worker     int fMaxTextureSize = 0;
385*c8dee2aaSAndroid Build Coastguard Worker     int fDefaultMSAASamples = 4;
386*c8dee2aaSAndroid Build Coastguard Worker     size_t fRequiredUniformBufferAlignment = 0;
387*c8dee2aaSAndroid Build Coastguard Worker     size_t fRequiredStorageBufferAlignment = 0;
388*c8dee2aaSAndroid Build Coastguard Worker     size_t fRequiredTransferBufferAlignment = 0;
389*c8dee2aaSAndroid Build Coastguard Worker     size_t fTextureDataRowBytesAlignment = 1;
390*c8dee2aaSAndroid Build Coastguard Worker 
391*c8dee2aaSAndroid Build Coastguard Worker     std::unique_ptr<SkSL::ShaderCaps> fShaderCaps;
392*c8dee2aaSAndroid Build Coastguard Worker 
393*c8dee2aaSAndroid Build Coastguard Worker     bool fNDCYAxisPointsDown = false; // Most backends have NDC +Y pointing up
394*c8dee2aaSAndroid Build Coastguard Worker     bool fClampToBorderSupport = true;
395*c8dee2aaSAndroid Build Coastguard Worker     bool fProtectedSupport = false;
396*c8dee2aaSAndroid Build Coastguard Worker     bool fSemaphoreSupport = false;
397*c8dee2aaSAndroid Build Coastguard Worker     bool fAllowCpuSync = true;
398*c8dee2aaSAndroid Build Coastguard Worker     bool fStorageBufferSupport = false;
399*c8dee2aaSAndroid Build Coastguard Worker     bool fDrawBufferCanBeMapped = true;
400*c8dee2aaSAndroid Build Coastguard Worker     bool fBufferMapsAreAsync = false;
401*c8dee2aaSAndroid Build Coastguard Worker     bool fMSAARenderToSingleSampledSupport = false;
402*c8dee2aaSAndroid Build Coastguard Worker 
403*c8dee2aaSAndroid Build Coastguard Worker     bool fComputeSupport = false;
404*c8dee2aaSAndroid Build Coastguard Worker     bool fSupportsAHardwareBufferImages = false;
405*c8dee2aaSAndroid Build Coastguard Worker     bool fFullCompressedUploadSizeMustAlignToBlockDims = false;
406*c8dee2aaSAndroid Build Coastguard Worker 
407*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
408*c8dee2aaSAndroid Build Coastguard Worker     bool fDrawBufferCanBeMappedForReadback = true;
409*c8dee2aaSAndroid Build Coastguard Worker #endif
410*c8dee2aaSAndroid Build Coastguard Worker 
411*c8dee2aaSAndroid Build Coastguard Worker     ResourceBindingRequirements fResourceBindingReqs;
412*c8dee2aaSAndroid Build Coastguard Worker 
413*c8dee2aaSAndroid Build Coastguard Worker     GpuStatsFlags fSupportedGpuStats = GpuStatsFlags::kNone;
414*c8dee2aaSAndroid Build Coastguard Worker 
415*c8dee2aaSAndroid Build Coastguard Worker     //////////////////////////////////////////////////////////////////////////////////////////
416*c8dee2aaSAndroid Build Coastguard Worker     // Client-provided Caps
417*c8dee2aaSAndroid Build Coastguard Worker 
418*c8dee2aaSAndroid Build Coastguard Worker     /**
419*c8dee2aaSAndroid Build Coastguard Worker      * If present, use this object to report shader compilation failures. If not, report failures
420*c8dee2aaSAndroid Build Coastguard Worker      * via SkDebugf and assert.
421*c8dee2aaSAndroid Build Coastguard Worker      */
422*c8dee2aaSAndroid Build Coastguard Worker     ShaderErrorHandler* fShaderErrorHandler = nullptr;
423*c8dee2aaSAndroid Build Coastguard Worker 
424*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
425*c8dee2aaSAndroid Build Coastguard Worker     std::string fDeviceName;
426*c8dee2aaSAndroid Build Coastguard Worker     int fMaxTextureAtlasSize = 2048;
427*c8dee2aaSAndroid Build Coastguard Worker     PathRendererStrategy fRequestedPathRendererStrategy;
428*c8dee2aaSAndroid Build Coastguard Worker #endif
429*c8dee2aaSAndroid Build Coastguard Worker     size_t fGlyphCacheTextureMaximumBytes = 2048 * 1024 * 4;
430*c8dee2aaSAndroid Build Coastguard Worker 
431*c8dee2aaSAndroid Build Coastguard Worker     float fMinDistanceFieldFontSize = 18;
432*c8dee2aaSAndroid Build Coastguard Worker     float fGlyphsAsPathsFontSize = 324;
433*c8dee2aaSAndroid Build Coastguard Worker 
434*c8dee2aaSAndroid Build Coastguard Worker     int fMaxPathAtlasTextureSize = 8192;
435*c8dee2aaSAndroid Build Coastguard Worker 
436*c8dee2aaSAndroid Build Coastguard Worker     bool fAllowMultipleAtlasTextures = true;
437*c8dee2aaSAndroid Build Coastguard Worker     bool fSupportBilerpFromGlyphAtlas = false;
438*c8dee2aaSAndroid Build Coastguard Worker 
439*c8dee2aaSAndroid Build Coastguard Worker     // Set based on client options
440*c8dee2aaSAndroid Build Coastguard Worker     bool fRequireOrderedRecordings = false;
441*c8dee2aaSAndroid Build Coastguard Worker 
442*c8dee2aaSAndroid Build Coastguard Worker     bool fSetBackendLabels = false;
443*c8dee2aaSAndroid Build Coastguard Worker 
444*c8dee2aaSAndroid Build Coastguard Worker private:
445*c8dee2aaSAndroid Build Coastguard Worker     virtual bool onIsTexturable(const TextureInfo&) const = 0;
446*c8dee2aaSAndroid Build Coastguard Worker     virtual const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const = 0;
447*c8dee2aaSAndroid Build Coastguard Worker 
448*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SkCapabilities> fCapabilities;
449*c8dee2aaSAndroid Build Coastguard Worker };
450*c8dee2aaSAndroid Build Coastguard Worker 
451*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
452*c8dee2aaSAndroid Build Coastguard Worker 
453*c8dee2aaSAndroid Build Coastguard Worker #endif // skgpu_graphite_Caps_DEFINED
454