xref: /aosp_15_r20/external/skia/src/gpu/graphite/dawn/DawnCaps.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2022 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 #include "src/gpu/graphite/dawn/DawnCaps.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include <algorithm>
11*c8dee2aaSAndroid Build Coastguard Worker #include <string>
12*c8dee2aaSAndroid Build Coastguard Worker 
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTextureCompressionType.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/ContextOptions.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/TextureInfo.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/gpu/graphite/dawn/DawnBackendContext.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/SwizzlePriv.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ComputePipelineDesc.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GraphicsPipelineDesc.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/GraphiteResourceKey.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RenderPassDesc.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/RendererProvider.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/ResourceTypes.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/UniformManager.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/dawn/DawnGraphicsPipeline.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/dawn/DawnGraphiteTypesPriv.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/dawn/DawnGraphiteUtilsPriv.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/graphite/dawn/DawnUtilsPriv.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "src/sksl/SkSLUtil.h"
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker #if defined(__EMSCRIPTEN__)
32*c8dee2aaSAndroid Build Coastguard Worker #include <emscripten/version.h>
33*c8dee2aaSAndroid Build Coastguard Worker #endif
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker namespace {
36*c8dee2aaSAndroid Build Coastguard Worker 
get_pipeline_domain()37*c8dee2aaSAndroid Build Coastguard Worker skgpu::UniqueKey::Domain get_pipeline_domain() {
38*c8dee2aaSAndroid Build Coastguard Worker     static const skgpu::UniqueKey::Domain kDawnGraphicsPipelineDomain =
39*c8dee2aaSAndroid Build Coastguard Worker             skgpu::UniqueKey::GenerateDomain();
40*c8dee2aaSAndroid Build Coastguard Worker 
41*c8dee2aaSAndroid Build Coastguard Worker     return kDawnGraphicsPipelineDomain;
42*c8dee2aaSAndroid Build Coastguard Worker }
43*c8dee2aaSAndroid Build Coastguard Worker 
44*c8dee2aaSAndroid Build Coastguard Worker // These are all the valid wgpu::TextureFormat that we currently support in Skia.
45*c8dee2aaSAndroid Build Coastguard Worker // They are roughly ordered from most frequently used to least to improve lookup times in arrays.
46*c8dee2aaSAndroid Build Coastguard Worker static constexpr wgpu::TextureFormat kFormats[] = {
47*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RGBA8Unorm,
48*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::R8Unorm,
49*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
50*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::R16Unorm,
51*c8dee2aaSAndroid Build Coastguard Worker #endif
52*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::BGRA8Unorm,
53*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RGBA16Float,
54*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::R16Float,
55*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RG8Unorm,
56*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
57*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RG16Unorm,
58*c8dee2aaSAndroid Build Coastguard Worker #endif
59*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RGB10A2Unorm,
60*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::RG16Float,
61*c8dee2aaSAndroid Build Coastguard Worker 
62*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::Stencil8,
63*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::Depth16Unorm,
64*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::Depth32Float,
65*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::Depth24PlusStencil8,
66*c8dee2aaSAndroid Build Coastguard Worker 
67*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::BC1RGBAUnorm,
68*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::ETC2RGB8Unorm,
69*c8dee2aaSAndroid Build Coastguard Worker 
70*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
71*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat::External,
72*c8dee2aaSAndroid Build Coastguard Worker #endif
73*c8dee2aaSAndroid Build Coastguard Worker };
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
IsMultiplanarFormat(wgpu::TextureFormat format)76*c8dee2aaSAndroid Build Coastguard Worker bool IsMultiplanarFormat(wgpu::TextureFormat format) {
77*c8dee2aaSAndroid Build Coastguard Worker     switch (format) {
78*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R8BG8Biplanar420Unorm:
79*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm:
80*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R8BG8A8Triplanar420Unorm:
81*c8dee2aaSAndroid Build Coastguard Worker             return true;
82*c8dee2aaSAndroid Build Coastguard Worker         default:
83*c8dee2aaSAndroid Build Coastguard Worker             return false;
84*c8dee2aaSAndroid Build Coastguard Worker     }
85*c8dee2aaSAndroid Build Coastguard Worker }
86*c8dee2aaSAndroid Build Coastguard Worker #endif
87*c8dee2aaSAndroid Build Coastguard Worker }  // anonymous namespace
88*c8dee2aaSAndroid Build Coastguard Worker 
89*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu::graphite {
90*c8dee2aaSAndroid Build Coastguard Worker 
DawnCaps(const DawnBackendContext & backendContext,const ContextOptions & options)91*c8dee2aaSAndroid Build Coastguard Worker DawnCaps::DawnCaps(const DawnBackendContext& backendContext, const ContextOptions& options)
92*c8dee2aaSAndroid Build Coastguard Worker     : Caps() {
93*c8dee2aaSAndroid Build Coastguard Worker     this->initCaps(backendContext, options);
94*c8dee2aaSAndroid Build Coastguard Worker     this->initShaderCaps(backendContext.fDevice);
95*c8dee2aaSAndroid Build Coastguard Worker     this->initFormatTable(backendContext.fDevice);
96*c8dee2aaSAndroid Build Coastguard Worker     this->finishInitialization(options);
97*c8dee2aaSAndroid Build Coastguard Worker }
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker DawnCaps::~DawnCaps() = default;
100*c8dee2aaSAndroid Build Coastguard Worker 
channelMask(const TextureInfo & info) const101*c8dee2aaSAndroid Build Coastguard Worker uint32_t DawnCaps::channelMask(const TextureInfo& info) const {
102*c8dee2aaSAndroid Build Coastguard Worker     return DawnFormatChannels(TextureInfos::GetDawnTextureSpec(info).getViewFormat());
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker 
onIsTexturable(const TextureInfo & info) const105*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::onIsTexturable(const TextureInfo& info) const {
106*c8dee2aaSAndroid Build Coastguard Worker     if (!info.isValid()) {
107*c8dee2aaSAndroid Build Coastguard Worker         return false;
108*c8dee2aaSAndroid Build Coastguard Worker     }
109*c8dee2aaSAndroid Build Coastguard Worker 
110*c8dee2aaSAndroid Build Coastguard Worker     const DawnTextureSpec spec = TextureInfos::GetDawnTextureSpec(info);
111*c8dee2aaSAndroid Build Coastguard Worker 
112*c8dee2aaSAndroid Build Coastguard Worker     if (!(spec.fUsage & wgpu::TextureUsage::TextureBinding)) {
113*c8dee2aaSAndroid Build Coastguard Worker         return false;
114*c8dee2aaSAndroid Build Coastguard Worker     }
115*c8dee2aaSAndroid Build Coastguard Worker 
116*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
117*c8dee2aaSAndroid Build Coastguard Worker     switch (spec.fFormat) {
118*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R8BG8Biplanar420Unorm: {
119*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane0Only &&
120*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::R8Unorm) {
121*c8dee2aaSAndroid Build Coastguard Worker                 return false;
122*c8dee2aaSAndroid Build Coastguard Worker             }
123*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane1Only &&
124*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::RG8Unorm) {
125*c8dee2aaSAndroid Build Coastguard Worker                 return false;
126*c8dee2aaSAndroid Build Coastguard Worker             }
127*c8dee2aaSAndroid Build Coastguard Worker             break;
128*c8dee2aaSAndroid Build Coastguard Worker         }
129*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R10X6BG10X6Biplanar420Unorm: {
130*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane0Only &&
131*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::R16Unorm) {
132*c8dee2aaSAndroid Build Coastguard Worker                 return false;
133*c8dee2aaSAndroid Build Coastguard Worker             }
134*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane1Only &&
135*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::RG16Unorm) {
136*c8dee2aaSAndroid Build Coastguard Worker                 return false;
137*c8dee2aaSAndroid Build Coastguard Worker             }
138*c8dee2aaSAndroid Build Coastguard Worker             break;
139*c8dee2aaSAndroid Build Coastguard Worker         }
140*c8dee2aaSAndroid Build Coastguard Worker         case wgpu::TextureFormat::R8BG8A8Triplanar420Unorm: {
141*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane0Only &&
142*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::R8Unorm) {
143*c8dee2aaSAndroid Build Coastguard Worker                 return false;
144*c8dee2aaSAndroid Build Coastguard Worker             }
145*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane1Only &&
146*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::RG8Unorm) {
147*c8dee2aaSAndroid Build Coastguard Worker                 return false;
148*c8dee2aaSAndroid Build Coastguard Worker             }
149*c8dee2aaSAndroid Build Coastguard Worker             if (spec.fAspect == wgpu::TextureAspect::Plane2Only &&
150*c8dee2aaSAndroid Build Coastguard Worker                 spec.getViewFormat() != wgpu::TextureFormat::R8Unorm) {
151*c8dee2aaSAndroid Build Coastguard Worker                 return false;
152*c8dee2aaSAndroid Build Coastguard Worker             }
153*c8dee2aaSAndroid Build Coastguard Worker             break;
154*c8dee2aaSAndroid Build Coastguard Worker         }
155*c8dee2aaSAndroid Build Coastguard Worker         default:
156*c8dee2aaSAndroid Build Coastguard Worker             break;
157*c8dee2aaSAndroid Build Coastguard Worker     }
158*c8dee2aaSAndroid Build Coastguard Worker #endif
159*c8dee2aaSAndroid Build Coastguard Worker 
160*c8dee2aaSAndroid Build Coastguard Worker     return this->isTexturable(spec.getViewFormat());
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker 
isTexturable(wgpu::TextureFormat format) const163*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::isTexturable(wgpu::TextureFormat format) const {
164*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& formatInfo = this->getFormatInfo(format);
165*c8dee2aaSAndroid Build Coastguard Worker     return SkToBool(FormatInfo::kTexturable_Flag & formatInfo.fFlags);
166*c8dee2aaSAndroid Build Coastguard Worker }
167*c8dee2aaSAndroid Build Coastguard Worker 
isRenderable(const TextureInfo & info) const168*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::isRenderable(const TextureInfo& info) const {
169*c8dee2aaSAndroid Build Coastguard Worker     const DawnTextureSpec spec = TextureInfos::GetDawnTextureSpec(info);
170*c8dee2aaSAndroid Build Coastguard Worker 
171*c8dee2aaSAndroid Build Coastguard Worker     return info.isValid() && (spec.fUsage & wgpu::TextureUsage::RenderAttachment) &&
172*c8dee2aaSAndroid Build Coastguard Worker            this->isRenderable(spec.getViewFormat(), info.numSamples());
173*c8dee2aaSAndroid Build Coastguard Worker }
174*c8dee2aaSAndroid Build Coastguard Worker 
isStorage(const TextureInfo & info) const175*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::isStorage(const TextureInfo& info) const {
176*c8dee2aaSAndroid Build Coastguard Worker     if (!info.isValid()) {
177*c8dee2aaSAndroid Build Coastguard Worker         return false;
178*c8dee2aaSAndroid Build Coastguard Worker     }
179*c8dee2aaSAndroid Build Coastguard Worker     const DawnTextureSpec spec = TextureInfos::GetDawnTextureSpec(info);
180*c8dee2aaSAndroid Build Coastguard Worker     if (!(spec.fUsage & wgpu::TextureUsage::StorageBinding)) {
181*c8dee2aaSAndroid Build Coastguard Worker         return false;
182*c8dee2aaSAndroid Build Coastguard Worker     }
183*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& formatInfo = this->getFormatInfo(spec.getViewFormat());
184*c8dee2aaSAndroid Build Coastguard Worker     return info.numSamples() == 1 && SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags);
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker 
maxRenderTargetSampleCount(wgpu::TextureFormat format) const187*c8dee2aaSAndroid Build Coastguard Worker uint32_t DawnCaps::maxRenderTargetSampleCount(wgpu::TextureFormat format) const {
188*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& formatInfo = this->getFormatInfo(format);
189*c8dee2aaSAndroid Build Coastguard Worker     if (!SkToBool(formatInfo.fFlags & FormatInfo::kRenderable_Flag)) {
190*c8dee2aaSAndroid Build Coastguard Worker         return 0;
191*c8dee2aaSAndroid Build Coastguard Worker     }
192*c8dee2aaSAndroid Build Coastguard Worker     if (SkToBool(formatInfo.fFlags & FormatInfo::kMSAA_Flag)) {
193*c8dee2aaSAndroid Build Coastguard Worker         return 8;
194*c8dee2aaSAndroid Build Coastguard Worker     } else {
195*c8dee2aaSAndroid Build Coastguard Worker         return 1;
196*c8dee2aaSAndroid Build Coastguard Worker     }
197*c8dee2aaSAndroid Build Coastguard Worker }
198*c8dee2aaSAndroid Build Coastguard Worker 
isRenderable(wgpu::TextureFormat format,uint32_t sampleCount) const199*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::isRenderable(wgpu::TextureFormat format, uint32_t sampleCount) const {
200*c8dee2aaSAndroid Build Coastguard Worker     return sampleCount <= this->maxRenderTargetSampleCount(format);
201*c8dee2aaSAndroid Build Coastguard Worker }
202*c8dee2aaSAndroid Build Coastguard Worker 
getDefaultSampledTextureInfo(SkColorType colorType,Mipmapped mipmapped,Protected,Renderable renderable) const203*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getDefaultSampledTextureInfo(SkColorType colorType,
204*c8dee2aaSAndroid Build Coastguard Worker                                                    Mipmapped mipmapped,
205*c8dee2aaSAndroid Build Coastguard Worker                                                    Protected,
206*c8dee2aaSAndroid Build Coastguard Worker                                                    Renderable renderable) const {
207*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureUsage usage = wgpu::TextureUsage::TextureBinding |
208*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::CopyDst |
209*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::CopySrc;
210*c8dee2aaSAndroid Build Coastguard Worker     if (renderable == Renderable::kYes) {
211*c8dee2aaSAndroid Build Coastguard Worker         usage |= wgpu::TextureUsage::RenderAttachment;
212*c8dee2aaSAndroid Build Coastguard Worker     }
213*c8dee2aaSAndroid Build Coastguard Worker 
214*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureFormat format = this->getFormatFromColorType(colorType);
215*c8dee2aaSAndroid Build Coastguard Worker     if (format == wgpu::TextureFormat::Undefined) {
216*c8dee2aaSAndroid Build Coastguard Worker         return {};
217*c8dee2aaSAndroid Build Coastguard Worker     }
218*c8dee2aaSAndroid Build Coastguard Worker 
219*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
220*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = 1;
221*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped = mipmapped;
222*c8dee2aaSAndroid Build Coastguard Worker     info.fFormat = format;
223*c8dee2aaSAndroid Build Coastguard Worker     info.fViewFormat = format;
224*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage = usage;
225*c8dee2aaSAndroid Build Coastguard Worker 
226*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
227*c8dee2aaSAndroid Build Coastguard Worker }
228*c8dee2aaSAndroid Build Coastguard Worker 
getTextureInfoForSampledCopy(const TextureInfo & textureInfo,Mipmapped mipmapped) const229*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getTextureInfoForSampledCopy(const TextureInfo& textureInfo,
230*c8dee2aaSAndroid Build Coastguard Worker                                                    Mipmapped mipmapped) const {
231*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
232*c8dee2aaSAndroid Build Coastguard Worker     if (!TextureInfos::GetDawnTextureInfo(textureInfo, &info)) {
233*c8dee2aaSAndroid Build Coastguard Worker         return {};
234*c8dee2aaSAndroid Build Coastguard Worker     }
235*c8dee2aaSAndroid Build Coastguard Worker 
236*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = 1;
237*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped = mipmapped;
238*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::CopyDst |
239*c8dee2aaSAndroid Build Coastguard Worker                   wgpu::TextureUsage::CopySrc;
240*c8dee2aaSAndroid Build Coastguard Worker 
241*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
242*c8dee2aaSAndroid Build Coastguard Worker }
243*c8dee2aaSAndroid Build Coastguard Worker 
244*c8dee2aaSAndroid Build Coastguard Worker namespace {
format_from_compression(SkTextureCompressionType compression)245*c8dee2aaSAndroid Build Coastguard Worker wgpu::TextureFormat format_from_compression(SkTextureCompressionType compression) {
246*c8dee2aaSAndroid Build Coastguard Worker     switch (compression) {
247*c8dee2aaSAndroid Build Coastguard Worker         case SkTextureCompressionType::kETC2_RGB8_UNORM:
248*c8dee2aaSAndroid Build Coastguard Worker             return wgpu::TextureFormat::ETC2RGB8Unorm;
249*c8dee2aaSAndroid Build Coastguard Worker         case SkTextureCompressionType::kBC1_RGBA8_UNORM:
250*c8dee2aaSAndroid Build Coastguard Worker             return wgpu::TextureFormat::BC1RGBAUnorm;
251*c8dee2aaSAndroid Build Coastguard Worker         default:
252*c8dee2aaSAndroid Build Coastguard Worker             return wgpu::TextureFormat::Undefined;
253*c8dee2aaSAndroid Build Coastguard Worker     }
254*c8dee2aaSAndroid Build Coastguard Worker }
255*c8dee2aaSAndroid Build Coastguard Worker }
256*c8dee2aaSAndroid Build Coastguard Worker 
getDefaultCompressedTextureInfo(SkTextureCompressionType compression,Mipmapped mipmapped,Protected) const257*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getDefaultCompressedTextureInfo(SkTextureCompressionType compression,
258*c8dee2aaSAndroid Build Coastguard Worker                                                       Mipmapped mipmapped,
259*c8dee2aaSAndroid Build Coastguard Worker                                                       Protected) const {
260*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureUsage usage = wgpu::TextureUsage::TextureBinding |
261*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::CopyDst |
262*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::CopySrc;
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureFormat format = format_from_compression(compression);
265*c8dee2aaSAndroid Build Coastguard Worker     if (format == wgpu::TextureFormat::Undefined) {
266*c8dee2aaSAndroid Build Coastguard Worker         return {};
267*c8dee2aaSAndroid Build Coastguard Worker     }
268*c8dee2aaSAndroid Build Coastguard Worker 
269*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
270*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = 1;
271*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped = mipmapped;
272*c8dee2aaSAndroid Build Coastguard Worker     info.fFormat = format;
273*c8dee2aaSAndroid Build Coastguard Worker     info.fViewFormat = format;
274*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage = usage;
275*c8dee2aaSAndroid Build Coastguard Worker 
276*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
277*c8dee2aaSAndroid Build Coastguard Worker }
278*c8dee2aaSAndroid Build Coastguard Worker 
getDefaultMSAATextureInfo(const TextureInfo & singleSampledInfo,Discardable discardable) const279*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getDefaultMSAATextureInfo(const TextureInfo& singleSampledInfo,
280*c8dee2aaSAndroid Build Coastguard Worker                                                 Discardable discardable) const {
281*c8dee2aaSAndroid Build Coastguard Worker     if (fDefaultMSAASamples <= 1) {
282*c8dee2aaSAndroid Build Coastguard Worker         return {};
283*c8dee2aaSAndroid Build Coastguard Worker     }
284*c8dee2aaSAndroid Build Coastguard Worker     const DawnTextureSpec singleSpec = TextureInfos::GetDawnTextureSpec(singleSampledInfo);
285*c8dee2aaSAndroid Build Coastguard Worker 
286*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
287*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = fDefaultMSAASamples;
288*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped   = Mipmapped::kNo;
289*c8dee2aaSAndroid Build Coastguard Worker     info.fFormat      = singleSpec.fFormat;
290*c8dee2aaSAndroid Build Coastguard Worker     info.fViewFormat  = singleSpec.fFormat;
291*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage       = wgpu::TextureUsage::RenderAttachment;
292*c8dee2aaSAndroid Build Coastguard Worker 
293*c8dee2aaSAndroid Build Coastguard Worker     if (fSupportedTransientAttachmentUsage != wgpu::TextureUsage::None &&
294*c8dee2aaSAndroid Build Coastguard Worker         discardable == Discardable::kYes) {
295*c8dee2aaSAndroid Build Coastguard Worker         info.fUsage |= fSupportedTransientAttachmentUsage;
296*c8dee2aaSAndroid Build Coastguard Worker     }
297*c8dee2aaSAndroid Build Coastguard Worker 
298*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
299*c8dee2aaSAndroid Build Coastguard Worker }
300*c8dee2aaSAndroid Build Coastguard Worker 
getDefaultDepthStencilTextureInfo(SkEnumBitMask<DepthStencilFlags> depthStencilType,uint32_t sampleCount,Protected) const301*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getDefaultDepthStencilTextureInfo(
302*c8dee2aaSAndroid Build Coastguard Worker     SkEnumBitMask<DepthStencilFlags> depthStencilType,
303*c8dee2aaSAndroid Build Coastguard Worker     uint32_t sampleCount,
304*c8dee2aaSAndroid Build Coastguard Worker     Protected) const {
305*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
306*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = sampleCount;
307*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped   = Mipmapped::kNo;
308*c8dee2aaSAndroid Build Coastguard Worker     info.fFormat      = DawnDepthStencilFlagsToFormat(depthStencilType);
309*c8dee2aaSAndroid Build Coastguard Worker     info.fViewFormat  = info.fFormat;
310*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage       = wgpu::TextureUsage::RenderAttachment;
311*c8dee2aaSAndroid Build Coastguard Worker 
312*c8dee2aaSAndroid Build Coastguard Worker     if (fSupportedTransientAttachmentUsage != wgpu::TextureUsage::None) {
313*c8dee2aaSAndroid Build Coastguard Worker         info.fUsage |= fSupportedTransientAttachmentUsage;
314*c8dee2aaSAndroid Build Coastguard Worker     }
315*c8dee2aaSAndroid Build Coastguard Worker 
316*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
317*c8dee2aaSAndroid Build Coastguard Worker }
318*c8dee2aaSAndroid Build Coastguard Worker 
getDefaultStorageTextureInfo(SkColorType colorType) const319*c8dee2aaSAndroid Build Coastguard Worker TextureInfo DawnCaps::getDefaultStorageTextureInfo(SkColorType colorType) const {
320*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureFormat format = this->getFormatFromColorType(colorType);
321*c8dee2aaSAndroid Build Coastguard Worker     if (format == wgpu::TextureFormat::Undefined) {
322*c8dee2aaSAndroid Build Coastguard Worker         SkDebugf("colorType=%d is not supported\n", static_cast<int>(colorType));
323*c8dee2aaSAndroid Build Coastguard Worker         return {};
324*c8dee2aaSAndroid Build Coastguard Worker     }
325*c8dee2aaSAndroid Build Coastguard Worker 
326*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& formatInfo = this->getFormatInfo(format);
327*c8dee2aaSAndroid Build Coastguard Worker     if (!SkToBool(FormatInfo::kStorage_Flag & formatInfo.fFlags)) {
328*c8dee2aaSAndroid Build Coastguard Worker         return {};
329*c8dee2aaSAndroid Build Coastguard Worker     }
330*c8dee2aaSAndroid Build Coastguard Worker 
331*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureUsage usage = wgpu::TextureUsage::StorageBinding |
332*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::TextureBinding |
333*c8dee2aaSAndroid Build Coastguard Worker                                wgpu::TextureUsage::CopySrc;
334*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo info;
335*c8dee2aaSAndroid Build Coastguard Worker     info.fSampleCount = 1;
336*c8dee2aaSAndroid Build Coastguard Worker     info.fMipmapped = Mipmapped::kNo;
337*c8dee2aaSAndroid Build Coastguard Worker     info.fFormat = format;
338*c8dee2aaSAndroid Build Coastguard Worker     info.fViewFormat = format;
339*c8dee2aaSAndroid Build Coastguard Worker     info.fUsage = usage;
340*c8dee2aaSAndroid Build Coastguard Worker 
341*c8dee2aaSAndroid Build Coastguard Worker     return TextureInfos::MakeDawn(info);
342*c8dee2aaSAndroid Build Coastguard Worker }
343*c8dee2aaSAndroid Build Coastguard Worker 
getDepthAttachmentDimensions(const TextureInfo & textureInfo,const SkISize colorAttachmentDimensions) const344*c8dee2aaSAndroid Build Coastguard Worker SkISize DawnCaps::getDepthAttachmentDimensions(const TextureInfo& textureInfo,
345*c8dee2aaSAndroid Build Coastguard Worker                                                const SkISize colorAttachmentDimensions) const {
346*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
347*c8dee2aaSAndroid Build Coastguard Worker     // For multiplanar textures, texture->textureInfo() uses the format of planes instead of
348*c8dee2aaSAndroid Build Coastguard Worker     // textures (R8, R8G8, vs R8BG8Biplanar420Unorm), so we have to query texture format from
349*c8dee2aaSAndroid Build Coastguard Worker     // wgpu::Texture object, and then use it reconstruct the full dimensions.
350*c8dee2aaSAndroid Build Coastguard Worker     const auto dawnTextureSpec = TextureInfos::GetDawnTextureSpec(textureInfo);
351*c8dee2aaSAndroid Build Coastguard Worker     wgpu::TextureFormat format = dawnTextureSpec.fFormat;
352*c8dee2aaSAndroid Build Coastguard Worker     if (IsMultiplanarFormat(format) && dawnTextureSpec.fAspect == wgpu::TextureAspect::Plane1Only) {
353*c8dee2aaSAndroid Build Coastguard Worker         // Dawn requires depth attachment to match the size of Y plane (texture size).
354*c8dee2aaSAndroid Build Coastguard Worker         return SkISize::Make(colorAttachmentDimensions.width() * 2,
355*c8dee2aaSAndroid Build Coastguard Worker                              colorAttachmentDimensions.height() * 2);
356*c8dee2aaSAndroid Build Coastguard Worker     }
357*c8dee2aaSAndroid Build Coastguard Worker #endif
358*c8dee2aaSAndroid Build Coastguard Worker 
359*c8dee2aaSAndroid Build Coastguard Worker     return colorAttachmentDimensions;
360*c8dee2aaSAndroid Build Coastguard Worker }
361*c8dee2aaSAndroid Build Coastguard Worker 
getColorTypeInfo(SkColorType colorType,const TextureInfo & textureInfo) const362*c8dee2aaSAndroid Build Coastguard Worker const Caps::ColorTypeInfo* DawnCaps::getColorTypeInfo(SkColorType colorType,
363*c8dee2aaSAndroid Build Coastguard Worker                                                       const TextureInfo& textureInfo) const {
364*c8dee2aaSAndroid Build Coastguard Worker     auto dawnFormat = TextureInfos::GetDawnTextureSpec(textureInfo).getViewFormat();
365*c8dee2aaSAndroid Build Coastguard Worker     if (dawnFormat == wgpu::TextureFormat::Undefined) {
366*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(false);
367*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
368*c8dee2aaSAndroid Build Coastguard Worker     }
369*c8dee2aaSAndroid Build Coastguard Worker 
370*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& info = this->getFormatInfo(dawnFormat);
371*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
372*c8dee2aaSAndroid Build Coastguard Worker         const ColorTypeInfo& ctInfo = info.fColorTypeInfos[i];
373*c8dee2aaSAndroid Build Coastguard Worker         if (ctInfo.fColorType == colorType) {
374*c8dee2aaSAndroid Build Coastguard Worker             return &ctInfo;
375*c8dee2aaSAndroid Build Coastguard Worker         }
376*c8dee2aaSAndroid Build Coastguard Worker     }
377*c8dee2aaSAndroid Build Coastguard Worker 
378*c8dee2aaSAndroid Build Coastguard Worker     return nullptr;
379*c8dee2aaSAndroid Build Coastguard Worker }
380*c8dee2aaSAndroid Build Coastguard Worker 
supportsWritePixels(const TextureInfo & textureInfo) const381*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::supportsWritePixels(const TextureInfo& textureInfo) const {
382*c8dee2aaSAndroid Build Coastguard Worker     const auto spec = TextureInfos::GetDawnTextureSpec(textureInfo);
383*c8dee2aaSAndroid Build Coastguard Worker     return spec.fUsage & wgpu::TextureUsage::CopyDst;
384*c8dee2aaSAndroid Build Coastguard Worker }
385*c8dee2aaSAndroid Build Coastguard Worker 
supportsReadPixels(const TextureInfo & textureInfo) const386*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::supportsReadPixels(const TextureInfo& textureInfo) const {
387*c8dee2aaSAndroid Build Coastguard Worker     const auto spec = TextureInfos::GetDawnTextureSpec(textureInfo);
388*c8dee2aaSAndroid Build Coastguard Worker     return spec.fUsage & wgpu::TextureUsage::CopySrc;
389*c8dee2aaSAndroid Build Coastguard Worker }
390*c8dee2aaSAndroid Build Coastguard Worker 
supportedWritePixelsColorType(SkColorType dstColorType,const TextureInfo & dstTextureInfo,SkColorType srcColorType) const391*c8dee2aaSAndroid Build Coastguard Worker std::pair<SkColorType, bool /*isRGBFormat*/> DawnCaps::supportedWritePixelsColorType(
392*c8dee2aaSAndroid Build Coastguard Worker         SkColorType dstColorType,
393*c8dee2aaSAndroid Build Coastguard Worker         const TextureInfo& dstTextureInfo,
394*c8dee2aaSAndroid Build Coastguard Worker         SkColorType srcColorType) const {
395*c8dee2aaSAndroid Build Coastguard Worker     return {dstColorType, false};
396*c8dee2aaSAndroid Build Coastguard Worker }
397*c8dee2aaSAndroid Build Coastguard Worker 
supportedReadPixelsColorType(SkColorType srcColorType,const TextureInfo & srcTextureInfo,SkColorType dstColorType) const398*c8dee2aaSAndroid Build Coastguard Worker std::pair<SkColorType, bool /*isRGBFormat*/> DawnCaps::supportedReadPixelsColorType(
399*c8dee2aaSAndroid Build Coastguard Worker         SkColorType srcColorType,
400*c8dee2aaSAndroid Build Coastguard Worker         const TextureInfo& srcTextureInfo,
401*c8dee2aaSAndroid Build Coastguard Worker         SkColorType dstColorType) const {
402*c8dee2aaSAndroid Build Coastguard Worker     auto dawnFormat = getFormatFromColorType(srcColorType);
403*c8dee2aaSAndroid Build Coastguard Worker     const FormatInfo& info = this->getFormatInfo(dawnFormat);
404*c8dee2aaSAndroid Build Coastguard Worker     for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
405*c8dee2aaSAndroid Build Coastguard Worker         const auto& ctInfo = info.fColorTypeInfos[i];
406*c8dee2aaSAndroid Build Coastguard Worker         if (ctInfo.fColorType == srcColorType) {
407*c8dee2aaSAndroid Build Coastguard Worker             return {srcColorType, false};
408*c8dee2aaSAndroid Build Coastguard Worker         }
409*c8dee2aaSAndroid Build Coastguard Worker     }
410*c8dee2aaSAndroid Build Coastguard Worker     return {kUnknown_SkColorType, false};
411*c8dee2aaSAndroid Build Coastguard Worker }
412*c8dee2aaSAndroid Build Coastguard Worker 
initCaps(const DawnBackendContext & backendContext,const ContextOptions & options)413*c8dee2aaSAndroid Build Coastguard Worker void DawnCaps::initCaps(const DawnBackendContext& backendContext, const ContextOptions& options) {
414*c8dee2aaSAndroid Build Coastguard Worker     // GetAdapter() is not available in WASM and there's no way to get AdapterInfo off of
415*c8dee2aaSAndroid Build Coastguard Worker     // the WGPUDevice directly.
416*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
417*c8dee2aaSAndroid Build Coastguard Worker     wgpu::AdapterInfo info;
418*c8dee2aaSAndroid Build Coastguard Worker     backendContext.fDevice.GetAdapter().GetInfo(&info);
419*c8dee2aaSAndroid Build Coastguard Worker 
420*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
421*c8dee2aaSAndroid Build Coastguard Worker     this->setDeviceName(std::string(info.device));
422*c8dee2aaSAndroid Build Coastguard Worker #endif
423*c8dee2aaSAndroid Build Coastguard Worker #endif // defined(__EMSCRIPTEN__)
424*c8dee2aaSAndroid Build Coastguard Worker 
425*c8dee2aaSAndroid Build Coastguard Worker     wgpu::SupportedLimits limits;
426*c8dee2aaSAndroid Build Coastguard Worker #if defined(__EMSCRIPTEN__)
427*c8dee2aaSAndroid Build Coastguard Worker     // TODO(crbug.com/42241199): Update Emscripten path with when webgpu.h in Emscripten is updated.
428*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] bool limitsSucceeded = backendContext.fDevice.GetLimits(&limits);
429*c8dee2aaSAndroid Build Coastguard Worker #if (__EMSCRIPTEN_major__ > 3 || (__EMSCRIPTEN_major__ == 3 && __EMSCRIPTEN_minor__ > 1) || \
430*c8dee2aaSAndroid Build Coastguard Worker      (__EMSCRIPTEN_major__ == 3 && __EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ > 50))
431*c8dee2aaSAndroid Build Coastguard Worker     // In Emscripten this always "fails" until
432*c8dee2aaSAndroid Build Coastguard Worker     // https://github.com/emscripten-core/emscripten/pull/20808, which was first included in 3.1.51.
433*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(limitsSucceeded);
434*c8dee2aaSAndroid Build Coastguard Worker #endif
435*c8dee2aaSAndroid Build Coastguard Worker #else
436*c8dee2aaSAndroid Build Coastguard Worker     wgpu::DawnTexelCopyBufferRowAlignmentLimits alignmentLimits{};
437*c8dee2aaSAndroid Build Coastguard Worker     if (backendContext.fDevice.HasFeature(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment)) {
438*c8dee2aaSAndroid Build Coastguard Worker         limits.nextInChain = &alignmentLimits;
439*c8dee2aaSAndroid Build Coastguard Worker     }
440*c8dee2aaSAndroid Build Coastguard Worker     [[maybe_unused]] wgpu::Status status = backendContext.fDevice.GetLimits(&limits);
441*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(status == wgpu::Status::Success);
442*c8dee2aaSAndroid Build Coastguard Worker #endif
443*c8dee2aaSAndroid Build Coastguard Worker 
444*c8dee2aaSAndroid Build Coastguard Worker     fMaxTextureSize = limits.limits.maxTextureDimension2D;
445*c8dee2aaSAndroid Build Coastguard Worker 
446*c8dee2aaSAndroid Build Coastguard Worker     fRequiredTransferBufferAlignment = 4;
447*c8dee2aaSAndroid Build Coastguard Worker     fRequiredUniformBufferAlignment = limits.limits.minUniformBufferOffsetAlignment;
448*c8dee2aaSAndroid Build Coastguard Worker     fRequiredStorageBufferAlignment = limits.limits.minStorageBufferOffsetAlignment;
449*c8dee2aaSAndroid Build Coastguard Worker 
450*c8dee2aaSAndroid Build Coastguard Worker     // Dawn requires 256 bytes per row alignment for buffer texture copies.
451*c8dee2aaSAndroid Build Coastguard Worker     fTextureDataRowBytesAlignment = 256;
452*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
453*c8dee2aaSAndroid Build Coastguard Worker     // If the device supports the DawnTexelCopyBufferRowAlignment feature, the alignment can be
454*c8dee2aaSAndroid Build Coastguard Worker     // queried from its limits.
455*c8dee2aaSAndroid Build Coastguard Worker     if (backendContext.fDevice.HasFeature(wgpu::FeatureName::DawnTexelCopyBufferRowAlignment)) {
456*c8dee2aaSAndroid Build Coastguard Worker         fTextureDataRowBytesAlignment = alignmentLimits.minTexelCopyBufferRowAlignment;
457*c8dee2aaSAndroid Build Coastguard Worker     }
458*c8dee2aaSAndroid Build Coastguard Worker #endif
459*c8dee2aaSAndroid Build Coastguard Worker 
460*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fUniformBufferLayout = Layout::kStd140;
461*c8dee2aaSAndroid Build Coastguard Worker     // The WGSL generator assumes tightly packed std430 layout for SSBOs which is also the default
462*c8dee2aaSAndroid Build Coastguard Worker     // for all types outside the uniform address space in WGSL.
463*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fStorageBufferLayout = Layout::kStd430;
464*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fSeparateTextureAndSamplerBinding = true;
465*c8dee2aaSAndroid Build Coastguard Worker 
466*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fIntrinsicBufferBinding =
467*c8dee2aaSAndroid Build Coastguard Worker             DawnGraphicsPipeline::kIntrinsicUniformBufferIndex;
468*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fRenderStepBufferBinding =
469*c8dee2aaSAndroid Build Coastguard Worker             DawnGraphicsPipeline::kRenderStepUniformBufferIndex;
470*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fPaintParamsBufferBinding = DawnGraphicsPipeline::kPaintUniformBufferIndex;
471*c8dee2aaSAndroid Build Coastguard Worker     fResourceBindingReqs.fGradientBufferBinding = DawnGraphicsPipeline::kGradientBufferIndex;
472*c8dee2aaSAndroid Build Coastguard Worker 
473*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
474*c8dee2aaSAndroid Build Coastguard Worker     // TODO(b/344963958): SSBOs contribute to OOB shader memory access and dawn device loss on
475*c8dee2aaSAndroid Build Coastguard Worker     // Android. Once the problem is fixed SSBOs can be enabled again.
476*c8dee2aaSAndroid Build Coastguard Worker     fStorageBufferSupport = info.backendType != wgpu::BackendType::OpenGL &&
477*c8dee2aaSAndroid Build Coastguard Worker                             info.backendType != wgpu::BackendType::OpenGLES &&
478*c8dee2aaSAndroid Build Coastguard Worker                             info.backendType != wgpu::BackendType::Vulkan;
479*c8dee2aaSAndroid Build Coastguard Worker #else
480*c8dee2aaSAndroid Build Coastguard Worker     // WASM doesn't provide a way to query the backend, so can't tell if we are on a backend that
481*c8dee2aaSAndroid Build Coastguard Worker     // needs to have SSBOs disabled. Pessimistically assume we could be. Once the above conditions
482*c8dee2aaSAndroid Build Coastguard Worker     // go away in Dawn-native, then we can assume SSBOs are always supported in pure WebGPU too.
483*c8dee2aaSAndroid Build Coastguard Worker     fStorageBufferSupport = false;
484*c8dee2aaSAndroid Build Coastguard Worker #endif
485*c8dee2aaSAndroid Build Coastguard Worker 
486*c8dee2aaSAndroid Build Coastguard Worker     fDrawBufferCanBeMapped = false;
487*c8dee2aaSAndroid Build Coastguard Worker 
488*c8dee2aaSAndroid Build Coastguard Worker     fComputeSupport = true;
489*c8dee2aaSAndroid Build Coastguard Worker 
490*c8dee2aaSAndroid Build Coastguard Worker     // TODO: support clamp to border.
491*c8dee2aaSAndroid Build Coastguard Worker     fClampToBorderSupport = false;
492*c8dee2aaSAndroid Build Coastguard Worker 
493*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
494*c8dee2aaSAndroid Build Coastguard Worker     fDrawBufferCanBeMappedForReadback = false;
495*c8dee2aaSAndroid Build Coastguard Worker #endif
496*c8dee2aaSAndroid Build Coastguard Worker 
497*c8dee2aaSAndroid Build Coastguard Worker #if defined(__EMSCRIPTEN__)
498*c8dee2aaSAndroid Build Coastguard Worker     // For wasm, we use async map.
499*c8dee2aaSAndroid Build Coastguard Worker     fBufferMapsAreAsync = true;
500*c8dee2aaSAndroid Build Coastguard Worker #else
501*c8dee2aaSAndroid Build Coastguard Worker     // For Dawn native, we use direct mapping.
502*c8dee2aaSAndroid Build Coastguard Worker     fBufferMapsAreAsync = false;
503*c8dee2aaSAndroid Build Coastguard Worker     fDrawBufferCanBeMapped =
504*c8dee2aaSAndroid Build Coastguard Worker             backendContext.fDevice.HasFeature(wgpu::FeatureName::BufferMapExtendedUsages);
505*c8dee2aaSAndroid Build Coastguard Worker 
506*c8dee2aaSAndroid Build Coastguard Worker     fMSAARenderToSingleSampledSupport =
507*c8dee2aaSAndroid Build Coastguard Worker             backendContext.fDevice.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled);
508*c8dee2aaSAndroid Build Coastguard Worker 
509*c8dee2aaSAndroid Build Coastguard Worker     if (backendContext.fDevice.HasFeature(wgpu::FeatureName::TransientAttachments)) {
510*c8dee2aaSAndroid Build Coastguard Worker         fSupportedTransientAttachmentUsage = wgpu::TextureUsage::TransientAttachment;
511*c8dee2aaSAndroid Build Coastguard Worker     }
512*c8dee2aaSAndroid Build Coastguard Worker     if (backendContext.fDevice.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture)) {
513*c8dee2aaSAndroid Build Coastguard Worker         fSupportedResolveTextureLoadOp = wgpu::LoadOp::ExpandResolveTexture;
514*c8dee2aaSAndroid Build Coastguard Worker     }
515*c8dee2aaSAndroid Build Coastguard Worker     fSupportsPartialLoadResolve =
516*c8dee2aaSAndroid Build Coastguard Worker             backendContext.fDevice.HasFeature(wgpu::FeatureName::DawnPartialLoadResolveTexture);
517*c8dee2aaSAndroid Build Coastguard Worker #endif
518*c8dee2aaSAndroid Build Coastguard Worker 
519*c8dee2aaSAndroid Build Coastguard Worker     if (backendContext.fDevice.HasFeature(wgpu::FeatureName::TimestampQuery)) {
520*c8dee2aaSAndroid Build Coastguard Worker         // Native Dawn has an API for writing timestamps on command buffers. WebGPU only supports
521*c8dee2aaSAndroid Build Coastguard Worker         // begin and end timestamps on render and compute passes.
522*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
523*c8dee2aaSAndroid Build Coastguard Worker         fSupportsCommandBufferTimestamps = true;
524*c8dee2aaSAndroid Build Coastguard Worker #endif
525*c8dee2aaSAndroid Build Coastguard Worker 
526*c8dee2aaSAndroid Build Coastguard Worker         // The emscripten C/C++ interface before 3.1.48 for timestamp query writes on render and
527*c8dee2aaSAndroid Build Coastguard Worker         // compute passes is different than on current emsdk. The older API isn't correctly
528*c8dee2aaSAndroid Build Coastguard Worker         // translated to the current JS WebGPU API in emsdk. So we require 3.1.48+.
529*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)                                                                   \
530*c8dee2aaSAndroid Build Coastguard Worker         || (__EMSCRIPTEN_major__ > 3)                                                          \
531*c8dee2aaSAndroid Build Coastguard Worker         || (__EMSCRIPTEN_major__ == 3 && __EMSCRIPTEN_minor__ > 1)                             \
532*c8dee2aaSAndroid Build Coastguard Worker         || (__EMSCRIPTEN_major__ == 3 && __EMSCRIPTEN_minor__ == 1 && __EMSCRIPTEN_tiny__ >= 48)
533*c8dee2aaSAndroid Build Coastguard Worker         fSupportedGpuStats |= GpuStatsFlags::kElapsedTime;
534*c8dee2aaSAndroid Build Coastguard Worker #endif
535*c8dee2aaSAndroid Build Coastguard Worker     }
536*c8dee2aaSAndroid Build Coastguard Worker 
537*c8dee2aaSAndroid Build Coastguard Worker     if (!backendContext.fTick) {
538*c8dee2aaSAndroid Build Coastguard Worker         fAllowCpuSync = false;
539*c8dee2aaSAndroid Build Coastguard Worker         // This seems paradoxical. However, if we use the async pipeline creation methods (e.g
540*c8dee2aaSAndroid Build Coastguard Worker         // Device::CreateRenderPipelineAsync) then we may have to synchronize before a submit that
541*c8dee2aaSAndroid Build Coastguard Worker         // uses the pipeline. If we use the methods that look synchronous (e.g.
542*c8dee2aaSAndroid Build Coastguard Worker         // Device::CreateRenderPipeline) they actually operate asynchronously on WebGPU but the
543*c8dee2aaSAndroid Build Coastguard Worker         // browser becomes responsible for synchronizing when we call submit.
544*c8dee2aaSAndroid Build Coastguard Worker         fUseAsyncPipelineCreation = false;
545*c8dee2aaSAndroid Build Coastguard Worker 
546*c8dee2aaSAndroid Build Coastguard Worker         // The implementation busy waits after popping.
547*c8dee2aaSAndroid Build Coastguard Worker         fAllowScopedErrorChecks = false;
548*c8dee2aaSAndroid Build Coastguard Worker     }
549*c8dee2aaSAndroid Build Coastguard Worker 
550*c8dee2aaSAndroid Build Coastguard Worker     fFullCompressedUploadSizeMustAlignToBlockDims = true;
551*c8dee2aaSAndroid Build Coastguard Worker }
552*c8dee2aaSAndroid Build Coastguard Worker 
initShaderCaps(const wgpu::Device & device)553*c8dee2aaSAndroid Build Coastguard Worker void DawnCaps::initShaderCaps(const wgpu::Device& device) {
554*c8dee2aaSAndroid Build Coastguard Worker     SkSL::ShaderCaps* shaderCaps = fShaderCaps.get();
555*c8dee2aaSAndroid Build Coastguard Worker 
556*c8dee2aaSAndroid Build Coastguard Worker     // WGSL does not support infinities regardless of hardware support. There are discussions around
557*c8dee2aaSAndroid Build Coastguard Worker     // enabling it using an extension in the future.
558*c8dee2aaSAndroid Build Coastguard Worker     shaderCaps->fInfinitySupport = false;
559*c8dee2aaSAndroid Build Coastguard Worker 
560*c8dee2aaSAndroid Build Coastguard Worker     // WGSL supports shader derivatives in the fragment shader
561*c8dee2aaSAndroid Build Coastguard Worker     shaderCaps->fShaderDerivativeSupport = true;
562*c8dee2aaSAndroid Build Coastguard Worker 
563*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
564*c8dee2aaSAndroid Build Coastguard Worker     if (device.HasFeature(wgpu::FeatureName::DualSourceBlending)) {
565*c8dee2aaSAndroid Build Coastguard Worker         shaderCaps->fDualSourceBlendingSupport = true;
566*c8dee2aaSAndroid Build Coastguard Worker     }
567*c8dee2aaSAndroid Build Coastguard Worker     if (device.HasFeature(wgpu::FeatureName::FramebufferFetch)) {
568*c8dee2aaSAndroid Build Coastguard Worker         shaderCaps->fFBFetchSupport = true;
569*c8dee2aaSAndroid Build Coastguard Worker     }
570*c8dee2aaSAndroid Build Coastguard Worker #endif
571*c8dee2aaSAndroid Build Coastguard Worker }
572*c8dee2aaSAndroid Build Coastguard Worker 
initFormatTable(const wgpu::Device & device)573*c8dee2aaSAndroid Build Coastguard Worker void DawnCaps::initFormatTable(const wgpu::Device& device) {
574*c8dee2aaSAndroid Build Coastguard Worker     FormatInfo* info;
575*c8dee2aaSAndroid Build Coastguard Worker     // Format: RGBA8Unorm
576*c8dee2aaSAndroid Build Coastguard Worker     {
577*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RGBA8Unorm)];
578*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
579*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 2;
580*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
581*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
582*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGBA8Unorm, Surface: kRGBA_8888
583*c8dee2aaSAndroid Build Coastguard Worker         {
584*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
585*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGBA_8888_SkColorType;
586*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
587*c8dee2aaSAndroid Build Coastguard Worker         }
588*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGBA8Unorm, Surface: kRGB_888x
589*c8dee2aaSAndroid Build Coastguard Worker         {
590*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
591*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGB_888x_SkColorType;
592*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
593*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
594*c8dee2aaSAndroid Build Coastguard Worker         }
595*c8dee2aaSAndroid Build Coastguard Worker     }
596*c8dee2aaSAndroid Build Coastguard Worker 
597*c8dee2aaSAndroid Build Coastguard Worker     // Format: R8Unorm
598*c8dee2aaSAndroid Build Coastguard Worker     {
599*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::R8Unorm)];
600*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
601*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
602*c8dee2aaSAndroid Build Coastguard Worker         if (!device.HasFeature(wgpu::FeatureName::R8UnormStorage)) {
603*c8dee2aaSAndroid Build Coastguard Worker             info->fFlags &= ~FormatInfo::kStorage_Flag;
604*c8dee2aaSAndroid Build Coastguard Worker         }
605*c8dee2aaSAndroid Build Coastguard Worker #else
606*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags & ~FormatInfo::kStorage_Flag;
607*c8dee2aaSAndroid Build Coastguard Worker #endif
608*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 3;
609*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
610*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
611*c8dee2aaSAndroid Build Coastguard Worker         // Format: R8Unorm, Surface: kR8_unorm
612*c8dee2aaSAndroid Build Coastguard Worker         {
613*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
614*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kR8_unorm_SkColorType;
615*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
616*c8dee2aaSAndroid Build Coastguard Worker         }
617*c8dee2aaSAndroid Build Coastguard Worker         // Format: R8Unorm, Surface: kAlpha_8
618*c8dee2aaSAndroid Build Coastguard Worker         {
619*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
620*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kAlpha_8_SkColorType;
621*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
622*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
623*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
624*c8dee2aaSAndroid Build Coastguard Worker         }
625*c8dee2aaSAndroid Build Coastguard Worker         // Format: R8Unorm, Surface: kGray_8
626*c8dee2aaSAndroid Build Coastguard Worker         {
627*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
628*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kGray_8_SkColorType;
629*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
630*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle("rrr1");
631*c8dee2aaSAndroid Build Coastguard Worker         }
632*c8dee2aaSAndroid Build Coastguard Worker     }
633*c8dee2aaSAndroid Build Coastguard Worker 
634*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
635*c8dee2aaSAndroid Build Coastguard Worker     const bool supportUnorm16 = device.HasFeature(wgpu::FeatureName::Unorm16TextureFormats);
636*c8dee2aaSAndroid Build Coastguard Worker     // TODO(crbug.com/dawn/1856): Support storage binding for compute shader in Dawn.
637*c8dee2aaSAndroid Build Coastguard Worker     // Format: R16Unorm
638*c8dee2aaSAndroid Build Coastguard Worker     {
639*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::R16Unorm)];
640*c8dee2aaSAndroid Build Coastguard Worker         if (supportUnorm16) {
641*c8dee2aaSAndroid Build Coastguard Worker             info->fFlags = FormatInfo::kAllFlags & ~FormatInfo::kStorage_Flag;
642*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfoCount = 1;
643*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
644*c8dee2aaSAndroid Build Coastguard Worker             int ctIdx = 0;
645*c8dee2aaSAndroid Build Coastguard Worker             // Format: R16Unorm, Surface: kA16_unorm
646*c8dee2aaSAndroid Build Coastguard Worker             {
647*c8dee2aaSAndroid Build Coastguard Worker                 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
648*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fColorType = kA16_unorm_SkColorType;
649*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
650*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
651*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
652*c8dee2aaSAndroid Build Coastguard Worker             }
653*c8dee2aaSAndroid Build Coastguard Worker         }
654*c8dee2aaSAndroid Build Coastguard Worker     }
655*c8dee2aaSAndroid Build Coastguard Worker #endif
656*c8dee2aaSAndroid Build Coastguard Worker 
657*c8dee2aaSAndroid Build Coastguard Worker     // Format: BGRA8Unorm
658*c8dee2aaSAndroid Build Coastguard Worker     {
659*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::BGRA8Unorm)];
660*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
661*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 2;
662*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
663*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
664*c8dee2aaSAndroid Build Coastguard Worker         // Format: BGRA8Unorm, Surface: kBGRA_8888
665*c8dee2aaSAndroid Build Coastguard Worker         {
666*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
667*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kBGRA_8888_SkColorType;
668*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
669*c8dee2aaSAndroid Build Coastguard Worker         }
670*c8dee2aaSAndroid Build Coastguard Worker         // Format: BGRA8Unorm, Surface: kRGB_888x
671*c8dee2aaSAndroid Build Coastguard Worker         {
672*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
673*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGB_888x_SkColorType;
674*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
675*c8dee2aaSAndroid Build Coastguard Worker         }
676*c8dee2aaSAndroid Build Coastguard Worker     }
677*c8dee2aaSAndroid Build Coastguard Worker 
678*c8dee2aaSAndroid Build Coastguard Worker     // Format: RGBA16Float
679*c8dee2aaSAndroid Build Coastguard Worker     {
680*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RGBA16Float)];
681*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
682*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 2;
683*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
684*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
685*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGBA16Float, Surface: RGBA_F16
686*c8dee2aaSAndroid Build Coastguard Worker         {
687*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
688*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGBA_F16_SkColorType;
689*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
690*c8dee2aaSAndroid Build Coastguard Worker         }
691*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGBA16Float, Surface: RGB_F16F16F16x
692*c8dee2aaSAndroid Build Coastguard Worker         {
693*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
694*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGBA_F16_SkColorType;
695*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
696*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
697*c8dee2aaSAndroid Build Coastguard Worker         }
698*c8dee2aaSAndroid Build Coastguard Worker     }
699*c8dee2aaSAndroid Build Coastguard Worker 
700*c8dee2aaSAndroid Build Coastguard Worker     // Format: R16Float
701*c8dee2aaSAndroid Build Coastguard Worker     {
702*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::R16Float)];
703*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
704*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 1;
705*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
706*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
707*c8dee2aaSAndroid Build Coastguard Worker         // Format: R16Float, Surface: kA16_float
708*c8dee2aaSAndroid Build Coastguard Worker         {
709*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
710*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kA16_float_SkColorType;
711*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
712*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle("000r");
713*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fWriteSwizzle = skgpu::Swizzle("a000");
714*c8dee2aaSAndroid Build Coastguard Worker         }
715*c8dee2aaSAndroid Build Coastguard Worker     }
716*c8dee2aaSAndroid Build Coastguard Worker 
717*c8dee2aaSAndroid Build Coastguard Worker     // TODO(crbug.com/dawn/1856): Support storage binding for compute shader in Dawn.
718*c8dee2aaSAndroid Build Coastguard Worker     // Format: RG8Unorm
719*c8dee2aaSAndroid Build Coastguard Worker     {
720*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RG8Unorm)];
721*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
722*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 1;
723*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
724*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
725*c8dee2aaSAndroid Build Coastguard Worker         // Format: RG8Unorm, Surface: kR8G8_unorm
726*c8dee2aaSAndroid Build Coastguard Worker         {
727*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
728*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kR8G8_unorm_SkColorType;
729*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
730*c8dee2aaSAndroid Build Coastguard Worker         }
731*c8dee2aaSAndroid Build Coastguard Worker     }
732*c8dee2aaSAndroid Build Coastguard Worker 
733*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
734*c8dee2aaSAndroid Build Coastguard Worker     // TODO(crbug.com/dawn/1856): Support storage binding for compute shader in Dawn.
735*c8dee2aaSAndroid Build Coastguard Worker     // Format: RG16Unorm
736*c8dee2aaSAndroid Build Coastguard Worker     {
737*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RG16Unorm)];
738*c8dee2aaSAndroid Build Coastguard Worker         if (supportUnorm16) {
739*c8dee2aaSAndroid Build Coastguard Worker             info->fFlags = FormatInfo::kAllFlags;
740*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfoCount = 1;
741*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
742*c8dee2aaSAndroid Build Coastguard Worker             int ctIdx = 0;
743*c8dee2aaSAndroid Build Coastguard Worker             // Format: RG16Unorm, Surface: kR16G16_unorm
744*c8dee2aaSAndroid Build Coastguard Worker             {
745*c8dee2aaSAndroid Build Coastguard Worker                 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
746*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fColorType = kR16G16_unorm_SkColorType;
747*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
748*c8dee2aaSAndroid Build Coastguard Worker             }
749*c8dee2aaSAndroid Build Coastguard Worker         }
750*c8dee2aaSAndroid Build Coastguard Worker     }
751*c8dee2aaSAndroid Build Coastguard Worker #endif
752*c8dee2aaSAndroid Build Coastguard Worker 
753*c8dee2aaSAndroid Build Coastguard Worker     // Format: RGB10A2Unorm
754*c8dee2aaSAndroid Build Coastguard Worker     {
755*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RGB10A2Unorm)];
756*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
757*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 2;
758*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
759*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
760*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGB10A2Unorm, Surface: kRGBA_1010102
761*c8dee2aaSAndroid Build Coastguard Worker         {
762*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
763*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGBA_1010102_SkColorType;
764*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
765*c8dee2aaSAndroid Build Coastguard Worker         }
766*c8dee2aaSAndroid Build Coastguard Worker         // Format: RGB10A2Unorm, Surface: kRGB_101010x
767*c8dee2aaSAndroid Build Coastguard Worker         {
768*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
769*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGB_101010x_SkColorType;
770*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
771*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fReadSwizzle = skgpu::Swizzle::RGB1();
772*c8dee2aaSAndroid Build Coastguard Worker         }
773*c8dee2aaSAndroid Build Coastguard Worker     }
774*c8dee2aaSAndroid Build Coastguard Worker 
775*c8dee2aaSAndroid Build Coastguard Worker     // Format: RG16Float
776*c8dee2aaSAndroid Build Coastguard Worker     {
777*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::RG16Float)];
778*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kAllFlags;
779*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 1;
780*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
781*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
782*c8dee2aaSAndroid Build Coastguard Worker         // Format: RG16Float, Surface: kR16G16_float
783*c8dee2aaSAndroid Build Coastguard Worker         {
784*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
785*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kR16G16_float_SkColorType;
786*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag | ColorTypeInfo::kRenderable_Flag;
787*c8dee2aaSAndroid Build Coastguard Worker         }
788*c8dee2aaSAndroid Build Coastguard Worker     }
789*c8dee2aaSAndroid Build Coastguard Worker 
790*c8dee2aaSAndroid Build Coastguard Worker     // Format: ETC2RGB8Unorm
791*c8dee2aaSAndroid Build Coastguard Worker     {
792*c8dee2aaSAndroid Build Coastguard Worker         if (device.HasFeature(wgpu::FeatureName::TextureCompressionETC2)) {
793*c8dee2aaSAndroid Build Coastguard Worker             info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::ETC2RGB8Unorm)];
794*c8dee2aaSAndroid Build Coastguard Worker             info->fFlags = FormatInfo::kTexturable_Flag;
795*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfoCount = 1;
796*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
797*c8dee2aaSAndroid Build Coastguard Worker             int ctIdx = 0;
798*c8dee2aaSAndroid Build Coastguard Worker             // Format: ETC2RGB8Unorm, Surface: kRGB_888x
799*c8dee2aaSAndroid Build Coastguard Worker             {
800*c8dee2aaSAndroid Build Coastguard Worker                 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
801*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fColorType = kRGB_888x_SkColorType;
802*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
803*c8dee2aaSAndroid Build Coastguard Worker             }
804*c8dee2aaSAndroid Build Coastguard Worker         }
805*c8dee2aaSAndroid Build Coastguard Worker     }
806*c8dee2aaSAndroid Build Coastguard Worker 
807*c8dee2aaSAndroid Build Coastguard Worker     // Format: BC1RGBAUnorm
808*c8dee2aaSAndroid Build Coastguard Worker     {
809*c8dee2aaSAndroid Build Coastguard Worker         if (device.HasFeature(wgpu::FeatureName::TextureCompressionBC)) {
810*c8dee2aaSAndroid Build Coastguard Worker             info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::BC1RGBAUnorm)];
811*c8dee2aaSAndroid Build Coastguard Worker             info->fFlags = FormatInfo::kTexturable_Flag;
812*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfoCount = 1;
813*c8dee2aaSAndroid Build Coastguard Worker             info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
814*c8dee2aaSAndroid Build Coastguard Worker             int ctIdx = 0;
815*c8dee2aaSAndroid Build Coastguard Worker             // Format: BC1RGBAUnorm, Surface: kRGBA_8888
816*c8dee2aaSAndroid Build Coastguard Worker             {
817*c8dee2aaSAndroid Build Coastguard Worker                 auto& ctInfo = info->fColorTypeInfos[ctIdx++];
818*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fColorType = kRGBA_8888_SkColorType;
819*c8dee2aaSAndroid Build Coastguard Worker                 ctInfo.fFlags = ColorTypeInfo::kUploadData_Flag;
820*c8dee2aaSAndroid Build Coastguard Worker             }
821*c8dee2aaSAndroid Build Coastguard Worker         }
822*c8dee2aaSAndroid Build Coastguard Worker     }
823*c8dee2aaSAndroid Build Coastguard Worker 
824*c8dee2aaSAndroid Build Coastguard Worker     /*
825*c8dee2aaSAndroid Build Coastguard Worker      * Non-color formats
826*c8dee2aaSAndroid Build Coastguard Worker      */
827*c8dee2aaSAndroid Build Coastguard Worker 
828*c8dee2aaSAndroid Build Coastguard Worker     // Format: Stencil8
829*c8dee2aaSAndroid Build Coastguard Worker     {
830*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::Stencil8)];
831*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kMSAA_Flag;
832*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 0;
833*c8dee2aaSAndroid Build Coastguard Worker     }
834*c8dee2aaSAndroid Build Coastguard Worker 
835*c8dee2aaSAndroid Build Coastguard Worker     // Format: Depth16UNorm
836*c8dee2aaSAndroid Build Coastguard Worker     {
837*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::Depth16Unorm)];
838*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kMSAA_Flag;
839*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 0;
840*c8dee2aaSAndroid Build Coastguard Worker     }
841*c8dee2aaSAndroid Build Coastguard Worker 
842*c8dee2aaSAndroid Build Coastguard Worker     // Format: Depth32Float
843*c8dee2aaSAndroid Build Coastguard Worker     {
844*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::Depth32Float)];
845*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kMSAA_Flag;
846*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 0;
847*c8dee2aaSAndroid Build Coastguard Worker     }
848*c8dee2aaSAndroid Build Coastguard Worker 
849*c8dee2aaSAndroid Build Coastguard Worker     // Format: Depth24PlusStencil8
850*c8dee2aaSAndroid Build Coastguard Worker     {
851*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::Depth24PlusStencil8)];
852*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kMSAA_Flag;
853*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 0;
854*c8dee2aaSAndroid Build Coastguard Worker     }
855*c8dee2aaSAndroid Build Coastguard Worker 
856*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
857*c8dee2aaSAndroid Build Coastguard Worker     // Format: External
858*c8dee2aaSAndroid Build Coastguard Worker     {
859*c8dee2aaSAndroid Build Coastguard Worker         info = &fFormatTable[GetFormatIndex(wgpu::TextureFormat::External)];
860*c8dee2aaSAndroid Build Coastguard Worker         info->fFlags = FormatInfo::kTexturable_Flag;
861*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfoCount = 1;
862*c8dee2aaSAndroid Build Coastguard Worker         info->fColorTypeInfos = std::make_unique<ColorTypeInfo[]>(info->fColorTypeInfoCount);
863*c8dee2aaSAndroid Build Coastguard Worker         int ctIdx = 0;
864*c8dee2aaSAndroid Build Coastguard Worker         // Format: External, Surface: kRGBA_8888
865*c8dee2aaSAndroid Build Coastguard Worker         {
866*c8dee2aaSAndroid Build Coastguard Worker             auto& ctInfo = info->fColorTypeInfos[ctIdx++];
867*c8dee2aaSAndroid Build Coastguard Worker             ctInfo.fColorType = kRGBA_8888_SkColorType;
868*c8dee2aaSAndroid Build Coastguard Worker         }
869*c8dee2aaSAndroid Build Coastguard Worker     }
870*c8dee2aaSAndroid Build Coastguard Worker #endif
871*c8dee2aaSAndroid Build Coastguard Worker 
872*c8dee2aaSAndroid Build Coastguard Worker     ////////////////////////////////////////////////////////////////////////////
873*c8dee2aaSAndroid Build Coastguard Worker     // Map SkColorTypes (used for creating SkSurfaces) to wgpu::TextureFormat.
874*c8dee2aaSAndroid Build Coastguard Worker     // The order in which the formats are passed into the setColorType function
875*c8dee2aaSAndroid Build Coastguard Worker     // indicates the priority in selecting which format we use for a given
876*c8dee2aaSAndroid Build Coastguard Worker     // SkColorType.
877*c8dee2aaSAndroid Build Coastguard Worker 
878*c8dee2aaSAndroid Build Coastguard Worker     std::fill_n(fColorTypeToFormatTable, kSkColorTypeCnt, wgpu::TextureFormat::Undefined);
879*c8dee2aaSAndroid Build Coastguard Worker 
880*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kAlpha_8_SkColorType,          { wgpu::TextureFormat::R8Unorm });
881*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGBA_8888_SkColorType,        { wgpu::TextureFormat::RGBA8Unorm });
882*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGB_888x_SkColorType,
883*c8dee2aaSAndroid Build Coastguard Worker                        {wgpu::TextureFormat::RGBA8Unorm, wgpu::TextureFormat::BGRA8Unorm});
884*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kBGRA_8888_SkColorType,        { wgpu::TextureFormat::BGRA8Unorm });
885*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kGray_8_SkColorType,           { wgpu::TextureFormat::R8Unorm });
886*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kR8_unorm_SkColorType,         { wgpu::TextureFormat::R8Unorm });
887*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGBA_F16_SkColorType,         { wgpu::TextureFormat::RGBA16Float });
888*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGB_F16F16F16x_SkColorType,   { wgpu::TextureFormat::RGBA16Float });
889*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kA16_float_SkColorType,        { wgpu::TextureFormat::R16Float });
890*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kR8G8_unorm_SkColorType,       { wgpu::TextureFormat::RG8Unorm });
891*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGBA_1010102_SkColorType,     { wgpu::TextureFormat::RGB10A2Unorm });
892*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kRGB_101010x_SkColorType,      { wgpu::TextureFormat::RGB10A2Unorm });
893*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kR16G16_float_SkColorType,     { wgpu::TextureFormat::RG16Float });
894*c8dee2aaSAndroid Build Coastguard Worker 
895*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
896*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kA16_unorm_SkColorType,        { wgpu::TextureFormat::R16Unorm });
897*c8dee2aaSAndroid Build Coastguard Worker     this->setColorType(kR16G16_unorm_SkColorType,     { wgpu::TextureFormat::RG16Unorm });
898*c8dee2aaSAndroid Build Coastguard Worker #endif
899*c8dee2aaSAndroid Build Coastguard Worker }
900*c8dee2aaSAndroid Build Coastguard Worker 
901*c8dee2aaSAndroid Build Coastguard Worker // static
GetFormatIndex(wgpu::TextureFormat format)902*c8dee2aaSAndroid Build Coastguard Worker size_t DawnCaps::GetFormatIndex(wgpu::TextureFormat format) {
903*c8dee2aaSAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kFormats); ++i) {
904*c8dee2aaSAndroid Build Coastguard Worker         if (format == kFormats[i]) {
905*c8dee2aaSAndroid Build Coastguard Worker             return i;
906*c8dee2aaSAndroid Build Coastguard Worker         }
907*c8dee2aaSAndroid Build Coastguard Worker     }
908*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGFAILF("Unsupported wgpu::TextureFormat: 0x%08X\n", static_cast<uint32_t>(format));
909*c8dee2aaSAndroid Build Coastguard Worker     return 0;
910*c8dee2aaSAndroid Build Coastguard Worker }
911*c8dee2aaSAndroid Build Coastguard Worker 
setColorType(SkColorType colorType,std::initializer_list<wgpu::TextureFormat> formats)912*c8dee2aaSAndroid Build Coastguard Worker void DawnCaps::setColorType(SkColorType colorType,
913*c8dee2aaSAndroid Build Coastguard Worker                             std::initializer_list<wgpu::TextureFormat> formats) {
914*c8dee2aaSAndroid Build Coastguard Worker     static_assert(std::size(kFormats) <= kFormatCount,
915*c8dee2aaSAndroid Build Coastguard Worker                   "Size is not compatible for DawnCaps::fFormatTable and kFormats");
916*c8dee2aaSAndroid Build Coastguard Worker     int idx = static_cast<int>(colorType);
917*c8dee2aaSAndroid Build Coastguard Worker     for (auto it = formats.begin(); it != formats.end(); ++it) {
918*c8dee2aaSAndroid Build Coastguard Worker         const auto& info = this->getFormatInfo(*it);
919*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < info.fColorTypeInfoCount; ++i) {
920*c8dee2aaSAndroid Build Coastguard Worker             if (info.fColorTypeInfos[i].fColorType == colorType) {
921*c8dee2aaSAndroid Build Coastguard Worker                 fColorTypeToFormatTable[idx] = *it;
922*c8dee2aaSAndroid Build Coastguard Worker                 return;
923*c8dee2aaSAndroid Build Coastguard Worker             }
924*c8dee2aaSAndroid Build Coastguard Worker         }
925*c8dee2aaSAndroid Build Coastguard Worker     }
926*c8dee2aaSAndroid Build Coastguard Worker }
927*c8dee2aaSAndroid Build Coastguard Worker 
928*c8dee2aaSAndroid Build Coastguard Worker // Make sure the format table indices will fit into the packed bits, with room to spare for
929*c8dee2aaSAndroid Build Coastguard Worker // representing an unused attachment.
930*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kFormatBits = 11; // x2 attachments (color & depthStencil formats)
931*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kSampleBits = 4;  // x2 attachments (color & depthStencil numSamples)
932*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kResolveBits = 1;
933*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kUnusedAttachmentIndex = (1 << kFormatBits) - 1;
934*c8dee2aaSAndroid Build Coastguard Worker static_assert(2*(kFormatBits + kSampleBits) + kResolveBits <= 32);
935*c8dee2aaSAndroid Build Coastguard Worker static_assert(std::size(kFormats) <= kUnusedAttachmentIndex);
936*c8dee2aaSAndroid Build Coastguard Worker 
937*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kDepthStencilNumSamplesOffset = kResolveBits;
938*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kDepthStencilFormatOffset = kDepthStencilNumSamplesOffset + kSampleBits;
939*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kColorNumSamplesOffset = kDepthStencilFormatOffset + kFormatBits;
940*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kColorFormatOffset = kColorNumSamplesOffset + kSampleBits;
941*c8dee2aaSAndroid Build Coastguard Worker 
942*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kFormatMask     = (1 << kFormatBits) - 1;
943*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kNumSamplesMask = (1 << kSampleBits) - 1;
944*c8dee2aaSAndroid Build Coastguard Worker static constexpr uint32_t kResolveMask    = (1 << kResolveBits) - 1;
945*c8dee2aaSAndroid Build Coastguard Worker 
getRenderPassDescKeyForPipeline(const RenderPassDesc & renderPassDesc) const946*c8dee2aaSAndroid Build Coastguard Worker uint32_t DawnCaps::getRenderPassDescKeyForPipeline(const RenderPassDesc& renderPassDesc) const {
947*c8dee2aaSAndroid Build Coastguard Worker     const TextureInfo& colorInfo = renderPassDesc.fColorAttachment.fTextureInfo;
948*c8dee2aaSAndroid Build Coastguard Worker     const TextureInfo& depthStencilInfo = renderPassDesc.fDepthStencilAttachment.fTextureInfo;
949*c8dee2aaSAndroid Build Coastguard Worker     // The color attachment should be valid; the depth-stencil attachment may not be if it's not
950*c8dee2aaSAndroid Build Coastguard Worker     // being used.
951*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(colorInfo.isValid());
952*c8dee2aaSAndroid Build Coastguard Worker 
953*c8dee2aaSAndroid Build Coastguard Worker     // Use format indices instead of WGPUTextureFormat values since they can be larger than 16 bits.
954*c8dee2aaSAndroid Build Coastguard Worker     uint32_t colorFormatIndex =
955*c8dee2aaSAndroid Build Coastguard Worker             GetFormatIndex(TextureInfos::GetDawnTextureSpec(colorInfo).getViewFormat());
956*c8dee2aaSAndroid Build Coastguard Worker     uint32_t depthStencilFormatIndex =
957*c8dee2aaSAndroid Build Coastguard Worker             depthStencilInfo.isValid()
958*c8dee2aaSAndroid Build Coastguard Worker                     ? GetFormatIndex(
959*c8dee2aaSAndroid Build Coastguard Worker                               TextureInfos::GetDawnTextureSpec(depthStencilInfo).getViewFormat())
960*c8dee2aaSAndroid Build Coastguard Worker                     : kUnusedAttachmentIndex;
961*c8dee2aaSAndroid Build Coastguard Worker 
962*c8dee2aaSAndroid Build Coastguard Worker     // Note: if Dawn supports ExpandResolveTexture load op and the render pass uses it to load
963*c8dee2aaSAndroid Build Coastguard Worker     // the resolve texture, a render pipeline will need to be created with
964*c8dee2aaSAndroid Build Coastguard Worker     // wgpu::ColorTargetStateExpandResolveTextureDawn chained struct in order to be compatible.
965*c8dee2aaSAndroid Build Coastguard Worker     // Hence a render pipeline created for a render pass using ExpandResolveTexture load op will
966*c8dee2aaSAndroid Build Coastguard Worker     // be different from the one created for a render pass not using that load op.
967*c8dee2aaSAndroid Build Coastguard Worker     // So we need to include a bit flag to differentiate the two kinds of pipelines.
968*c8dee2aaSAndroid Build Coastguard Worker     // Also avoid returning a cached pipeline that is not compatible with the render pass using
969*c8dee2aaSAndroid Build Coastguard Worker     // ExpandResolveTexture load op and vice versa.
970*c8dee2aaSAndroid Build Coastguard Worker     const bool shouldIncludeLoadResolveAttachmentBit = this->resolveTextureLoadOp().has_value();
971*c8dee2aaSAndroid Build Coastguard Worker     uint32_t loadResolveAttachmentKey = 0;
972*c8dee2aaSAndroid Build Coastguard Worker     if (shouldIncludeLoadResolveAttachmentBit &&
973*c8dee2aaSAndroid Build Coastguard Worker         renderPassDesc.fColorResolveAttachment.fTextureInfo.isValid() &&
974*c8dee2aaSAndroid Build Coastguard Worker         renderPassDesc.fColorResolveAttachment.fLoadOp == LoadOp::kLoad) {
975*c8dee2aaSAndroid Build Coastguard Worker         loadResolveAttachmentKey = 1;
976*c8dee2aaSAndroid Build Coastguard Worker     }
977*c8dee2aaSAndroid Build Coastguard Worker 
978*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(colorFormatIndex < (1 << kFormatBits));
979*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(colorInfo.numSamples() < (1 << kSampleBits));
980*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(depthStencilFormatIndex < (1 << kFormatBits));
981*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(depthStencilInfo.numSamples() < (1 << kSampleBits));
982*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(loadResolveAttachmentKey < (1 << kResolveBits));
983*c8dee2aaSAndroid Build Coastguard Worker 
984*c8dee2aaSAndroid Build Coastguard Worker     return (colorFormatIndex              << kColorFormatOffset) |
985*c8dee2aaSAndroid Build Coastguard Worker            (colorInfo.numSamples()        << kColorNumSamplesOffset) |
986*c8dee2aaSAndroid Build Coastguard Worker            (depthStencilFormatIndex       << kDepthStencilFormatOffset) |
987*c8dee2aaSAndroid Build Coastguard Worker            (depthStencilInfo.numSamples() << kDepthStencilNumSamplesOffset) |
988*c8dee2aaSAndroid Build Coastguard Worker            loadResolveAttachmentKey;
989*c8dee2aaSAndroid Build Coastguard Worker }
990*c8dee2aaSAndroid Build Coastguard Worker 
991*c8dee2aaSAndroid Build Coastguard Worker static constexpr int kDawnGraphicsPipelineKeyData32Count = 4;
992*c8dee2aaSAndroid Build Coastguard Worker 
makeGraphicsPipelineKey(const GraphicsPipelineDesc & pipelineDesc,const RenderPassDesc & renderPassDesc) const993*c8dee2aaSAndroid Build Coastguard Worker UniqueKey DawnCaps::makeGraphicsPipelineKey(const GraphicsPipelineDesc& pipelineDesc,
994*c8dee2aaSAndroid Build Coastguard Worker                                             const RenderPassDesc& renderPassDesc) const {
995*c8dee2aaSAndroid Build Coastguard Worker     UniqueKey pipelineKey;
996*c8dee2aaSAndroid Build Coastguard Worker     {
997*c8dee2aaSAndroid Build Coastguard Worker         // 4 uint32_t's (render step id, paint id, uint32 RenderPassDesc, uint16 write swizzle key)
998*c8dee2aaSAndroid Build Coastguard Worker         UniqueKey::Builder builder(&pipelineKey, get_pipeline_domain(),
999*c8dee2aaSAndroid Build Coastguard Worker                                    kDawnGraphicsPipelineKeyData32Count, "DawnGraphicsPipeline");
1000*c8dee2aaSAndroid Build Coastguard Worker         // Add GraphicsPipelineDesc key.
1001*c8dee2aaSAndroid Build Coastguard Worker         builder[0] = pipelineDesc.renderStepID();
1002*c8dee2aaSAndroid Build Coastguard Worker         builder[1] = pipelineDesc.paintParamsID().asUInt();
1003*c8dee2aaSAndroid Build Coastguard Worker 
1004*c8dee2aaSAndroid Build Coastguard Worker         // Add RenderPassDesc key and write swizzle (which is separate from the RenderPassDescKey
1005*c8dee2aaSAndroid Build Coastguard Worker         // because it is applied in the program writing to the target, and is not actually part of
1006*c8dee2aaSAndroid Build Coastguard Worker         // the underlying GPU render pass config).
1007*c8dee2aaSAndroid Build Coastguard Worker         builder[2] = this->getRenderPassDescKeyForPipeline(renderPassDesc);
1008*c8dee2aaSAndroid Build Coastguard Worker         builder[3] = renderPassDesc.fWriteSwizzle.asKey();
1009*c8dee2aaSAndroid Build Coastguard Worker         builder.finish();
1010*c8dee2aaSAndroid Build Coastguard Worker     }
1011*c8dee2aaSAndroid Build Coastguard Worker 
1012*c8dee2aaSAndroid Build Coastguard Worker     return pipelineKey;
1013*c8dee2aaSAndroid Build Coastguard Worker }
1014*c8dee2aaSAndroid Build Coastguard Worker 
extractGraphicsDescs(const UniqueKey & key,GraphicsPipelineDesc * pipelineDesc,RenderPassDesc * renderPassDesc,const RendererProvider * rendererProvider) const1015*c8dee2aaSAndroid Build Coastguard Worker bool DawnCaps::extractGraphicsDescs(const UniqueKey& key,
1016*c8dee2aaSAndroid Build Coastguard Worker                                     GraphicsPipelineDesc* pipelineDesc,
1017*c8dee2aaSAndroid Build Coastguard Worker                                     RenderPassDesc* renderPassDesc,
1018*c8dee2aaSAndroid Build Coastguard Worker                                     const RendererProvider* rendererProvider) const {
1019*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(key.domain() == get_pipeline_domain());
1020*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(key.dataSize() == 4 * kDawnGraphicsPipelineKeyData32Count);
1021*c8dee2aaSAndroid Build Coastguard Worker 
1022*c8dee2aaSAndroid Build Coastguard Worker     const uint32_t* rawKeyData = key.data();
1023*c8dee2aaSAndroid Build Coastguard Worker 
1024*c8dee2aaSAndroid Build Coastguard Worker     const RenderStep* renderStep = rendererProvider->lookup(rawKeyData[0]);
1025*c8dee2aaSAndroid Build Coastguard Worker     *pipelineDesc = GraphicsPipelineDesc(renderStep, UniquePaintParamsID(rawKeyData[1]));
1026*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(renderStep->performsShading() == pipelineDesc->paintParamsID().isValid());
1027*c8dee2aaSAndroid Build Coastguard Worker 
1028*c8dee2aaSAndroid Build Coastguard Worker     uint32_t renderpassDescBits = rawKeyData[2];
1029*c8dee2aaSAndroid Build Coastguard Worker     uint32_t colorFormatIndex = (renderpassDescBits >> kColorFormatOffset) & kFormatMask;
1030*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(colorFormatIndex < std::size(kFormats));
1031*c8dee2aaSAndroid Build Coastguard Worker 
1032*c8dee2aaSAndroid Build Coastguard Worker     DawnTextureInfo dawnInfo;
1033*c8dee2aaSAndroid Build Coastguard Worker     dawnInfo.fFormat = dawnInfo.fViewFormat = kFormats[colorFormatIndex];
1034*c8dee2aaSAndroid Build Coastguard Worker     dawnInfo.fSampleCount  = 1;
1035*c8dee2aaSAndroid Build Coastguard Worker     dawnInfo.fMipmapped = skgpu::Mipmapped::kNo;
1036*c8dee2aaSAndroid Build Coastguard Worker     dawnInfo.fUsage = wgpu::TextureUsage::TextureBinding | wgpu::TextureUsage::RenderAttachment;
1037*c8dee2aaSAndroid Build Coastguard Worker 
1038*c8dee2aaSAndroid Build Coastguard Worker     uint32_t colorSampleCount = (renderpassDescBits >> kColorNumSamplesOffset) & kNumSamplesMask;
1039*c8dee2aaSAndroid Build Coastguard Worker     bool requiresMSAA = colorSampleCount > 1;
1040*c8dee2aaSAndroid Build Coastguard Worker 
1041*c8dee2aaSAndroid Build Coastguard Worker     SkEnumBitMask<DepthStencilFlags> dsFlags = DepthStencilFlags::kNone;
1042*c8dee2aaSAndroid Build Coastguard Worker 
1043*c8dee2aaSAndroid Build Coastguard Worker     uint32_t depthStencilFormatIndex =
1044*c8dee2aaSAndroid Build Coastguard Worker             (renderpassDescBits >> kDepthStencilFormatOffset) & kFormatMask;
1045*c8dee2aaSAndroid Build Coastguard Worker     if (depthStencilFormatIndex != kUnusedAttachmentIndex) {
1046*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(depthStencilFormatIndex < std::size(kFormats));
1047*c8dee2aaSAndroid Build Coastguard Worker         wgpu::TextureFormat dsFormat = kFormats[depthStencilFormatIndex];
1048*c8dee2aaSAndroid Build Coastguard Worker         if (DawnFormatIsDepth(dsFormat)) {
1049*c8dee2aaSAndroid Build Coastguard Worker             dsFlags |= DepthStencilFlags::kDepth;
1050*c8dee2aaSAndroid Build Coastguard Worker         }
1051*c8dee2aaSAndroid Build Coastguard Worker         if (DawnFormatIsStencil(dsFormat)) {
1052*c8dee2aaSAndroid Build Coastguard Worker             dsFlags |= DepthStencilFlags::kStencil;
1053*c8dee2aaSAndroid Build Coastguard Worker         }
1054*c8dee2aaSAndroid Build Coastguard Worker     }
1055*c8dee2aaSAndroid Build Coastguard Worker     SkDEBUGCODE(uint32_t dsSampleCount =
1056*c8dee2aaSAndroid Build Coastguard Worker                     (renderpassDescBits >> kDepthStencilNumSamplesOffset) & kNumSamplesMask;)
1057*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(colorSampleCount == dsSampleCount);
1058*c8dee2aaSAndroid Build Coastguard Worker 
1059*c8dee2aaSAndroid Build Coastguard Worker     LoadOp loadOp = LoadOp::kClear;
1060*c8dee2aaSAndroid Build Coastguard Worker     if (renderpassDescBits & kResolveMask) {
1061*c8dee2aaSAndroid Build Coastguard Worker         // This bit should only be set if Dawn supports ExpandResolveTexture load op
1062*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->resolveTextureLoadOp().has_value());
1063*c8dee2aaSAndroid Build Coastguard Worker         loadOp = LoadOp::kLoad;
1064*c8dee2aaSAndroid Build Coastguard Worker     }
1065*c8dee2aaSAndroid Build Coastguard Worker 
1066*c8dee2aaSAndroid Build Coastguard Worker     Swizzle writeSwizzle = SwizzleCtorAccessor::Make(rawKeyData[3]);
1067*c8dee2aaSAndroid Build Coastguard Worker 
1068*c8dee2aaSAndroid Build Coastguard Worker     *renderPassDesc = RenderPassDesc::Make(this,
1069*c8dee2aaSAndroid Build Coastguard Worker                                            TextureInfos::MakeDawn(dawnInfo),
1070*c8dee2aaSAndroid Build Coastguard Worker                                            loadOp,
1071*c8dee2aaSAndroid Build Coastguard Worker                                            StoreOp::kStore,
1072*c8dee2aaSAndroid Build Coastguard Worker                                            dsFlags,
1073*c8dee2aaSAndroid Build Coastguard Worker                                            /* clearColor= */ { .0f, .0f, .0f, .0f },
1074*c8dee2aaSAndroid Build Coastguard Worker                                            requiresMSAA,
1075*c8dee2aaSAndroid Build Coastguard Worker                                            writeSwizzle);
1076*c8dee2aaSAndroid Build Coastguard Worker 
1077*c8dee2aaSAndroid Build Coastguard Worker     return true;
1078*c8dee2aaSAndroid Build Coastguard Worker }
1079*c8dee2aaSAndroid Build Coastguard Worker 
makeComputePipelineKey(const ComputePipelineDesc & pipelineDesc) const1080*c8dee2aaSAndroid Build Coastguard Worker UniqueKey DawnCaps::makeComputePipelineKey(const ComputePipelineDesc& pipelineDesc) const {
1081*c8dee2aaSAndroid Build Coastguard Worker     UniqueKey pipelineKey;
1082*c8dee2aaSAndroid Build Coastguard Worker     {
1083*c8dee2aaSAndroid Build Coastguard Worker         static const skgpu::UniqueKey::Domain kComputePipelineDomain = UniqueKey::GenerateDomain();
1084*c8dee2aaSAndroid Build Coastguard Worker         // The key is made up of a single uint32_t corresponding to the compute step ID.
1085*c8dee2aaSAndroid Build Coastguard Worker         UniqueKey::Builder builder(&pipelineKey, kComputePipelineDomain, 1, "ComputePipeline");
1086*c8dee2aaSAndroid Build Coastguard Worker         builder[0] = pipelineDesc.computeStep()->uniqueID();
1087*c8dee2aaSAndroid Build Coastguard Worker 
1088*c8dee2aaSAndroid Build Coastguard Worker         // TODO(b/240615224): The local work group size should factor into the key here since it is
1089*c8dee2aaSAndroid Build Coastguard Worker         // specified in the shader text on Dawn/SPIR-V. This is not a problem right now since
1090*c8dee2aaSAndroid Build Coastguard Worker         // ComputeSteps don't vary their workgroup size dynamically.
1091*c8dee2aaSAndroid Build Coastguard Worker 
1092*c8dee2aaSAndroid Build Coastguard Worker         builder.finish();
1093*c8dee2aaSAndroid Build Coastguard Worker     }
1094*c8dee2aaSAndroid Build Coastguard Worker     return pipelineKey;
1095*c8dee2aaSAndroid Build Coastguard Worker }
1096*c8dee2aaSAndroid Build Coastguard Worker 
1097*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
1098*c8dee2aaSAndroid Build Coastguard Worker namespace {
1099*c8dee2aaSAndroid Build Coastguard Worker using namespace ycbcrUtils;
1100*c8dee2aaSAndroid Build Coastguard Worker 
non_format_info_as_uint32(const wgpu::YCbCrVkDescriptor & desc)1101*c8dee2aaSAndroid Build Coastguard Worker uint32_t non_format_info_as_uint32(const wgpu::YCbCrVkDescriptor& desc) {
1102*c8dee2aaSAndroid Build Coastguard Worker     static_assert(kComponentAShift + kComponentBits <= 32);
1103*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkYCbCrModel                          < (1u << kYcbcrModelBits    ));
1104*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkYCbCrRange                          < (1u << kYcbcrRangeBits    ));
1105*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkXChromaOffset                       < (1u << kXChromaOffsetBits ));
1106*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkYChromaOffset                       < (1u << kYChromaOffsetBits ));
1107*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(desc.vkChromaFilter) < (1u << kChromaFilterBits  ));
1108*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkComponentSwizzleRed                 < (1u << kComponentBits     ));
1109*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkComponentSwizzleGreen               < (1u << kComponentBits     ));
1110*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkComponentSwizzleBlue                < (1u << kComponentBits     ));
1111*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(desc.vkComponentSwizzleAlpha               < (1u << kComponentBits     ));
1112*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(desc.forceExplicitReconstruction)
1113*c8dee2aaSAndroid Build Coastguard Worker              < (1u << kForceExplicitReconBits));
1114*c8dee2aaSAndroid Build Coastguard Worker 
1115*c8dee2aaSAndroid Build Coastguard Worker     return (((uint32_t)(DawnDescriptorUsesExternalFormat(desc)) << kUsesExternalFormatShift) |
1116*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkYCbCrModel                     ) << kYcbcrModelShift        ) |
1117*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkYCbCrRange                     ) << kYcbcrRangeShift        ) |
1118*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkXChromaOffset                  ) << kXChromaOffsetShift     ) |
1119*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkYChromaOffset                  ) << kYChromaOffsetShift     ) |
1120*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkChromaFilter                   ) << kChromaFilterShift      ) |
1121*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.forceExplicitReconstruction      ) << kForceExplicitReconShift) |
1122*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkComponentSwizzleRed            ) << kComponentRShift        ) |
1123*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkComponentSwizzleGreen          ) << kComponentGShift        ) |
1124*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkComponentSwizzleBlue           ) << kComponentBShift        ) |
1125*c8dee2aaSAndroid Build Coastguard Worker             ((uint32_t)(desc.vkComponentSwizzleAlpha          ) << kComponentAShift        ));
1126*c8dee2aaSAndroid Build Coastguard Worker }
1127*c8dee2aaSAndroid Build Coastguard Worker } // anonymous
1128*c8dee2aaSAndroid Build Coastguard Worker #endif
1129*c8dee2aaSAndroid Build Coastguard Worker 
getImmutableSamplerInfo(const TextureProxy * proxy) const1130*c8dee2aaSAndroid Build Coastguard Worker ImmutableSamplerInfo DawnCaps::getImmutableSamplerInfo(const TextureProxy* proxy) const {
1131*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
1132*c8dee2aaSAndroid Build Coastguard Worker     if (proxy) {
1133*c8dee2aaSAndroid Build Coastguard Worker         const wgpu::YCbCrVkDescriptor& ycbcrConversionInfo =
1134*c8dee2aaSAndroid Build Coastguard Worker                 TextureInfos::GetDawnTextureSpec(proxy->textureInfo()).fYcbcrVkDescriptor;
1135*c8dee2aaSAndroid Build Coastguard Worker 
1136*c8dee2aaSAndroid Build Coastguard Worker         if (ycbcrUtils::DawnDescriptorIsValid(ycbcrConversionInfo)) {
1137*c8dee2aaSAndroid Build Coastguard Worker             ImmutableSamplerInfo immutableSamplerInfo;
1138*c8dee2aaSAndroid Build Coastguard Worker             // A vkFormat of 0 indicates we are using an external format rather than a known one.
1139*c8dee2aaSAndroid Build Coastguard Worker             immutableSamplerInfo.fFormat = (ycbcrConversionInfo.vkFormat == 0)
1140*c8dee2aaSAndroid Build Coastguard Worker                     ? ycbcrConversionInfo.externalFormat
1141*c8dee2aaSAndroid Build Coastguard Worker                     : ycbcrConversionInfo.vkFormat;
1142*c8dee2aaSAndroid Build Coastguard Worker             immutableSamplerInfo.fNonFormatYcbcrConversionInfo =
1143*c8dee2aaSAndroid Build Coastguard Worker                     non_format_info_as_uint32(ycbcrConversionInfo);
1144*c8dee2aaSAndroid Build Coastguard Worker             return immutableSamplerInfo;
1145*c8dee2aaSAndroid Build Coastguard Worker         }
1146*c8dee2aaSAndroid Build Coastguard Worker     }
1147*c8dee2aaSAndroid Build Coastguard Worker #endif
1148*c8dee2aaSAndroid Build Coastguard Worker 
1149*c8dee2aaSAndroid Build Coastguard Worker     // If the proxy is null or the YCbCr conversion for that proxy is invalid, then return a
1150*c8dee2aaSAndroid Build Coastguard Worker     // default ImmutableSamplerInfo struct.
1151*c8dee2aaSAndroid Build Coastguard Worker     return {};
1152*c8dee2aaSAndroid Build Coastguard Worker }
1153*c8dee2aaSAndroid Build Coastguard Worker 
buildKeyForTexture(SkISize dimensions,const TextureInfo & info,ResourceType type,Shareable shareable,GraphiteResourceKey * key) const1154*c8dee2aaSAndroid Build Coastguard Worker void DawnCaps::buildKeyForTexture(SkISize dimensions,
1155*c8dee2aaSAndroid Build Coastguard Worker                                   const TextureInfo& info,
1156*c8dee2aaSAndroid Build Coastguard Worker                                   ResourceType type,
1157*c8dee2aaSAndroid Build Coastguard Worker                                   Shareable shareable,
1158*c8dee2aaSAndroid Build Coastguard Worker                                   GraphiteResourceKey* key) const {
1159*c8dee2aaSAndroid Build Coastguard Worker     const DawnTextureSpec dawnSpec = TextureInfos::GetDawnTextureSpec(info);
1160*c8dee2aaSAndroid Build Coastguard Worker 
1161*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(!dimensions.isEmpty());
1162*c8dee2aaSAndroid Build Coastguard Worker 
1163*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(dawnSpec.getViewFormat() != wgpu::TextureFormat::Undefined);
1164*c8dee2aaSAndroid Build Coastguard Worker     uint32_t formatKey = static_cast<uint32_t>(dawnSpec.getViewFormat());
1165*c8dee2aaSAndroid Build Coastguard Worker 
1166*c8dee2aaSAndroid Build Coastguard Worker     uint32_t samplesKey = SamplesToKey(info.numSamples());
1167*c8dee2aaSAndroid Build Coastguard Worker     // We don't have to key the number of mip levels because it is inherit in the combination of
1168*c8dee2aaSAndroid Build Coastguard Worker     // isMipped and dimensions.
1169*c8dee2aaSAndroid Build Coastguard Worker     bool isMipped = info.mipmapped() == Mipmapped::kYes;
1170*c8dee2aaSAndroid Build Coastguard Worker 
1171*c8dee2aaSAndroid Build Coastguard Worker     // Confirm all the below parts of the key can fit in a single uint32_t. The sum of the shift
1172*c8dee2aaSAndroid Build Coastguard Worker     // amounts in the asserts must be less than or equal to 32.
1173*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(samplesKey                             < (1u << 3));  // sample key is first 3 bits
1174*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(isMipped)        < (1u << 1));  // isMapped is 4th bit
1175*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(static_cast<uint32_t>(dawnSpec.fUsage) < (1u << 28)); // usage is remaining 28 bits
1176*c8dee2aaSAndroid Build Coastguard Worker 
1177*c8dee2aaSAndroid Build Coastguard Worker     // We need two uint32_ts for dimensions, 1 for format, and 1 for the rest of the key;
1178*c8dee2aaSAndroid Build Coastguard Worker     int num32DataCnt = 2 + 1 + 1;
1179*c8dee2aaSAndroid Build Coastguard Worker     bool hasYcbcrInfo = false;
1180*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
1181*c8dee2aaSAndroid Build Coastguard Worker     // If we are using ycbcr texture/sampling, more key information is needed.
1182*c8dee2aaSAndroid Build Coastguard Worker     if ((hasYcbcrInfo = ycbcrUtils::DawnDescriptorIsValid(dawnSpec.fYcbcrVkDescriptor))) {
1183*c8dee2aaSAndroid Build Coastguard Worker         num32DataCnt += ycbcrUtils::DawnDescriptorUsesExternalFormat(dawnSpec.fYcbcrVkDescriptor)
1184*c8dee2aaSAndroid Build Coastguard Worker                 ? SamplerDesc::kInt32sNeededExternalFormat
1185*c8dee2aaSAndroid Build Coastguard Worker                 : SamplerDesc::kInt32sNeededKnownFormat;
1186*c8dee2aaSAndroid Build Coastguard Worker     }
1187*c8dee2aaSAndroid Build Coastguard Worker #endif
1188*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey::Builder builder(key, type, num32DataCnt, shareable);
1189*c8dee2aaSAndroid Build Coastguard Worker 
1190*c8dee2aaSAndroid Build Coastguard Worker     builder[0] = dimensions.width();
1191*c8dee2aaSAndroid Build Coastguard Worker     builder[1] = dimensions.height();
1192*c8dee2aaSAndroid Build Coastguard Worker     builder[2] = formatKey;
1193*c8dee2aaSAndroid Build Coastguard Worker     builder[3] = (samplesKey                                   << 0) |
1194*c8dee2aaSAndroid Build Coastguard Worker                  (static_cast<uint32_t>(isMipped)              << 3) |
1195*c8dee2aaSAndroid Build Coastguard Worker                  (static_cast<uint32_t>(dawnSpec.fUsage)       << 4);
1196*c8dee2aaSAndroid Build Coastguard Worker 
1197*c8dee2aaSAndroid Build Coastguard Worker #if !defined(__EMSCRIPTEN__)
1198*c8dee2aaSAndroid Build Coastguard Worker     if (hasYcbcrInfo) {
1199*c8dee2aaSAndroid Build Coastguard Worker         builder[4] = non_format_info_as_uint32(dawnSpec.fYcbcrVkDescriptor);
1200*c8dee2aaSAndroid Build Coastguard Worker         // Even though we already have formatKey appended to the texture key, we still need to add
1201*c8dee2aaSAndroid Build Coastguard Worker         // fYcbcrVkDescriptor's vkFormat or externalFormat. The latter two are distinct from
1202*c8dee2aaSAndroid Build Coastguard Worker         // dawnSpec's wgpu::TextureFormat.
1203*c8dee2aaSAndroid Build Coastguard Worker         if (!ycbcrUtils::DawnDescriptorUsesExternalFormat(dawnSpec.fYcbcrVkDescriptor)) {
1204*c8dee2aaSAndroid Build Coastguard Worker             builder[5] = dawnSpec.fYcbcrVkDescriptor.vkFormat;
1205*c8dee2aaSAndroid Build Coastguard Worker         } else {
1206*c8dee2aaSAndroid Build Coastguard Worker             builder[5] = (uint32_t)(dawnSpec.fYcbcrVkDescriptor.externalFormat >> 32);
1207*c8dee2aaSAndroid Build Coastguard Worker             builder[6] = (uint32_t)dawnSpec.fYcbcrVkDescriptor.externalFormat;
1208*c8dee2aaSAndroid Build Coastguard Worker         }
1209*c8dee2aaSAndroid Build Coastguard Worker     }
1210*c8dee2aaSAndroid Build Coastguard Worker #endif
1211*c8dee2aaSAndroid Build Coastguard Worker }
1212*c8dee2aaSAndroid Build Coastguard Worker 
makeSamplerKey(const SamplerDesc & samplerDesc) const1213*c8dee2aaSAndroid Build Coastguard Worker GraphiteResourceKey DawnCaps::makeSamplerKey(const SamplerDesc& samplerDesc) const {
1214*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey samplerKey;
1215*c8dee2aaSAndroid Build Coastguard Worker     const SkSpan<const uint32_t>& samplerData = samplerDesc.asSpan();
1216*c8dee2aaSAndroid Build Coastguard Worker     static const ResourceType kSamplerType = GraphiteResourceKey::GenerateResourceType();
1217*c8dee2aaSAndroid Build Coastguard Worker     // Non-format ycbcr and sampler information are guaranteed to fit within one uint32, so the size
1218*c8dee2aaSAndroid Build Coastguard Worker     // of the returned span accurately captures the quantity of uint32s needed whether the sampler
1219*c8dee2aaSAndroid Build Coastguard Worker     // is immutable or not.
1220*c8dee2aaSAndroid Build Coastguard Worker     GraphiteResourceKey::Builder builder(&samplerKey, kSamplerType, samplerData.size(),
1221*c8dee2aaSAndroid Build Coastguard Worker                                          Shareable::kYes);
1222*c8dee2aaSAndroid Build Coastguard Worker 
1223*c8dee2aaSAndroid Build Coastguard Worker     for (size_t i = 0; i < samplerData.size(); i++) {
1224*c8dee2aaSAndroid Build Coastguard Worker         builder[i] = samplerData[i];
1225*c8dee2aaSAndroid Build Coastguard Worker     }
1226*c8dee2aaSAndroid Build Coastguard Worker     builder.finish();
1227*c8dee2aaSAndroid Build Coastguard Worker     return samplerKey;
1228*c8dee2aaSAndroid Build Coastguard Worker }
1229*c8dee2aaSAndroid Build Coastguard Worker 
1230*c8dee2aaSAndroid Build Coastguard Worker } // namespace skgpu::graphite
1231