261 settings.fForceNoRTFlip =
true;
268 std::string vsCode, fsCode;
269 wgpu::ShaderModule fsModule, vsModule;
281 std::string& fsSkSL = fsSkSLInfo.
fSkSL;
286 bool hasFragmentSkSL = !fsSkSL.empty();
287 if (hasFragmentSkSL) {
298 &fsModule, errorHandler)) {
307 const std::string& vsSkSL = vsSkSLInfo.
fSkSL;
318 &vsModule, errorHandler)) {
322 std::string pipelineLabel =
324 wgpu::RenderPipelineDescriptor descriptor;
325 descriptor.label = pipelineLabel.c_str();
333 wgpu::BlendState
blend;
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);
343 wgpu::ColorTargetState colorTarget;
346 colorTarget.blend = blendOn ? &
blend :
nullptr;
347 colorTarget.writeMask = blendInfo.
fWritesColor && hasFragmentSkSL ? wgpu::ColorWriteMask::All
348 : wgpu::ColorWriteMask::None;
350 wgpu::FragmentState fragment;
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;
360 const auto& depthStencilSettings =
step->depthStencilSettings();
361 SkASSERT(depthStencilSettings.fDepthTestEnabled ||
363 wgpu::DepthStencilState depthStencil;
365 wgpu::TextureFormat dsFormat =
368 depthStencil.format =
370 if (depthStencilSettings.fDepthTestEnabled) {
371 depthStencil.depthWriteEnabled = depthStencilSettings.fDepthWriteEnabled;
373 depthStencil.depthCompare = compare_op_to_dawn(depthStencilSettings.fDepthCompareOp);
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;
384 descriptor.depthStencil = &depthStencil;
391 if (!groupLayouts[0]) {
396 if (hasFragmentSamplers) {
404 entries[i].binding =
static_cast<uint32_t
>(i);
405 entries[i].visibility = wgpu::ShaderStage::Fragment;
406 entries[i].sampler.type = wgpu::SamplerBindingType::Filtering;
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;
416 wgpu::BindGroupLayoutDescriptor groupLayoutDesc;
418 groupLayoutDesc.label = vsSkSLInfo.
fLabel.c_str();
420 groupLayoutDesc.entryCount = entries.size();
421 groupLayoutDesc.entries = entries.data();
422 groupLayouts[1] =
device.CreateBindGroupLayout(&groupLayoutDesc);
424 if (!groupLayouts[1]) {
429 wgpu::PipelineLayoutDescriptor layoutDesc;
431 layoutDesc.label = fsSkSLInfo.
fLabel.c_str();
433 layoutDesc.bindGroupLayoutCount =
434 hasFragmentSamplers ? groupLayouts.size() : groupLayouts.size() - 1;
435 layoutDesc.bindGroupLayouts = groupLayouts.data();
436 auto layout =
device.CreatePipelineLayout(&layoutDesc);
440 descriptor.layout = std::move(layout);
444 std::array<wgpu::VertexBufferLayout, kNumVertexBuffers> vertexBufferLayouts;
446 std::vector<wgpu::VertexAttribute> vertexAttributes;
448 auto arrayStride = create_vertex_attributes(
step->vertexAttributes(),
453 layout.arrayStride = arrayStride;
454 layout.stepMode = wgpu::VertexStepMode::Vertex;
455 layout.attributeCount = vertexAttributes.size();
456 layout.attributes = vertexAttributes.data();
458 layout.arrayStride = 0;
459 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
460 layout.attributeCount = 0;
461 layout.attributes =
nullptr;
466 std::vector<wgpu::VertexAttribute> instanceAttributes;
468 auto arrayStride = create_vertex_attributes(
step->instanceAttributes(),
469 step->vertexAttributes().size(),
470 &instanceAttributes);
473 layout.arrayStride = arrayStride;
474 layout.stepMode = wgpu::VertexStepMode::Instance;
475 layout.attributeCount = instanceAttributes.size();
476 layout.attributes = instanceAttributes.data();
478 layout.arrayStride = 0;
479 layout.stepMode = wgpu::VertexStepMode::VertexBufferNotUsed;
480 layout.attributeCount = 0;
481 layout.attributes =
nullptr;
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();
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;
501 descriptor.primitive.topology = wgpu::PrimitiveTopology::TriangleStrip;
502 descriptor.primitive.stripIndexFormat = wgpu::IndexFormat::Uint16;
505 descriptor.primitive.topology = wgpu::PrimitiveTopology::PointList;
510 descriptor.multisample.count = renderPassDesc.
fSampleCount;
511 [[maybe_unused]]
bool isMSAARenderToSingleSampled =
515#if defined(__EMSCRIPTEN__)
516 SkASSERT(!isMSAARenderToSingleSampled);
518 wgpu::DawnMultisampleStateRenderToSingleSampled pipelineMSAARenderToSingleSampledDesc;
519 if (isMSAARenderToSingleSampled) {
522 SkASSERT(
device.HasFeature(wgpu::FeatureName::MSAARenderToSingleSampled));
524 descriptor.multisample.nextInChain = &pipelineMSAARenderToSingleSampledDesc;
525 pipelineMSAARenderToSingleSampledDesc.enabled =
true;
529 descriptor.multisample.mask = 0xFFFFFFFF;
530 descriptor.multisample.alphaToCoverageEnabled =
false;
532 auto asyncCreation = std::make_unique<AsyncPipelineCreation>(
sharedContext);
535 device.CreateRenderPipelineAsync(
537 [](WGPUCreatePipelineAsyncStatus status,
538 WGPURenderPipeline pipeline,
543 if (status != WGPUCreatePipelineAsyncStatus_Success) {
547 arg->
set(wgpu::RenderPipeline::Acquire(pipeline));
550 asyncCreation.get());
552 asyncCreation->set(
device.CreateRenderPipeline(&descriptor));
554#if defined(GRAPHITE_TEST_UTILS)
555 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.
renderStepID(),
561 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
563 GraphicsPipeline::PipelineInfo* pipelineInfoPtr =
nullptr;
569 std::move(asyncCreation),
570 std::move(groupLayouts),
571 step->primitiveType(),
572 depthStencilSettings.fStencilReferenceValue,
573 !
step->uniforms().empty(),