1 /* 2 * Copyright 2022 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_DawnCaps_DEFINED 9 #define skgpu_graphite_DawnCaps_DEFINED 10 11 #include "src/gpu/graphite/Caps.h" 12 13 #include <array> 14 15 #include "webgpu/webgpu_cpp.h" // NO_G3_REWRITE 16 17 namespace skgpu::graphite { 18 struct ContextOptions; 19 20 struct DawnBackendContext; 21 22 class DawnCaps final : public Caps { 23 public: 24 DawnCaps(const DawnBackendContext&, const ContextOptions&); 25 ~DawnCaps() override; 26 useAsyncPipelineCreation()27 bool useAsyncPipelineCreation() const { return fUseAsyncPipelineCreation; } allowScopedErrorChecks()28 bool allowScopedErrorChecks() const { return fAllowScopedErrorChecks; } 29 30 // If this has no value then loading the resolve texture via a LoadOp is not supported. resolveTextureLoadOp()31 std::optional<wgpu::LoadOp> resolveTextureLoadOp() const { 32 return fSupportedResolveTextureLoadOp; 33 } supportsPartialLoadResolve()34 bool supportsPartialLoadResolve() const { return fSupportsPartialLoadResolve; } 35 36 TextureInfo getDefaultSampledTextureInfo(SkColorType, 37 Mipmapped mipmapped, 38 Protected, 39 Renderable) const override; 40 TextureInfo getTextureInfoForSampledCopy(const TextureInfo& textureInfo, 41 Mipmapped mipmapped) const override; 42 TextureInfo getDefaultCompressedTextureInfo(SkTextureCompressionType, 43 Mipmapped mipmapped, 44 Protected) const override; 45 TextureInfo getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo, 46 Discardable discardable) const override; 47 TextureInfo getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags>, 48 uint32_t sampleCount, 49 Protected, 50 Discardable discardable) const override; 51 TextureInfo getDefaultStorageTextureInfo(SkColorType) const override; 52 SkISize getDepthAttachmentDimensions(const TextureInfo&, 53 const SkISize colorAttachmentDimensions) const override; 54 UniqueKey makeGraphicsPipelineKey(const GraphicsPipelineDesc&, 55 const RenderPassDesc&) const override; 56 bool extractGraphicsDescs(const UniqueKey&, 57 GraphicsPipelineDesc*, 58 RenderPassDesc*, 59 const RendererProvider*) const override; 60 UniqueKey makeComputePipelineKey(const ComputePipelineDesc&) const override; 61 ImmutableSamplerInfo getImmutableSamplerInfo(const TextureInfo&) const override; 62 bool isRenderable(const TextureInfo&) const override; 63 bool isStorage(const TextureInfo&) const override; 64 loadOpAffectsMSAAPipelines()65 bool loadOpAffectsMSAAPipelines() const override { 66 return fSupportedResolveTextureLoadOp.has_value(); 67 } 68 69 bool serializeTextureInfo(const TextureInfo&, SkWStream*) const override; 70 bool deserializeTextureInfo(SkStream*, TextureInfo* out) const override; 71 72 void buildKeyForTexture(SkISize dimensions, 73 const TextureInfo&, 74 ResourceType, 75 GraphiteResourceKey*) const override; 76 // Compute render pass desc's key as 32 bits key. The key has room for additional flag which can 77 // optionally be provided. 78 uint32_t getRenderPassDescKeyForPipeline(const RenderPassDesc&, 79 bool additionalFlag = false) const; 80 supportsCommandBufferTimestamps()81 bool supportsCommandBufferTimestamps() const { return fSupportsCommandBufferTimestamps; } 82 83 // Whether we should emulate load/resolve with separate render passes. 84 // TODO(b/399640773): This is currently used until Dawn supports true partial resolve feature 85 // that can resolve a MSAA texture to a resolve texture with different size. emulateLoadStoreResolve()86 bool emulateLoadStoreResolve() const { return fEmulateLoadStoreResolve; } 87 88 // Check whether the texture is texturable, ignoring its sample count. This is needed 89 // instead of isTextureable() because graphite frontend treats multisampled textures as 90 // non-textureable. 91 bool isTexturableIgnoreSampleCount(const TextureInfo& info) const; 92 93 private: 94 const ColorTypeInfo* getColorTypeInfo(SkColorType, const TextureInfo&) const override; 95 bool onIsTexturable(const TextureInfo&) const override; 96 bool supportsWritePixels(const TextureInfo& textureInfo) const override; 97 bool supportsReadPixels(const TextureInfo& textureInfo) const override; 98 std::pair<SkColorType, bool /*isRGBFormat*/> supportedWritePixelsColorType( 99 SkColorType dstColorType, 100 const TextureInfo& dstTextureInfo, 101 SkColorType srcColorType) const override; 102 std::pair<SkColorType, bool /*isRGBFormat*/> supportedReadPixelsColorType( 103 SkColorType srcColorType, 104 const TextureInfo& srcTextureInfo, 105 SkColorType dstColorType) const override; 106 107 void initCaps(const DawnBackendContext& backendContext, const ContextOptions& options); 108 void initShaderCaps(const wgpu::Device& device); 109 void initFormatTable(const wgpu::Device& device); 110 getFormatFromColorType(SkColorType colorType)111 wgpu::TextureFormat getFormatFromColorType(SkColorType colorType) const { 112 int idx = static_cast<int>(colorType); 113 return fColorTypeToFormatTable[idx]; 114 } 115 116 uint32_t maxRenderTargetSampleCount(wgpu::TextureFormat format) const; 117 using Caps::isTexturable; 118 bool isTexturable(wgpu::TextureFormat format) const; 119 bool isRenderable(wgpu::TextureFormat format, uint32_t numSamples) const; 120 121 struct FormatInfo { colorTypeFlagsFormatInfo122 uint32_t colorTypeFlags(SkColorType colorType) const { 123 for (int i = 0; i < fColorTypeInfoCount; ++i) { 124 if (fColorTypeInfos[i].fColorType == colorType) { 125 return fColorTypeInfos[i].fFlags; 126 } 127 } 128 return 0; 129 } 130 131 enum { 132 kTexturable_Flag = 0x01, 133 kRenderable_Flag = 0x02, // Color attachment and blendable 134 kMSAA_Flag = 0x04, 135 kResolve_Flag = 0x08, 136 kStorage_Flag = 0x10, 137 }; 138 static const uint16_t kAllFlags = 139 kTexturable_Flag | kRenderable_Flag | kMSAA_Flag | kResolve_Flag | kStorage_Flag; 140 141 uint16_t fFlags = 0; 142 143 std::unique_ptr<ColorTypeInfo[]> fColorTypeInfos; 144 int fColorTypeInfoCount = 0; 145 }; 146 // Size here must be at least the size of kFormats in DawnCaps.cpp. 147 static constexpr size_t kFormatCount = 17; 148 std::array<FormatInfo, kFormatCount> fFormatTable; 149 150 static size_t GetFormatIndex(wgpu::TextureFormat format); getFormatInfo(wgpu::TextureFormat format)151 const FormatInfo& getFormatInfo(wgpu::TextureFormat format) const { 152 size_t index = GetFormatIndex(format); 153 return fFormatTable[index]; 154 } 155 156 wgpu::TextureFormat fColorTypeToFormatTable[kSkColorTypeCnt]; 157 void setColorType(SkColorType, std::initializer_list<wgpu::TextureFormat> formats); 158 159 // When supported, this value will hold the TransientAttachment usage symbol that is only 160 // defined in Dawn native builds and not EMSCRIPTEN but this avoids having to #define guard it. 161 wgpu::TextureUsage fSupportedTransientAttachmentUsage = wgpu::TextureUsage::None; 162 // When supported this holds the ExpandResolveTexture load op, otherwise holds no value. 163 std::optional<wgpu::LoadOp> fSupportedResolveTextureLoadOp; 164 // When 'fSupportedResolveTextureLoadOp' is supported, it by default performs full size expand 165 // and resolve. With this feature, we can do that partially according to the actual damage 166 // region. 167 bool fSupportsPartialLoadResolve = false; 168 169 bool fEmulateLoadStoreResolve = false; 170 171 bool fUseAsyncPipelineCreation = true; 172 bool fAllowScopedErrorChecks = true; 173 174 bool fSupportsCommandBufferTimestamps = false; 175 }; 176 177 } // namespace skgpu::graphite 178 179 #endif // skgpu_graphite_DawnCaps_DEFINED 180