1 /* 2 * Copyright 2021 Google LLC 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef skgpu_graphite_Caps_DEFINED 9 #define skgpu_graphite_Caps_DEFINED 10 11 #include "include/core/SkImageInfo.h" 12 #include "include/core/SkRefCnt.h" 13 #include "include/private/base/SkAlign.h" 14 #include "src/core/SkEnumBitMask.h" 15 #include "src/gpu/ResourceKey.h" 16 #include "src/gpu/Swizzle.h" 17 #include "src/gpu/graphite/ResourceTypes.h" 18 #include "src/text/gpu/SDFTControl.h" 19 20 class SkCapabilities; 21 22 namespace SkSL { struct ShaderCaps; } 23 24 namespace skgpu { class ShaderErrorHandler; } 25 26 namespace skgpu::graphite { 27 28 enum class BufferType : int; 29 struct ContextOptions; 30 class ComputePipelineDesc; 31 class GraphicsPipelineDesc; 32 class GraphiteResourceKey; 33 struct RenderPassDesc; 34 class TextureInfo; 35 class TextureProxy; 36 37 struct ResourceBindingRequirements { 38 // The required data layout rules for the contents of a uniform buffer. 39 Layout fUniformBufferLayout = Layout::kInvalid; 40 41 // The required data layout rules for the contents of a storage buffer. 42 Layout fStorageBufferLayout = Layout::kInvalid; 43 44 // Whether combined texture-sampler types are supported. Backends that do not support 45 // combined image samplers (i.e. sampler2D) require a texture and sampler object to be bound 46 // separately and their binding indices explicitly specified in the shader text. 47 bool fSeparateTextureAndSamplerBinding = false; 48 49 // Whether buffer, texture, and sampler resource bindings use distinct index ranges. 50 bool fDistinctIndexRanges = false; 51 }; 52 53 class Caps { 54 public: 55 virtual ~Caps(); 56 shaderCaps()57 const SkSL::ShaderCaps* shaderCaps() const { return fShaderCaps.get(); } 58 59 sk_sp<SkCapabilities> capabilities() const; 60 61 virtual TextureInfo getDefaultSampledTextureInfo(SkColorType, 62 Mipmapped mipmapped, 63 Protected, 64 Renderable) const = 0; 65 66 virtual TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo, 67 Discardable discardable) const = 0; 68 69 virtual TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>, 70 uint32_t sampleCount, 71 Protected) const = 0; 72 73 virtual UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&, 74 const RenderPassDesc&) const = 0; 75 virtual UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const = 0; 76 77 bool areColorTypeAndTextureInfoCompatible(SkColorType, const TextureInfo&) const; 78 79 bool isTexturable(const TextureInfo&) const; 80 virtual bool isRenderable(const TextureInfo&) const = 0; 81 maxTextureSize()82 int maxTextureSize() const { return fMaxTextureSize; } 83 84 virtual void buildKeyForTexture(SkISize dimensions, 85 const TextureInfo&, 86 ResourceType, 87 Shareable, 88 GraphiteResourceKey*) const = 0; 89 resourceBindingRequirements()90 const ResourceBindingRequirements& resourceBindingRequirements() const { 91 return fResourceBindingReqs; 92 } 93 94 // Returns the required alignment in bytes for the offset into a uniform buffer when binding it 95 // to a draw. requiredUniformBufferAlignment()96 size_t requiredUniformBufferAlignment() const { return fRequiredUniformBufferAlignment; } 97 98 // Returns the required alignment in bytes for the offset into a storage buffer when binding it 99 // to a draw. requiredStorageBufferAlignment()100 size_t requiredStorageBufferAlignment() const { return fRequiredStorageBufferAlignment; } 101 102 // Returns the required alignment in bytes for the offset and size of copies involving a buffer. requiredTransferBufferAlignment()103 size_t requiredTransferBufferAlignment() const { return fRequiredTransferBufferAlignment; } 104 105 // Returns the aligned rowBytes when transfering to or from a Texture getAlignedTextureDataRowBytes(size_t rowBytes)106 size_t getAlignedTextureDataRowBytes(size_t rowBytes) const { 107 return SkAlignTo(rowBytes, fTextureDataRowBytesAlignment); 108 } 109 110 /** 111 * Backends may have restrictions on what types of textures support Device::writePixels(). 112 * If this returns false then the caller should implement a fallback where a temporary texture 113 * is created, pixels are written to it, and then that is copied or drawn into the the surface. 114 */ 115 virtual bool supportsWritePixels(const TextureInfo& textureInfo) const = 0; 116 117 /** 118 * Backends may have restrictions on what types of textures support Device::readPixels(). 119 * If this returns false then the caller should implement a fallback where a temporary texture 120 * is created, the original texture is copied or drawn into it, and then pixels read from 121 * the temporary texture. 122 */ 123 virtual bool supportsReadPixels(const TextureInfo& textureInfo) const = 0; 124 125 /** 126 * Given a dst pixel config and a src color type what color type must the caller coax the 127 * the data into in order to use writePixels. 128 */ 129 virtual SkColorType supportedWritePixelsColorType(SkColorType dstColorType, 130 const TextureInfo& dstTextureInfo, 131 SkColorType srcColorType) const = 0; 132 133 /** 134 * Given a src surface's color type and its texture info as well as a color type the caller 135 * would like read into, this provides a legal color type that the caller can use for 136 * readPixels. The returned color type may differ from the passed dstColorType, in 137 * which case the caller must convert the read pixel data (see GrConvertPixels). When converting 138 * to dstColorType the swizzle in the returned struct should be applied. The caller must check 139 * the returned color type for kUnknown. 140 */ 141 virtual SkColorType supportedReadPixelsColorType(SkColorType srcColorType, 142 const TextureInfo& srcTextureInfo, 143 SkColorType dstColorType) const = 0; 144 clampToBorderSupport()145 bool clampToBorderSupport() const { return fClampToBorderSupport; } 146 protectedSupport()147 bool protectedSupport() const { return fProtectedSupport; } 148 149 // Returns whether storage buffers are supported. storageBufferSupport()150 bool storageBufferSupport() const { return fStorageBufferSupport; } 151 152 // Returns whether storage buffers are preferred over uniform buffers, when both will yield 153 // correct results. storageBufferPreferred()154 bool storageBufferPreferred() const { return fStorageBufferPreferred; } 155 156 // Returns whether a draw buffer can be mapped. drawBufferCanBeMapped()157 bool drawBufferCanBeMapped() const { return fDrawBufferCanBeMapped; } 158 159 // Returns the skgpu::Swizzle to use when sampling or reading back from a texture with the 160 // passed in SkColorType and TextureInfo. 161 skgpu::Swizzle getReadSwizzle(SkColorType, const TextureInfo&) const; 162 163 // Returns the skgpu::Swizzle to use when writing colors to a surface with the passed in 164 // SkColorType and TextureInfo. 165 skgpu::Swizzle getWriteSwizzle(SkColorType, const TextureInfo&) const; 166 shaderErrorHandler()167 skgpu::ShaderErrorHandler* shaderErrorHandler() const { return fShaderErrorHandler; } 168 minDistanceFieldFontSize()169 float minDistanceFieldFontSize() const { return fMinDistanceFieldFontSize; } glyphsAsPathsFontSize()170 float glyphsAsPathsFontSize() const { return fGlyphsAsPathsFontSize; } 171 glyphCacheTextureMaximumBytes()172 size_t glyphCacheTextureMaximumBytes() const { return fGlyphCacheTextureMaximumBytes; } 173 allowMultipleGlyphCacheTextures()174 bool allowMultipleGlyphCacheTextures() const { return fAllowMultipleGlyphCacheTextures; } supportBilerpFromGlyphAtlas()175 bool supportBilerpFromGlyphAtlas() const { return fSupportBilerpFromGlyphAtlas; } 176 177 sktext::gpu::SDFTControl getSDFTControl(bool useSDFTForSmallText) const; 178 179 protected: 180 Caps(); 181 182 // Subclasses must call this at the end of their init method in order to do final processing on 183 // the caps. 184 void finishInitialization(const ContextOptions&); 185 186 // TODO: This value should be set by some context option. For now just making it 4. defaultMSAASamples()187 uint32_t defaultMSAASamples() const { return 4; } 188 189 // There are only a few possible valid sample counts (1, 2, 4, 8, 16). So we can key on those 5 190 // options instead of the actual sample value. SamplesToKey(uint32_t numSamples)191 static inline uint32_t SamplesToKey(uint32_t numSamples) { 192 switch (numSamples) { 193 case 1: 194 return 0; 195 case 2: 196 return 1; 197 case 4: 198 return 2; 199 case 8: 200 return 3; 201 case 16: 202 return 4; 203 default: 204 SkUNREACHABLE; 205 } 206 } 207 208 // ColorTypeInfo for a specific format. 209 // Used in format tables. 210 struct ColorTypeInfo { 211 SkColorType fColorType = kUnknown_SkColorType; 212 SkColorType fTransferColorType = kUnknown_SkColorType; 213 enum { 214 kUploadData_Flag = 0x1, 215 // Does Graphite itself support rendering to this colorType & format pair. Renderability 216 // still additionally depends on if the format itself is renderable. 217 kRenderable_Flag = 0x2, 218 }; 219 uint32_t fFlags = 0; 220 221 skgpu::Swizzle fReadSwizzle; 222 skgpu::Swizzle fWriteSwizzle; 223 }; 224 225 int fMaxTextureSize = 0; 226 size_t fRequiredUniformBufferAlignment = 0; 227 size_t fRequiredStorageBufferAlignment = 0; 228 size_t fRequiredTransferBufferAlignment = 0; 229 size_t fTextureDataRowBytesAlignment = 1; 230 231 std::unique_ptr<SkSL::ShaderCaps> fShaderCaps; 232 233 bool fClampToBorderSupport = true; 234 bool fProtectedSupport = false; 235 bool fStorageBufferSupport = false; 236 bool fStorageBufferPreferred = false; 237 bool fDrawBufferCanBeMapped = true; 238 239 ResourceBindingRequirements fResourceBindingReqs; 240 241 ////////////////////////////////////////////////////////////////////////////////////////// 242 // Client-provided Caps 243 244 /** 245 * If present, use this object to report shader compilation failures. If not, report failures 246 * via SkDebugf and assert. 247 */ 248 ShaderErrorHandler* fShaderErrorHandler = nullptr; 249 250 #if GRAPHITE_TEST_UTILS 251 int fMaxTextureAtlasSize = 2048; 252 #endif 253 size_t fGlyphCacheTextureMaximumBytes = 2048 * 1024 * 4; 254 255 float fMinDistanceFieldFontSize = 18; 256 float fGlyphsAsPathsFontSize = 324; 257 258 bool fAllowMultipleGlyphCacheTextures = true; 259 bool fSupportBilerpFromGlyphAtlas = false; 260 261 private: 262 virtual bool onIsTexturable(const TextureInfo&) const = 0; 263 virtual const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const = 0; 264 265 sk_sp<SkCapabilities> fCapabilities; 266 }; 267 268 } // namespace skgpu::graphite 269 270 #endif // skgpu_graphite_Caps_DEFINED 271