Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
DawnGraphicsPipeline.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2022 Google LLC
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
9
12#include "src/gpu/Swizzle.h"
27#include "src/sksl/SkSLUtil.h"
29
30#include <vector>
31
32namespace skgpu::graphite {
33
34namespace {
35
36inline wgpu::VertexFormat attribute_type_to_dawn(VertexAttribType type) {
37 switch (type) {
39 return wgpu::VertexFormat::Float32;
41 return wgpu::VertexFormat::Float32x2;
43 return wgpu::VertexFormat::Float32x3;
45 return wgpu::VertexFormat::Float32x4;
47 return wgpu::VertexFormat::Undefined;
49 return wgpu::VertexFormat::Float16x2;
51 return wgpu::VertexFormat::Float16x4;
53 return wgpu::VertexFormat::Sint32x2;
55 return wgpu::VertexFormat::Sint32x3;
57 return wgpu::VertexFormat::Sint32x4;
59 return wgpu::VertexFormat::Undefined;
61 return wgpu::VertexFormat::Sint8x2;
63 return wgpu::VertexFormat::Sint8x4;
65 return wgpu::VertexFormat::Undefined;
67 return wgpu::VertexFormat::Uint8x2;
69 return wgpu::VertexFormat::Uint8x4;
71 return wgpu::VertexFormat::Undefined;
73 return wgpu::VertexFormat::Unorm8x4;
75 return wgpu::VertexFormat::Sint16x2;
77 return wgpu::VertexFormat::Sint16x4;
79 return wgpu::VertexFormat::Uint16x2;
81 return wgpu::VertexFormat::Unorm16x2;
83 return wgpu::VertexFormat::Sint32;
85 return wgpu::VertexFormat::Uint32;
87 return wgpu::VertexFormat::Undefined;
89 return wgpu::VertexFormat::Unorm16x4;
90 }
92}
93
94wgpu::CompareFunction compare_op_to_dawn(CompareOp op) {
95 switch (op) {
97 return wgpu::CompareFunction::Always;
99 return wgpu::CompareFunction::Never;
101 return wgpu::CompareFunction::Greater;
103 return wgpu::CompareFunction::GreaterEqual;
104 case CompareOp::kLess:
105 return wgpu::CompareFunction::Less;
107 return wgpu::CompareFunction::LessEqual;
109 return wgpu::CompareFunction::Equal;
111 return wgpu::CompareFunction::NotEqual;
112 }
114}
115
116wgpu::StencilOperation stencil_op_to_dawn(StencilOp op) {
117 switch (op) {
118 case StencilOp::kKeep:
119 return wgpu::StencilOperation::Keep;
120 case StencilOp::kZero:
121 return wgpu::StencilOperation::Zero;
123 return wgpu::StencilOperation::Replace;
125 return wgpu::StencilOperation::Invert;
127 return wgpu::StencilOperation::IncrementWrap;
129 return wgpu::StencilOperation::DecrementWrap;
131 return wgpu::StencilOperation::IncrementClamp;
133 return wgpu::StencilOperation::DecrementClamp;
134 }
136}
137
138wgpu::StencilFaceState stencil_face_to_dawn(DepthStencilSettings::Face face) {
139 wgpu::StencilFaceState state;
140 state.compare = compare_op_to_dawn(face.fCompareOp);
141 state.failOp = stencil_op_to_dawn(face.fStencilFailOp);
142 state.depthFailOp = stencil_op_to_dawn(face.fDepthFailOp);
143 state.passOp = stencil_op_to_dawn(face.fDepthStencilPassOp);
144 return state;
145}
146
147size_t create_vertex_attributes(SkSpan<const Attribute> attrs,
148 int shaderLocationOffset,
149 std::vector<wgpu::VertexAttribute>* out) {
150 SkASSERT(out && out->empty());
151 out->resize(attrs.size());
152 size_t vertexAttributeOffset = 0;
153 int attributeIndex = 0;
154 for (const auto& attr : attrs) {
155 wgpu::VertexAttribute& vertexAttribute = (*out)[attributeIndex];
156 vertexAttribute.format = attribute_type_to_dawn(attr.cpuType());
157 SkASSERT(vertexAttribute.format != wgpu::VertexFormat::Undefined);
158 vertexAttribute.offset = vertexAttributeOffset;
159 vertexAttribute.shaderLocation = shaderLocationOffset + attributeIndex;
160 vertexAttributeOffset += attr.sizeAlign4();
161 attributeIndex++;
162 }
163 return vertexAttributeOffset;
164}
165
166// TODO: share this w/ Ganesh dawn backend?
167static wgpu::BlendFactor blend_coeff_to_dawn_blend(const DawnCaps& caps, skgpu::BlendCoeff coeff) {
168#if defined(__EMSCRIPTEN__)
169#define VALUE_IF_DSB_OR_ZERO(VALUE) wgpu::BlendFactor::Zero
170#else
171#define VALUE_IF_DSB_OR_ZERO(VALUE) \
172 ((caps.shaderCaps()->fDualSourceBlendingSupport) ? (VALUE) : wgpu::BlendFactor::Zero)
173#endif
174 switch (coeff) {
176 return wgpu::BlendFactor::Zero;
178 return wgpu::BlendFactor::One;
180 return wgpu::BlendFactor::Src;
182 return wgpu::BlendFactor::OneMinusSrc;
184 return wgpu::BlendFactor::Dst;
186 return wgpu::BlendFactor::OneMinusDst;
188 return wgpu::BlendFactor::SrcAlpha;
190 return wgpu::BlendFactor::OneMinusSrcAlpha;
192 return wgpu::BlendFactor::DstAlpha;
194 return wgpu::BlendFactor::OneMinusDstAlpha;
196 return wgpu::BlendFactor::Constant;
198 return wgpu::BlendFactor::OneMinusConstant;
200 return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::Src1);
202 return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::OneMinusSrc1);
204 return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::Src1Alpha);
206 return VALUE_IF_DSB_OR_ZERO(wgpu::BlendFactor::OneMinusSrc1Alpha);
208 return wgpu::BlendFactor::Zero;
209 }
211#undef VALUE_IF_DSB_OR_ZERO
212}
213
214static wgpu::BlendFactor blend_coeff_to_dawn_blend_for_alpha(const DawnCaps& caps,
215 skgpu::BlendCoeff coeff) {
216 switch (coeff) {
217 // Force all srcColor used in alpha slot to alpha version.
219 return wgpu::BlendFactor::SrcAlpha;
221 return wgpu::BlendFactor::OneMinusSrcAlpha;
223 return wgpu::BlendFactor::DstAlpha;
225 return wgpu::BlendFactor::OneMinusDstAlpha;
226 default:
227 return blend_coeff_to_dawn_blend(caps, coeff);
228 }
229}
230
231// TODO: share this w/ Ganesh Metal backend?
232static wgpu::BlendOperation blend_equation_to_dawn_blend_op(skgpu::BlendEquation equation) {
233 static const wgpu::BlendOperation gTable[] = {
234 wgpu::BlendOperation::Add, // skgpu::BlendEquation::kAdd
235 wgpu::BlendOperation::Subtract, // skgpu::BlendEquation::kSubtract
236 wgpu::BlendOperation::ReverseSubtract, // skgpu::BlendEquation::kReverseSubtract
237 };
238 static_assert(std::size(gTable) == (int)skgpu::BlendEquation::kFirstAdvanced);
239 static_assert(0 == (int)skgpu::BlendEquation::kAdd);
240 static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
241 static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
242
243 SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
244 return gTable[(int)equation];
245}
246
247} // anonymous namespace
248
249// static
251 DawnResourceProvider* resourceProvider,
252 const RuntimeEffectDictionary* runtimeDict,
253 const GraphicsPipelineDesc& pipelineDesc,
254 const RenderPassDesc& renderPassDesc) {
255 const DawnCaps& caps = *static_cast<const DawnCaps*>(sharedContext->caps());
256 const auto& device = sharedContext->device();
257
258 SkSL::Program::Interface vsInterface, fsInterface;
259 SkSL::ProgramSettings settings;
260
261 settings.fForceNoRTFlip = true;
262
263 ShaderErrorHandler* errorHandler = caps.shaderErrorHandler();
264
266 const bool useStorageBuffers = caps.storageBufferPreferred();
267
268 std::string vsCode, fsCode;
269 wgpu::ShaderModule fsModule, vsModule;
270
271 // Some steps just render depth buffer but not color buffer, so the fragment
272 // shader is null.
273 UniquePaintParamsID paintID = pipelineDesc.paintParamsID();
274 FragSkSLInfo fsSkSLInfo = BuildFragmentSkSL(&caps,
276 runtimeDict,
277 step,
278 paintID,
279 useStorageBuffers,
280 renderPassDesc.fWriteSwizzle);
281 std::string& fsSkSL = fsSkSLInfo.fSkSL;
282 const BlendInfo& blendInfo = fsSkSLInfo.fBlendInfo;
283 const bool localCoordsNeeded = fsSkSLInfo.fRequiresLocalCoords;
284 const int numTexturesAndSamplers = fsSkSLInfo.fNumTexturesAndSamplers;
285
286 bool hasFragmentSkSL = !fsSkSL.empty();
287 if (hasFragmentSkSL) {
288 if (!skgpu::SkSLToWGSL(caps.shaderCaps(),
289 fsSkSL,
291 settings,
292 &fsCode,
293 &fsInterface,
294 errorHandler)) {
295 return {};
296 }
297 if (!DawnCompileWGSLShaderModule(sharedContext, fsSkSLInfo.fLabel.c_str(), fsCode,
298 &fsModule, errorHandler)) {
299 return {};
300 }
301 }
302
304 step,
305 useStorageBuffers,
306 localCoordsNeeded);
307 const std::string& vsSkSL = vsSkSLInfo.fSkSL;
308 if (!skgpu::SkSLToWGSL(caps.shaderCaps(),
309 vsSkSL,
311 settings,
312 &vsCode,
313 &vsInterface,
314 errorHandler)) {
315 return {};
316 }
317 if (!DawnCompileWGSLShaderModule(sharedContext, vsSkSLInfo.fLabel.c_str(), vsCode,
318 &vsModule, errorHandler)) {
319 return {};
320 }
321
322 std::string pipelineLabel =
323 GetPipelineLabel(sharedContext->shaderCodeDictionary(), renderPassDesc, step, paintID);
324 wgpu::RenderPipelineDescriptor descriptor;
325 descriptor.label = pipelineLabel.c_str();
326
327 // Fragment state
328 skgpu::BlendEquation equation = blendInfo.fEquation;
329 skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
330 skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
331 bool blendOn = !skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
332
333 wgpu::BlendState blend;
334 if (blendOn) {
335 blend.color.operation = blend_equation_to_dawn_blend_op(equation);
336 blend.color.srcFactor = blend_coeff_to_dawn_blend(caps, srcCoeff);
337 blend.color.dstFactor = blend_coeff_to_dawn_blend(caps, dstCoeff);
338 blend.alpha.operation = blend_equation_to_dawn_blend_op(equation);
339 blend.alpha.srcFactor = blend_coeff_to_dawn_blend_for_alpha(caps, srcCoeff);
340 blend.alpha.dstFactor = blend_coeff_to_dawn_blend_for_alpha(caps, dstCoeff);
341 }
342
343 wgpu::ColorTargetState colorTarget;
344 colorTarget.format =
345 renderPassDesc.fColorAttachment.fTextureInfo.dawnTextureSpec().getViewFormat();
346 colorTarget.blend = blendOn ? &blend : nullptr;
347 colorTarget.writeMask = blendInfo.fWritesColor && hasFragmentSkSL ? wgpu::ColorWriteMask::All
348 : wgpu::ColorWriteMask::None;
349
350 wgpu::FragmentState fragment;
351 // Dawn doesn't allow having a color attachment but without fragment shader, so have to use a
352 // noop fragment shader, if fragment shader is null.
353 fragment.module = hasFragmentSkSL ? std::move(fsModule) : sharedContext->noopFragment();
354 fragment.entryPoint = "main";
355 fragment.targetCount = 1;
356 fragment.targets = &colorTarget;
357 descriptor.fragment = &fragment;
358
359 // Depth stencil state
360 const auto& depthStencilSettings = step->depthStencilSettings();
361 SkASSERT(depthStencilSettings.fDepthTestEnabled ||
362 depthStencilSettings.fDepthCompareOp == CompareOp::kAlways);
363 wgpu::DepthStencilState depthStencil;
364 if (renderPassDesc.fDepthStencilAttachment.fTextureInfo.isValid()) {
365 wgpu::TextureFormat dsFormat =
366 renderPassDesc.fDepthStencilAttachment.fTextureInfo.dawnTextureSpec()
367 .getViewFormat();
368 depthStencil.format =
369 DawnFormatIsDepthOrStencil(dsFormat) ? dsFormat : wgpu::TextureFormat::Undefined;
370 if (depthStencilSettings.fDepthTestEnabled) {
371 depthStencil.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
372 }
373 depthStencil.depthCompare = compare_op_to_dawn(depthStencilSettings.fDepthCompareOp);
374
375 // Dawn validation fails if the stencil state is non-default and the
376 // format doesn't have the stencil aspect.
377 if (DawnFormatIsStencil(dsFormat) && depthStencilSettings.fStencilTestEnabled) {
378 depthStencil.stencilFront = stencil_face_to_dawn(depthStencilSettings.fFrontStencil);
379 depthStencil.stencilBack = stencil_face_to_dawn(depthStencilSettings.fBackStencil);
380 depthStencil.stencilReadMask = depthStencilSettings.fFrontStencil.fReadMask;
381 depthStencil.stencilWriteMask = depthStencilSettings.fFrontStencil.fWriteMask;
382 }
383
384 descriptor.depthStencil = &depthStencil;
385 }
386
387 // Pipeline layout
388 BindGroupLayouts groupLayouts;
389 {
390 groupLayouts[0] = resourceProvider->getOrCreateUniformBuffersBindGroupLayout();
391 if (!groupLayouts[0]) {
392 return {};
393 }
394
395 bool hasFragmentSamplers = hasFragmentSkSL && numTexturesAndSamplers > 0;
396 if (hasFragmentSamplers) {
397 if (numTexturesAndSamplers == 2) {
398 // Common case: single texture + sampler.
399 groupLayouts[1] =
401 } else {
402 std::vector<wgpu::BindGroupLayoutEntry> entries(numTexturesAndSamplers);
403 for (int i = 0; i < numTexturesAndSamplers;) {
404 entries[i].binding = static_cast<uint32_t>(i);
405 entries[i].visibility = wgpu::ShaderStage::Fragment;
406 entries[i].sampler.type = wgpu::SamplerBindingType::Filtering;
407 ++i;
408 entries[i].binding = i;
409 entries[i].visibility = wgpu::ShaderStage::Fragment;
410 entries[i].texture.sampleType = wgpu::TextureSampleType::Float;
411 entries[i].texture.viewDimension = wgpu::TextureViewDimension::e2D;
412 entries[i].texture.multisampled = false;
413 ++i;
414 }
415
416 wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
417#if defined(SK_DEBUG)
418 groupLayoutDesc.label = vsSkSLInfo.fLabel.c_str();
419#endif
420 groupLayoutDesc.entryCount = entries.size();
421 groupLayoutDesc.entries = entries.data();
422 groupLayouts[1] = device.CreateBindGroupLayout(&groupLayoutDesc);
423 }
424 if (!groupLayouts[1]) {
425 return {};
426 }
427 }
428
429 wgpu::PipelineLayoutDescriptor layoutDesc;
430#if defined(SK_DEBUG)
431 layoutDesc.label = fsSkSLInfo.fLabel.c_str();
432#endif
433 layoutDesc.bindGroupLayoutCount =
434 hasFragmentSamplers ? groupLayouts.size() : groupLayouts.size() - 1;
435 layoutDesc.bindGroupLayouts = groupLayouts.data();
436 auto layout = device.CreatePipelineLayout(&layoutDesc);
437 if (!layout) {
438 return {};
439 }
440 descriptor.layout = std::move(layout);
441 }
442
443 // Vertex state
444 std::array<wgpu::VertexBufferLayout, kNumVertexBuffers> vertexBufferLayouts;
445 // Vertex buffer layout
446 std::vector<wgpu::VertexAttribute> vertexAttributes;
447 {
448 auto arrayStride = create_vertex_attributes(step->vertexAttributes(),
449 0,
450 &vertexAttributes);
451 auto& layout = vertexBufferLayouts[kVertexBufferIndex];
452 if (arrayStride) {
453 layout.arrayStride = arrayStride;
454 layout.stepMode = wgpu::VertexStepMode::Vertex;
455 layout.attributeCount = vertexAttributes.size();
456 layout.attributes = vertexAttributes.data();
457 } else {
458 layout.arrayStride = 0;
459 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
460 layout.attributeCount = 0;
461 layout.attributes = nullptr;
462 }
463 }
464
465 // Instance buffer layout
466 std::vector<wgpu::VertexAttribute> instanceAttributes;
467 {
468 auto arrayStride = create_vertex_attributes(step->instanceAttributes(),
469 step->vertexAttributes().size(),
470 &instanceAttributes);
471 auto& layout = vertexBufferLayouts[kInstanceBufferIndex];
472 if (arrayStride) {
473 layout.arrayStride = arrayStride;
474 layout.stepMode = wgpu::VertexStepMode::Instance;
475 layout.attributeCount = instanceAttributes.size();
476 layout.attributes = instanceAttributes.data();
477 } else {
478 layout.arrayStride = 0;
479 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
480 layout.attributeCount = 0;
481 layout.attributes = nullptr;
482 }
483 }
484
485 auto& vertex = descriptor.vertex;
486 vertex.module = std::move(vsModule);
487 vertex.entryPoint = "main";
488 vertex.constantCount = 0;
489 vertex.constants = nullptr;
490 vertex.bufferCount = vertexBufferLayouts.size();
491 vertex.buffers = vertexBufferLayouts.data();
492
493 // Other state
494 descriptor.primitive.frontFace = wgpu::FrontFace::CCW;
495 descriptor.primitive.cullMode = wgpu::CullMode::None;
496 switch(step->primitiveType()) {
498 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
499 break;
501 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
502 descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Uint16;
503 break;
505 descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
506 break;
507 }
508
509 // Multisampled state
510 descriptor.multisample.count = renderPassDesc.fSampleCount;
511 [[maybe_unused]] bool isMSAARenderToSingleSampled =
512 renderPassDesc.fSampleCount > 1 &&
513 renderPassDesc.fColorAttachment.fTextureInfo.isValid() &&
514 renderPassDesc.fColorAttachment.fTextureInfo.numSamples() == 1;
515#if defined(__EMSCRIPTEN__)
516 SkASSERT(!isMSAARenderToSingleSampled);
517#else
518 wgpu::DawnMultisampleStateRenderToSingleSampled pipelineMSAARenderToSingleSampledDesc;
519 if (isMSAARenderToSingleSampled) {
520 // If render pass is multi sampled but the color attachment is single sampled, we need
521 // to activate multisampled render to single sampled feature for this graphics pipeline.
522 SkASSERT(device.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled));
523
524 descriptor.multisample.nextInChain = &pipelineMSAARenderToSingleSampledDesc;
525 pipelineMSAARenderToSingleSampledDesc.enabled = true;
526 }
527#endif
528
529 descriptor.multisample.mask = 0xFFFFFFFF;
530 descriptor.multisample.alphaToCoverageEnabled = false;
531
532 auto asyncCreation = std::make_unique<AsyncPipelineCreation>(sharedContext);
533
534 if (caps.useAsyncPipelineCreation()) {
535 device.CreateRenderPipelineAsync(
536 &descriptor,
537 [](WGPUCreatePipelineAsyncStatus status,
538 WGPURenderPipeline pipeline,
539 char const* message,
540 void* userdata) {
541 AsyncPipelineCreation* arg = static_cast<AsyncPipelineCreation*>(userdata);
542
543 if (status != WGPUCreatePipelineAsyncStatus_Success) {
544 SKGPU_LOG_E("Failed to create render pipeline (%d): %s", status, message);
545 arg->set(nullptr);
546 } else {
547 arg->set(wgpu::RenderPipeline::Acquire(pipeline));
548 }
549 },
550 asyncCreation.get());
551 } else {
552 asyncCreation->set(device.CreateRenderPipeline(&descriptor));
553 }
554#if defined(GRAPHITE_TEST_UTILS)
555 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.renderStepID(),
556 pipelineDesc.paintParamsID(),
557 std::move(vsSkSL),
558 std::move(fsSkSL),
559 std::move(vsCode),
560 std::move(fsCode)};
561 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
562#else
563 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = nullptr;
564#endif
565
568 pipelineInfoPtr,
569 std::move(asyncCreation),
570 std::move(groupLayouts),
571 step->primitiveType(),
572 depthStencilSettings.fStencilReferenceValue,
573 /*hasStepUniforms=*/!step->uniforms().empty(),
574 /*hasPaintUniforms=*/fsSkSLInfo.fNumPaintUniforms > 0,
576}
577
578DawnGraphicsPipeline::DawnGraphicsPipeline(const skgpu::graphite::SharedContext* sharedContext,
579 PipelineInfo* pipelineInfo,
580 std::unique_ptr<AsyncPipelineCreation> asyncCreationInfo,
581 BindGroupLayouts groupLayouts,
582 PrimitiveType primitiveType,
583 uint32_t refValue,
584 bool hasStepUniforms,
585 bool hasPaintUniforms,
586 int numFragmentTexturesAndSamplers)
587 : GraphicsPipeline(sharedContext, pipelineInfo)
588 , fAsyncPipelineCreation(std::move(asyncCreationInfo))
589 , fGroupLayouts(std::move(groupLayouts))
590 , fPrimitiveType(primitiveType)
591 , fStencilReferenceValue(refValue)
592 , fHasStepUniforms(hasStepUniforms)
593 , fHasPaintUniforms(hasPaintUniforms)
594 , fNumFragmentTexturesAndSamplers(numFragmentTexturesAndSamplers) {}
595
597 fAsyncPipelineCreation = nullptr;
598}
599
600const wgpu::RenderPipeline& DawnGraphicsPipeline::dawnRenderPipeline() const {
601 if (auto pipeline = fAsyncPipelineCreation->getIfReady()) {
602 return *pipeline;
603 }
604 return fAsyncPipelineCreation->waitAndGet();
605}
606
607} // namespace skgpu::graphite
static int step(int x, SkScalar min, SkScalar max)
Definition BlurTest.cpp:215
#define VALUE_IF_DSB_OR_ZERO(VALUE)
#define SKGPU_LOG_E(fmt,...)
Definition Log.h:38
#define SkUNREACHABLE
Definition SkAssert.h:135
#define SkASSERT(cond)
Definition SkAssert.h:116
Type::kYUV Type::kRGBA() int(0.7 *637)
constexpr size_t size() const
Definition SkSpan_impl.h:95
skgpu::ShaderErrorHandler * shaderErrorHandler() const
Definition Caps.h:266
const ResourceBindingRequirements & resourceBindingRequirements() const
Definition Caps.h:143
bool storageBufferPreferred() const
Definition Caps.h:232
const SkSL::ShaderCaps * shaderCaps() const
Definition Caps.h:74
bool useAsyncPipelineCreation() const
Definition DawnCaps.h:27
std::array< wgpu::BindGroupLayout, kBindGroupCount > BindGroupLayouts
const wgpu::RenderPipeline & dawnRenderPipeline() const
static constexpr unsigned int kInstanceBufferIndex
static sk_sp< DawnGraphicsPipeline > Make(const DawnSharedContext *sharedContext, DawnResourceProvider *resourceProvider, const RuntimeEffectDictionary *runtimeDict, const GraphicsPipelineDesc &pipelineDesc, const RenderPassDesc &renderPassDesc)
static constexpr unsigned int kVertexBufferIndex
const wgpu::BindGroupLayout & getOrCreateSingleTextureSamplerBindGroupLayout()
const wgpu::BindGroupLayout & getOrCreateUniformBuffersBindGroupLayout()
UniquePaintParamsID paintParamsID() const
const RenderStep * lookup(uint32_t uniqueID) const
const SharedContext * sharedContext() const
Definition Resource.h:187
const Caps * caps() const
ShaderCodeDictionary * shaderCodeDictionary()
const RendererProvider * rendererProvider() const
uint32_t numSamples() const
Definition TextureInfo.h:78
VkDevice device
Definition main.cc:53
AtkStateType state
static SkColor blend(SkColor dst, SkColor src, void(*mode)(float, float, float, float *, float *, float *))
Definition hsl.cpp:142
Win32Message message
VertSkSLInfo BuildVertexSkSL(const ResourceBindingRequirements &bindingReqs, const RenderStep *step, bool useStorageBuffers, bool defineLocalCoordsVarying)
bool DawnFormatIsDepthOrStencil(wgpu::TextureFormat format)
FragSkSLInfo BuildFragmentSkSL(const Caps *caps, const ShaderCodeDictionary *dict, const RuntimeEffectDictionary *rteDict, const RenderStep *step, UniquePaintParamsID paintID, bool useStorageBuffers, skgpu::Swizzle writeSwizzle)
std::string GetPipelineLabel(const ShaderCodeDictionary *dict, const RenderPassDesc &renderPassDesc, const RenderStep *renderStep, UniquePaintParamsID paintID)
bool DawnCompileWGSLShaderModule(const DawnSharedContext *sharedContext, const char *label, const std::string &wgsl, wgpu::ShaderModule *module, ShaderErrorHandler *errorHandler)
bool DawnFormatIsStencil(wgpu::TextureFormat format)
static constexpr bool BlendShouldDisable(BlendEquation equation, BlendCoeff srcCoeff, BlendCoeff dstCoeff)
Definition Blend.h:145
static const int kBlendEquationCnt
Definition Blend.h:55
BlendEquation
Definition Blend.h:26
BlendCoeff
Definition Blend.h:60
bool SkSLToWGSL(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *wgsl, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
Definition ref_ptr.h:256
skgpu::BlendCoeff fDstBlend
Definition Blend.h:96
bool fWritesColor
Definition Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition Blend.h:95