39 return wgpu::VertexFormat::Float32;
41 return wgpu::VertexFormat::Float32x2;
43 return wgpu::VertexFormat::Float32x3;
45 return wgpu::VertexFormat::Float32x4;
47 return wgpu::VertexFormat::Float16x2;
49 return wgpu::VertexFormat::Float16x4;
51 return wgpu::VertexFormat::Sint32x2;
53 return wgpu::VertexFormat::Sint32x3;
55 return wgpu::VertexFormat::Sint32x4;
57 return wgpu::VertexFormat::Sint8x2;
59 return wgpu::VertexFormat::Sint8x4;
61 return wgpu::VertexFormat::Uint8x2;
63 return wgpu::VertexFormat::Uint8x4;
65 return wgpu::VertexFormat::Unorm8x4;
67 return wgpu::VertexFormat::Sint16x2;
69 return wgpu::VertexFormat::Sint16x4;
71 return wgpu::VertexFormat::Uint16x2;
73 return wgpu::VertexFormat::Unorm16x2;
75 return wgpu::VertexFormat::Sint32;
77 return wgpu::VertexFormat::Uint32;
79 return wgpu::VertexFormat::Unorm16x4;
94 return wgpu::CompareFunction::Always;
96 return wgpu::CompareFunction::Never;
98 return wgpu::CompareFunction::Greater;
100 return wgpu::CompareFunction::GreaterEqual;
102 return wgpu::CompareFunction::Less;
104 return wgpu::CompareFunction::LessEqual;
106 return wgpu::CompareFunction::Equal;
108 return wgpu::CompareFunction::NotEqual;
116 return wgpu::StencilOperation::Keep;
118 return wgpu::StencilOperation::Zero;
120 return wgpu::StencilOperation::Replace;
122 return wgpu::StencilOperation::Invert;
124 return wgpu::StencilOperation::IncrementWrap;
126 return wgpu::StencilOperation::DecrementWrap;
128 return wgpu::StencilOperation::IncrementClamp;
130 return wgpu::StencilOperation::DecrementClamp;
135wgpu::StencilFaceState stencil_face_to_dawn(DepthStencilSettings::Face face) {
136 wgpu::StencilFaceState
state;
137 state.compare = compare_op_to_dawn(face.fCompareOp);
138 state.failOp = stencil_op_to_dawn(face.fStencilFailOp);
139 state.depthFailOp = stencil_op_to_dawn(face.fDepthFailOp);
140 state.passOp = stencil_op_to_dawn(face.fDepthStencilPassOp);
145 int shaderLocationOffset,
146 std::vector<wgpu::VertexAttribute>*
out) {
149 size_t vertexAttributeOffset = 0;
150 int attributeIndex = 0;
151 for (
const auto& attr : attrs) {
152 wgpu::VertexAttribute& vertexAttribute = (*out)[attributeIndex];
153 vertexAttribute.format = attribute_type_to_dawn(attr.cpuType());
154 vertexAttribute.offset = vertexAttributeOffset;
155 vertexAttribute.shaderLocation = shaderLocationOffset + attributeIndex;
156 vertexAttributeOffset += attr.sizeAlign4();
159 return vertexAttributeOffset;
164#if defined(__EMSCRIPTEN__)
165#define VALUE_IF_DSB_OR_ZERO(VALUE) wgpu::BlendFactor::Zero
167#define VALUE_IF_DSB_OR_ZERO(VALUE) \
168 ((caps.shaderCaps()->fDualSourceBlendingSupport) ? (VALUE) : wgpu::BlendFactor::Zero)
172 return wgpu::BlendFactor::Zero;
174 return wgpu::BlendFactor::One;
176 return wgpu::BlendFactor::Src;
178 return wgpu::BlendFactor::OneMinusSrc;
180 return wgpu::BlendFactor::Dst;
182 return wgpu::BlendFactor::OneMinusDst;
184 return wgpu::BlendFactor::SrcAlpha;
186 return wgpu::BlendFactor::OneMinusSrcAlpha;
188 return wgpu::BlendFactor::DstAlpha;
190 return wgpu::BlendFactor::OneMinusDstAlpha;
192 return wgpu::BlendFactor::Constant;
194 return wgpu::BlendFactor::OneMinusConstant;
204 return wgpu::BlendFactor::Zero;
207#undef VALUE_IF_DSB_OR_ZERO
210static wgpu::BlendFactor blend_coeff_to_dawn_blend_for_alpha(
const DawnCaps& caps,
215 return wgpu::BlendFactor::SrcAlpha;
217 return wgpu::BlendFactor::OneMinusSrcAlpha;
219 return wgpu::BlendFactor::DstAlpha;
221 return wgpu::BlendFactor::OneMinusDstAlpha;
223 return blend_coeff_to_dawn_blend(caps, coeff);
230 wgpu::BlendOperation::Add,
231 wgpu::BlendOperation::Subtract,
232 wgpu::BlendOperation::ReverseSubtract,
240 return gTable[(
int)equation];
243struct AsyncPipelineCreationBase {
250#if defined(__EMSCRIPTEN__)
252struct DawnGraphicsPipeline::AsyncPipelineCreation :
public AsyncPipelineCreationBase {};
278 std::string vsCode, fsCode;
279 wgpu::ShaderModule fsModule, vsModule;
291 std::string& fsSkSL = fsSkSLInfo.
fSkSL;
296 bool hasFragmentSkSL = !fsSkSL.empty();
297 if (hasFragmentSkSL) {
308 &fsModule, errorHandler)) {
317 const std::string& vsSkSL = vsSkSLInfo.
fSkSL;
328 &vsModule, errorHandler)) {
332 std::string pipelineLabel =
334 wgpu::RenderPipelineDescriptor descriptor;
336 descriptor.label = pipelineLabel.c_str();
344 wgpu::BlendState
blend;
346 blend.color.operation = blend_equation_to_dawn_blend_op(equation);
347 blend.color.srcFactor = blend_coeff_to_dawn_blend(caps, srcCoeff);
348 blend.color.dstFactor = blend_coeff_to_dawn_blend(caps, dstCoeff);
349 blend.alpha.operation = blend_equation_to_dawn_blend_op(equation);
350 blend.alpha.srcFactor = blend_coeff_to_dawn_blend_for_alpha(caps, srcCoeff);
351 blend.alpha.dstFactor = blend_coeff_to_dawn_blend_for_alpha(caps, dstCoeff);
354 wgpu::ColorTargetState colorTarget;
357 colorTarget.blend = blendOn ? &
blend :
nullptr;
358 colorTarget.writeMask = blendInfo.
fWritesColor && hasFragmentSkSL ? wgpu::ColorWriteMask::All
359 : wgpu::ColorWriteMask::None;
361#if !defined(__EMSCRIPTEN__)
362 const bool loadMsaaFromResolve =
367 wgpu::ColorTargetStateExpandResolveTextureDawn pipelineMSAALoadResolveTextureDesc;
368 if (loadMsaaFromResolve &&
sharedContext->dawnCaps()->resolveTextureLoadOp().has_value()) {
369 SkASSERT(
device.HasFeature(wgpu::FeatureName::DawnLoadResolveTexture));
370 colorTarget.nextInChain = &pipelineMSAALoadResolveTextureDesc;
371 pipelineMSAALoadResolveTextureDesc.enabled =
true;
375 wgpu::FragmentState fragment;
378 fragment.module = hasFragmentSkSL ? std::move(fsModule) :
sharedContext->noopFragment();
379 fragment.entryPoint =
"main";
380 fragment.targetCount = 1;
381 fragment.targets = &colorTarget;
382 descriptor.fragment = &fragment;
385 const auto& depthStencilSettings =
step->depthStencilSettings();
386 SkASSERT(depthStencilSettings.fDepthTestEnabled ||
388 wgpu::DepthStencilState depthStencil;
390 wgpu::TextureFormat dsFormat =
393 depthStencil.format =
395 if (depthStencilSettings.fDepthTestEnabled) {
396 depthStencil.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
398 depthStencil.depthCompare = compare_op_to_dawn(depthStencilSettings.fDepthCompareOp);
403 depthStencil.stencilFront = stencil_face_to_dawn(depthStencilSettings.fFrontStencil);
404 depthStencil.stencilBack = stencil_face_to_dawn(depthStencilSettings.fBackStencil);
405 depthStencil.stencilReadMask = depthStencilSettings.fFrontStencil.fReadMask;
406 depthStencil.stencilWriteMask = depthStencilSettings.fFrontStencil.fWriteMask;
409 descriptor.depthStencil = &depthStencil;
416 if (!groupLayouts[0]) {
421 if (hasFragmentSamplers) {
429 entries[
i].binding =
static_cast<uint32_t
>(
i);
430 entries[
i].visibility = wgpu::ShaderStage::Fragment;
431 entries[
i].sampler.type = wgpu::SamplerBindingType::Filtering;
433 entries[
i].binding =
i;
434 entries[
i].visibility = wgpu::ShaderStage::Fragment;
435 entries[
i].texture.sampleType = wgpu::TextureSampleType::Float;
436 entries[
i].texture.viewDimension = wgpu::TextureViewDimension::e2D;
437 entries[
i].texture.multisampled =
false;
441 wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
443 groupLayoutDesc.label = vsSkSLInfo.
fLabel.c_str();
445 groupLayoutDesc.entryCount = entries.size();
446 groupLayoutDesc.entries = entries.data();
447 groupLayouts[1] =
device.CreateBindGroupLayout(&groupLayoutDesc);
449 if (!groupLayouts[1]) {
454 wgpu::PipelineLayoutDescriptor layoutDesc;
456 layoutDesc.label = fsSkSLInfo.
fLabel.c_str();
458 layoutDesc.bindGroupLayoutCount =
459 hasFragmentSamplers ? groupLayouts.size() : groupLayouts.size() - 1;
460 layoutDesc.bindGroupLayouts = groupLayouts.data();
461 auto layout =
device.CreatePipelineLayout(&layoutDesc);
465 descriptor.layout = std::move(layout);
469 std::array<wgpu::VertexBufferLayout, kNumVertexBuffers> vertexBufferLayouts;
471 std::vector<wgpu::VertexAttribute> vertexAttributes;
473 auto arrayStride = create_vertex_attributes(
step->vertexAttributes(),
478 layout.arrayStride = arrayStride;
480 layout.attributeCount = vertexAttributes.size();
481 layout.attributes = vertexAttributes.data();
483 layout.arrayStride = 0;
484 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
485 layout.attributeCount = 0;
486 layout.attributes =
nullptr;
491 std::vector<wgpu::VertexAttribute> instanceAttributes;
493 auto arrayStride = create_vertex_attributes(
step->instanceAttributes(),
494 step->vertexAttributes().size(),
495 &instanceAttributes);
498 layout.arrayStride = arrayStride;
499 layout.stepMode = wgpu::VertexStepMode::Instance;
500 layout.attributeCount = instanceAttributes.size();
501 layout.attributes = instanceAttributes.data();
503 layout.arrayStride = 0;
504 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
505 layout.attributeCount = 0;
506 layout.attributes =
nullptr;
510 auto& vertex = descriptor.vertex;
511 vertex.module = std::move(vsModule);
512 vertex.entryPoint =
"main";
513 vertex.constantCount = 0;
514 vertex.constants =
nullptr;
515 vertex.bufferCount = vertexBufferLayouts.size();
516 vertex.buffers = vertexBufferLayouts.data();
519 descriptor.primitive.frontFace = wgpu::FrontFace::CCW;
520 descriptor.primitive.cullMode = wgpu::CullMode::None;
521 switch (
step->primitiveType()) {
523 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleList;
526 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
527 descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Uint16;
530 descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
535 descriptor.multisample.count = renderPassDesc.
fSampleCount;
536 descriptor.multisample.mask = 0xFFFFFFFF;
537 descriptor.multisample.alphaToCoverageEnabled =
false;
539 auto asyncCreation = std::make_unique<AsyncPipelineCreation>();
542#if defined(__EMSCRIPTEN__)
544 SKGPU_LOG_F(
"CreateRenderPipelineAsync shouldn't be used in WASM");
546 asyncCreation->fFuture =
device.CreateRenderPipelineAsync(
548 wgpu::CallbackMode::WaitAnyOnly,
549 [asyncCreationPtr = asyncCreation.get()](wgpu::CreatePipelineAsyncStatus status,
550 wgpu::RenderPipeline pipeline,
552 if (status != wgpu::CreatePipelineAsyncStatus::Success) {
553 SKGPU_LOG_E(
"Failed to create render pipeline (%d): %s",
554 static_cast<int>(status),
558 asyncCreationPtr->fRenderPipeline = nullptr;
560 asyncCreationPtr->fRenderPipeline = std::move(pipeline);
563 asyncCreationPtr->fFinished =
true;
567 std::optional<DawnErrorChecker> errorChecker;
568 if (sharedContext->dawnCaps()->allowScopedErrorChecks()) {
569 errorChecker.emplace(sharedContext);
571 asyncCreation->fRenderPipeline =
device.CreateRenderPipeline(&descriptor);
572 asyncCreation->fFinished =
true;
575 asyncCreation->fRenderPipeline =
nullptr;
578#if defined(GRAPHITE_TEST_UTILS)
579 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.renderStepID(),
580 pipelineDesc.paintParamsID(),
585 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
587 GraphicsPipeline::PipelineInfo* pipelineInfoPtr =
nullptr;
591 new DawnGraphicsPipeline(sharedContext,
593 std::move(asyncCreation),
594 std::move(groupLayouts),
595 step->primitiveType(),
596 depthStencilSettings.fStencilReferenceValue,
597 !
step->uniforms().empty(),
598 fsSkSLInfo.fNumPaintUniforms > 0,
599 fsSkSLInfo.fHasGradientBuffer,
600 numTexturesAndSamplers));
604 PipelineInfo* pipelineInfo,
605 std::unique_ptr<AsyncPipelineCreation> asyncCreationInfo,
606 BindGroupLayouts groupLayouts,
609 bool hasStepUniforms,
610 bool hasPaintUniforms,
611 bool hasGradientBuffer,
612 int numFragmentTexturesAndSamplers)
613 : GraphicsPipeline(sharedContext, pipelineInfo)
614 , fAsyncPipelineCreation(
std::move(asyncCreationInfo))
615 , fGroupLayouts(
std::move(groupLayouts))
616 , fPrimitiveType(primitiveType)
617 , fStencilReferenceValue(refValue)
618 , fHasStepUniforms(hasStepUniforms)
619 , fHasPaintUniforms(hasPaintUniforms)
620 , fHasGradientBuffer(hasGradientBuffer)
621 , fNumFragmentTexturesAndSamplers(numFragmentTexturesAndSamplers) {}
627void DawnGraphicsPipeline::freeGpuData() {
630 fAsyncPipelineCreation =
nullptr;
634 if (!fAsyncPipelineCreation) {
635 static const wgpu::RenderPipeline kNullPipeline =
nullptr;
636 return kNullPipeline;
638 if (fAsyncPipelineCreation->fFinished) {
639 return fAsyncPipelineCreation->fRenderPipeline;
641#if defined(__EMSCRIPTEN__)
643 SKGPU_LOG_F(
"CreateRenderPipelineAsync shouldn't be used in WASM");
645 wgpu::FutureWaitInfo waitInfo{};
646 waitInfo.future = fAsyncPipelineCreation->fFuture;
652 [[maybe_unused]]
auto status =
654 SkASSERT(status == wgpu::WaitStatus::Success);
658 return fAsyncPipelineCreation->fRenderPipeline;
static int step(int x, SkScalar min, SkScalar max)
wgpu::RenderPipeline fRenderPipeline
#define VALUE_IF_DSB_OR_ZERO(VALUE)
GrTriangulator::Vertex Vertex
#define SKGPU_LOG_F(fmt,...)
constexpr size_t size() const
skgpu::ShaderErrorHandler * shaderErrorHandler() const
const ResourceBindingRequirements & resourceBindingRequirements() const
bool setBackendLabels() const
bool storageBufferPreferred() const
const SkSL::ShaderCaps * shaderCaps() const
bool useAsyncPipelineCreation() const
std::array< wgpu::BindGroupLayout, kBindGroupCount > BindGroupLayouts
const wgpu::RenderPipeline & dawnRenderPipeline() const
int numTexturesAndSamplers() const
static constexpr unsigned int kInstanceBufferIndex
~DawnGraphicsPipeline() override
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
uint32_t renderStepID() const
const RenderStep * lookup(uint32_t uniqueID) const
const SharedContext * sharedContext() const
const Caps * caps() const
ShaderCodeDictionary * shaderCodeDictionary()
const RendererProvider * rendererProvider() const
static SkColor blend(SkColor dst, SkColor src, void(*mode)(float, float, float, float *, float *, float *))
static float max(float r, float g, float b)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
PrimitiveType
Decides how backend draws pixels based on input vertices.
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)
static const int kBlendEquationCnt
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)
skgpu::BlendCoeff fDstBlend
skgpu::BlendCoeff fSrcBlend
bool fRequiresLocalCoords
int fNumTexturesAndSamplers
AttachmentDesc fDepthStencilAttachment
AttachmentDesc fColorResolveAttachment
AttachmentDesc fColorAttachment