Flutter Engine
The Flutter Engine
VulkanGraphicsPipeline.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2023 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
31
32namespace skgpu::graphite {
33
35 switch (type) {
57 return VK_FORMAT_R8_SINT;
63 return VK_FORMAT_R8_UINT;
69 return VK_FORMAT_R8_UNORM;
81 return VK_FORMAT_R32_SINT;
83 return VK_FORMAT_R32_UINT;
88 }
89 SK_ABORT("Unknown vertex attrib type");
90}
91
93 const SkSpan<const Attribute>& vertexAttrs,
94 const SkSpan<const Attribute>& instanceAttrs,
98 // Setup attribute & binding descriptions
99 int attribIndex = 0;
100 size_t vertexAttributeOffset = 0;
101 for (auto attrib : vertexAttrs) {
103 vkAttrib.location = attribIndex++;
105 vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
106 vkAttrib.offset = vertexAttributeOffset;
107 vertexAttributeOffset += attrib.sizeAlign4();
108 attributeDescs->push_back(vkAttrib);
109 }
110
111 size_t instanceAttributeOffset = 0;
112 for (auto attrib : instanceAttrs) {
114 vkAttrib.location = attribIndex++;
116 vkAttrib.format = attrib_type_to_vkformat(attrib.cpuType());
117 vkAttrib.offset = instanceAttributeOffset;
118 instanceAttributeOffset += attrib.sizeAlign4();
119 attributeDescs->push_back(vkAttrib);
120 }
121
122 if (bindingDescs && !vertexAttrs.empty()) {
123 bindingDescs->push_back() = {
125 (uint32_t) vertexAttributeOffset,
127 };
128 }
129 if (bindingDescs && !instanceAttrs.empty()) {
130 bindingDescs->push_back() = {
132 (uint32_t) instanceAttributeOffset,
134 };
135 }
136
137 memset(vertexInputInfo, 0, sizeof(VkPipelineVertexInputStateCreateInfo));
139 vertexInputInfo->pNext = nullptr;
140 vertexInputInfo->flags = 0;
141 vertexInputInfo->vertexBindingDescriptionCount = bindingDescs ? bindingDescs->size() : 0;
142 vertexInputInfo->pVertexBindingDescriptions =
143 bindingDescs && !bindingDescs->empty() ? bindingDescs->begin() : VK_NULL_HANDLE;
144 vertexInputInfo->vertexAttributeDescriptionCount = attributeDescs ? attributeDescs->size() : 0;
145 vertexInputInfo->pVertexAttributeDescriptions =
146 attributeDescs && !attributeDescs->empty() ? attributeDescs->begin() : VK_NULL_HANDLE;
147}
148
150 switch (primitiveType) {
157 }
159}
160
162 VkPipelineInputAssemblyStateCreateInfo* inputAssemblyInfo) {
163 memset(inputAssemblyInfo, 0, sizeof(VkPipelineInputAssemblyStateCreateInfo));
165 inputAssemblyInfo->pNext = nullptr;
166 inputAssemblyInfo->flags = 0;
167 inputAssemblyInfo->primitiveRestartEnable = false;
168 inputAssemblyInfo->topology = primitive_type_to_vk_topology(primitiveType);
169}
170
172 static const VkStencilOp gTable[] = {
173 VK_STENCIL_OP_KEEP, // kKeep
174 VK_STENCIL_OP_ZERO, // kZero
175 VK_STENCIL_OP_REPLACE, // kReplace
176 VK_STENCIL_OP_INVERT, // kInvert
181 };
182 static_assert(std::size(gTable) == kStencilOpCount);
183 static_assert(0 == (int)StencilOp::kKeep);
184 static_assert(1 == (int)StencilOp::kZero);
185 static_assert(2 == (int)StencilOp::kReplace);
186 static_assert(3 == (int)StencilOp::kInvert);
187 static_assert(4 == (int)StencilOp::kIncWrap);
188 static_assert(5 == (int)StencilOp::kDecWrap);
189 static_assert(6 == (int)StencilOp::kIncClamp);
190 static_assert(7 == (int)StencilOp::kDecClamp);
192 return gTable[(int)op];
193}
194
196 static const VkCompareOp gTable[] = {
197 VK_COMPARE_OP_ALWAYS, // kAlways
198 VK_COMPARE_OP_NEVER, // kNever
199 VK_COMPARE_OP_GREATER, // kGreater
201 VK_COMPARE_OP_LESS, // kLess
203 VK_COMPARE_OP_EQUAL, // kEqual
204 VK_COMPARE_OP_NOT_EQUAL, // kNotEqual
205 };
206 static_assert(std::size(gTable) == kCompareOpCount);
207 static_assert(0 == (int)CompareOp::kAlways);
208 static_assert(1 == (int)CompareOp::kNever);
209 static_assert(2 == (int)CompareOp::kGreater);
210 static_assert(3 == (int)CompareOp::kGEqual);
211 static_assert(4 == (int)CompareOp::kLess);
212 static_assert(5 == (int)CompareOp::kLEqual);
213 static_assert(6 == (int)CompareOp::kEqual);
214 static_assert(7 == (int)CompareOp::kNotEqual);
216
217 return gTable[(int)op];
218}
219
221 const DepthStencilSettings::Face& face,
222 uint32_t referenceValue) {
227 opState->compareMask = face.fReadMask; // TODO - check this.
228 opState->writeMask = face.fWriteMask;
229 opState->reference = referenceValue;
230}
231
232static void setup_depth_stencil_state(const DepthStencilSettings& stencilSettings,
234 SkASSERT(stencilSettings.fDepthTestEnabled ||
235 stencilSettings.fDepthCompareOp == CompareOp::kAlways);
236
237 memset(stencilInfo, 0, sizeof(VkPipelineDepthStencilStateCreateInfo));
239 stencilInfo->pNext = nullptr;
240 stencilInfo->flags = 0;
241 stencilInfo->depthTestEnable = stencilSettings.fDepthTestEnabled;
242 stencilInfo->depthWriteEnable = stencilSettings.fDepthWriteEnabled;
243 stencilInfo->depthCompareOp = compare_op_to_vk_compare_op(stencilSettings.fDepthCompareOp);
244 stencilInfo->depthBoundsTestEnable = VK_FALSE; // Default value TODO - Confirm
245 stencilInfo->stencilTestEnable = stencilSettings.fStencilTestEnabled;
246 if (stencilSettings.fStencilTestEnabled) {
247 setup_stencil_op_state(&stencilInfo->front,
248 stencilSettings.fFrontStencil,
249 stencilSettings.fStencilReferenceValue);
250 setup_stencil_op_state(&stencilInfo->back,
251 stencilSettings.fBackStencil,
252 stencilSettings.fStencilReferenceValue);
253 }
254 stencilInfo->minDepthBounds = 0.0f;
255 stencilInfo->maxDepthBounds = 1.0f;
256}
257
259 memset(viewportInfo, 0, sizeof(VkPipelineViewportStateCreateInfo));
261 viewportInfo->pNext = nullptr;
262 viewportInfo->flags = 0;
263
264 viewportInfo->viewportCount = 1;
265 viewportInfo->pViewports = nullptr; // This is set dynamically with a draw pass command
266
267 viewportInfo->scissorCount = 1;
268 viewportInfo->pScissors = nullptr; // This is set dynamically with a draw pass command
269
270 SkASSERT(viewportInfo->viewportCount == viewportInfo->scissorCount);
271}
272
273static void setup_multisample_state(int numSamples,
274 VkPipelineMultisampleStateCreateInfo* multisampleInfo) {
275 memset(multisampleInfo, 0, sizeof(VkPipelineMultisampleStateCreateInfo));
277 multisampleInfo->pNext = nullptr;
278 multisampleInfo->flags = 0;
280 &multisampleInfo->rasterizationSamples));
281 multisampleInfo->sampleShadingEnable = VK_FALSE;
282 multisampleInfo->minSampleShading = 0.0f;
283 multisampleInfo->pSampleMask = nullptr;
284 multisampleInfo->alphaToCoverageEnable = VK_FALSE;
285 multisampleInfo->alphaToOneEnable = VK_FALSE;
286}
287
289 switch (coeff) {
293 return VK_BLEND_FACTOR_ONE;
324 }
326}
327
329 static const VkBlendOp gTable[] = {
330 // Basic blend ops
334
335 // Advanced blend ops
351
352 // Illegal.
354 };
355 static_assert(0 == (int)skgpu::BlendEquation::kAdd);
356 static_assert(1 == (int)skgpu::BlendEquation::kSubtract);
357 static_assert(2 == (int)skgpu::BlendEquation::kReverseSubtract);
358 static_assert(3 == (int)skgpu::BlendEquation::kScreen);
359 static_assert(4 == (int)skgpu::BlendEquation::kOverlay);
360 static_assert(5 == (int)skgpu::BlendEquation::kDarken);
361 static_assert(6 == (int)skgpu::BlendEquation::kLighten);
362 static_assert(7 == (int)skgpu::BlendEquation::kColorDodge);
363 static_assert(8 == (int)skgpu::BlendEquation::kColorBurn);
364 static_assert(9 == (int)skgpu::BlendEquation::kHardLight);
365 static_assert(10 == (int)skgpu::BlendEquation::kSoftLight);
366 static_assert(11 == (int)skgpu::BlendEquation::kDifference);
367 static_assert(12 == (int)skgpu::BlendEquation::kExclusion);
368 static_assert(13 == (int)skgpu::BlendEquation::kMultiply);
369 static_assert(14 == (int)skgpu::BlendEquation::kHSLHue);
370 static_assert(15 == (int)skgpu::BlendEquation::kHSLSaturation);
371 static_assert(16 == (int)skgpu::BlendEquation::kHSLColor);
372 static_assert(17 == (int)skgpu::BlendEquation::kHSLLuminosity);
373 static_assert(std::size(gTable) == skgpu::kBlendEquationCnt);
374
375 SkASSERT((unsigned)equation < skgpu::kBlendEquationCnt);
376 return gTable[(int)equation];
377}
378
379static void setup_color_blend_state(const skgpu::BlendInfo& blendInfo,
381 VkPipelineColorBlendAttachmentState* attachmentState) {
382 skgpu::BlendEquation equation = blendInfo.fEquation;
383 skgpu::BlendCoeff srcCoeff = blendInfo.fSrcBlend;
384 skgpu::BlendCoeff dstCoeff = blendInfo.fDstBlend;
385 bool blendOff = skgpu::BlendShouldDisable(equation, srcCoeff, dstCoeff);
386
387 memset(attachmentState, 0, sizeof(VkPipelineColorBlendAttachmentState));
388 attachmentState->blendEnable = !blendOff;
389 if (!blendOff) {
390 attachmentState->srcColorBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
391 attachmentState->dstColorBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
392 attachmentState->colorBlendOp = blend_equation_to_vk_blend_op(equation);
393 attachmentState->srcAlphaBlendFactor = blend_coeff_to_vk_blend(srcCoeff);
394 attachmentState->dstAlphaBlendFactor = blend_coeff_to_vk_blend(dstCoeff);
395 attachmentState->alphaBlendOp = blend_equation_to_vk_blend_op(equation);
396 }
397
398 if (!blendInfo.fWritesColor) {
399 attachmentState->colorWriteMask = 0;
400 } else {
403 }
404
405 memset(colorBlendInfo, 0, sizeof(VkPipelineColorBlendStateCreateInfo));
407 colorBlendInfo->pNext = nullptr;
408 colorBlendInfo->flags = 0;
409 colorBlendInfo->logicOpEnable = VK_FALSE;
410 colorBlendInfo->attachmentCount = 1;
411 colorBlendInfo->pAttachments = attachmentState;
412 // colorBlendInfo->blendConstants is set dynamically
413}
414
415static void setup_raster_state(bool isWireframe,
417 memset(rasterInfo, 0, sizeof(VkPipelineRasterizationStateCreateInfo));
419 rasterInfo->pNext = nullptr;
420 rasterInfo->flags = 0;
421 rasterInfo->depthClampEnable = VK_FALSE;
422 rasterInfo->rasterizerDiscardEnable = VK_FALSE;
423 rasterInfo->polygonMode = isWireframe ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL;
424 rasterInfo->cullMode = VK_CULL_MODE_NONE;
426 rasterInfo->depthBiasEnable = VK_FALSE;
427 rasterInfo->depthBiasConstantFactor = 0.0f;
428 rasterInfo->depthBiasClamp = 0.0f;
429 rasterInfo->depthBiasSlopeFactor = 0.0f;
430 rasterInfo->lineWidth = 1.0f;
431}
432
434 VkShaderModule shaderModule,
435 VkPipelineShaderStageCreateInfo* shaderStageInfo) {
436 memset(shaderStageInfo, 0, sizeof(VkPipelineShaderStageCreateInfo));
438 shaderStageInfo->pNext = nullptr;
439 shaderStageInfo->flags = 0;
440 shaderStageInfo->stage = stage;
441 shaderStageInfo->module = shaderModule;
442 shaderStageInfo->pName = "main";
443 shaderStageInfo->pSpecializationInfo = nullptr;
444}
445
446
447static VkDescriptorSetLayout descriptor_data_to_layout(const VulkanSharedContext* sharedContext,
448 const SkSpan<DescriptorData>& descriptorData) {
449 if (descriptorData.size() == 0) { return VK_NULL_HANDLE; }
450
451 VkDescriptorSetLayout setLayout;
452 DescriptorDataToVkDescSetLayout(sharedContext, descriptorData, &setLayout);
453 if (setLayout == VK_NULL_HANDLE) {
454 SKGPU_LOG_E("Failed to create descriptor set layout; pipeline creation will fail.\n");
455 return VK_NULL_HANDLE;
456 }
457 return setLayout;
458}
459
460static void destroy_desc_set_layouts(const VulkanSharedContext* sharedContext,
462 for (int i = 0; i < setLayouts.size(); i++) {
463 if (setLayouts[i] != VK_NULL_HANDLE) {
464 VULKAN_CALL(sharedContext->interface(),
465 DestroyDescriptorSetLayout(sharedContext->device(),
466 setLayouts[i],
467 nullptr));
468 }
469 }
470}
471
472static VkPipelineLayout setup_pipeline_layout(const VulkanSharedContext* sharedContext,
473 bool usesIntrinsicConstantUbo,
474 bool hasStepUniforms,
475 int numPaintUniforms,
476 int numTextureSamplers,
477 int numInputAttachments) {
478 // Determine descriptor set layouts for this pipeline based upon render pass information.
480
481 // Determine uniform descriptor set layout
483 uniformDescriptors;
484 if (usesIntrinsicConstantUbo) {
486 }
487 if (hasStepUniforms) {
489 }
490 if (numPaintUniforms > 0) {
492 }
493
494 if (!uniformDescriptors.empty()) {
495 VkDescriptorSetLayout uniformSetLayout =
496 descriptor_data_to_layout(sharedContext, {uniformDescriptors});
497 if (uniformSetLayout == VK_NULL_HANDLE) { return VK_NULL_HANDLE; }
498 setLayouts.push_back(uniformSetLayout);
499 }
500
501 // Determine input attachment descriptor set layout
502 if (numInputAttachments > 0) {
503 // For now, we only expect to have up to 1 input attachment. We also share that descriptor
504 // set number with uniform descriptors for normal graphics pipeline usages, so verify that
505 // we are not using any uniform descriptors to avoid conflicts.
506 SkASSERT(numInputAttachments == 1 && uniformDescriptors.empty());
507 skia_private::TArray<DescriptorData> inputAttachmentDescriptors(numInputAttachments);
509
510 VkDescriptorSetLayout inputAttachmentDescSetLayout =
511 descriptor_data_to_layout(sharedContext, {inputAttachmentDescriptors});
512
513 if (inputAttachmentDescSetLayout == VK_NULL_HANDLE) {
514 destroy_desc_set_layouts(sharedContext, setLayouts);
515 return VK_NULL_HANDLE;
516 }
517 setLayouts.push_back(inputAttachmentDescSetLayout);
518 }
519
520 // Determine texture/sampler descriptor set layout
521 if (numTextureSamplers > 0) {
522 skia_private::TArray<DescriptorData> textureSamplerDescs(numTextureSamplers);
523 for (int i = 0; i < numTextureSamplers; i++) {
525 /*count=*/1,
526 /*bindingIdx=*/i,
528 }
529 VkDescriptorSetLayout textureSamplerDescSetLayout =
530 descriptor_data_to_layout(sharedContext, {textureSamplerDescs});
531
532 if (textureSamplerDescSetLayout == VK_NULL_HANDLE) {
533 destroy_desc_set_layouts(sharedContext, setLayouts);
534 return VK_NULL_HANDLE;
535 }
536 setLayouts.push_back(textureSamplerDescSetLayout);
537 }
538
539 // Generate a pipeline layout using the now-populated descriptor set layout array
540 VkPipelineLayoutCreateInfo layoutCreateInfo;
541 memset(&layoutCreateInfo, 0, sizeof(VkPipelineLayoutCreateFlags));
543 layoutCreateInfo.pNext = nullptr;
544 layoutCreateInfo.flags = 0;
545 layoutCreateInfo.setLayoutCount = setLayouts.size();
546 layoutCreateInfo.pSetLayouts = setLayouts.begin();
547 // TODO: Add support for push constants.
548 layoutCreateInfo.pushConstantRangeCount = 0;
549 layoutCreateInfo.pPushConstantRanges = nullptr;
550
552 VkPipelineLayout layout;
553 VULKAN_CALL_RESULT(sharedContext,
554 result,
555 CreatePipelineLayout(sharedContext->device(),
556 &layoutCreateInfo,
557 /*const VkAllocationCallbacks*=*/nullptr,
558 &layout));
559
560 // DescriptorSetLayouts can be deleted after the pipeline layout is created.
561 destroy_desc_set_layouts(sharedContext, setLayouts);
562
563 return result == VK_SUCCESS ? layout : VK_NULL_HANDLE;
564}
565
566static void destroy_shader_modules(const VulkanSharedContext* sharedContext,
567 VkShaderModule vsModule,
568 VkShaderModule fsModule) {
569 if (vsModule != VK_NULL_HANDLE) {
570 VULKAN_CALL(sharedContext->interface(),
571 DestroyShaderModule(sharedContext->device(), vsModule, nullptr));
572 }
573 if (fsModule != VK_NULL_HANDLE) {
574 VULKAN_CALL(sharedContext->interface(),
575 DestroyShaderModule(sharedContext->device(), fsModule, nullptr));
576 }
577}
578
580 VkDynamicState* dynamicStates) {
581 memset(dynamicInfo, 0, sizeof(VkPipelineDynamicStateCreateInfo));
583 dynamicInfo->pNext = VK_NULL_HANDLE;
584 dynamicInfo->flags = 0;
585 dynamicStates[0] = VK_DYNAMIC_STATE_VIEWPORT;
586 dynamicStates[1] = VK_DYNAMIC_STATE_SCISSOR;
587 dynamicStates[2] = VK_DYNAMIC_STATE_BLEND_CONSTANTS;
588 dynamicInfo->dynamicStateCount = 3;
589 dynamicInfo->pDynamicStates = dynamicStates;
590}
591
593 const VulkanSharedContext* sharedContext,
594 const RuntimeEffectDictionary* runtimeDict,
595 const GraphicsPipelineDesc& pipelineDesc,
596 const RenderPassDesc& renderPassDesc,
597 const sk_sp<VulkanRenderPass>& compatibleRenderPass,
598 VkPipelineCache pipelineCache) {
599
600 SkSL::Program::Interface vsInterface, fsInterface;
602 settings.fForceNoRTFlip = true; // TODO: Confirm
604
606 const bool useStorageBuffers = sharedContext->caps()->storageBufferPreferred();
607
608 if (step->vertexAttributes().size() + step->instanceAttributes().size() >
609 sharedContext->vulkanCaps().maxVertexAttributes()) {
610 SKGPU_LOG_W("Requested more than the supported number of vertex attributes");
611 return nullptr;
612 }
613
616 runtimeDict,
617 step,
618 pipelineDesc.paintParamsID(),
619 useStorageBuffers,
620 renderPassDesc.fWriteSwizzle);
621 std::string& fsSkSL = fsSkSLInfo.fSkSL;
622 const bool localCoordsNeeded = fsSkSLInfo.fRequiresLocalCoords;
623
624 bool hasFragmentSkSL = !fsSkSL.empty();
625 std::string vsSPIRV, fsSPIRV;
626 VkShaderModule fsModule = VK_NULL_HANDLE, vsModule = VK_NULL_HANDLE;
627
628 if (hasFragmentSkSL) {
630 fsSkSL,
632 settings,
633 &fsSPIRV,
634 &fsInterface,
635 errorHandler)) {
636 return nullptr;
637 }
638
640 if (!fsModule) {
641 return nullptr;
642 }
643 }
644
646 step,
647 useStorageBuffers,
648 localCoordsNeeded);
649 const std::string& vsSkSL = vsSkSLInfo.fSkSL;
651 vsSkSL,
653 settings,
654 &vsSPIRV,
655 &vsInterface,
656 errorHandler)) {
657 return nullptr;
658 }
659
661 if (!vsModule) {
662 // Clean up the other shader module before returning.
664 return nullptr;
665 }
666
670 setup_vertex_input_state(step->vertexAttributes(),
671 step->instanceAttributes(),
672 &vertexInputInfo,
673 &bindingDescs,
674 &attributeDescs);
675
677 setup_input_assembly_state(step->primitiveType(), &inputAssemblyInfo);
678
680 setup_depth_stencil_state(step->depthStencilSettings(), &depthStencilInfo);
681
683 setup_viewport_scissor_state(&viewportInfo);
684
687 &multisampleInfo);
688
689 // We will only have one color blend attachment per pipeline.
690 VkPipelineColorBlendAttachmentState attachmentStates[1];
692 setup_color_blend_state(fsSkSLInfo.fBlendInfo, &colorBlendInfo, attachmentStates);
693
695 // TODO: Check for wire frame mode once that is an available context option within graphite.
696 setup_raster_state(/*isWireframe=*/false, &rasterInfo);
697
698 VkPipelineShaderStageCreateInfo pipelineShaderStages[2];
700 vsModule,
701 &pipelineShaderStages[0]);
702 if (hasFragmentSkSL) {
704 fsModule,
705 &pipelineShaderStages[1]);
706 }
707
708 // TODO(b/347070730): Analyze fsSkSLInfo.fData to see if we have any immutable samplers which
709 // should be a part of the pipeline layout.
710
711 // TODO: Query RenderPassDesc for input attachment information. For now, we only use one for
712 // loading MSAA from resolve so we can simply pass in 0 when not doing that.
713 VkPipelineLayout pipelineLayout = setup_pipeline_layout(sharedContext,
714 /*usesIntrinsicConstantUbo=*/true,
715 !step->uniforms().empty(),
716 fsSkSLInfo.fNumPaintUniforms,
717 fsSkSLInfo.fNumTexturesAndSamplers,
718 /*numInputAttachments=*/0);
719 if (pipelineLayout == VK_NULL_HANDLE) {
720 destroy_shader_modules(sharedContext, vsModule, fsModule);
721 return nullptr;
722 }
723
724 VkDynamicState dynamicStates[3];
726 setup_dynamic_state(&dynamicInfo, dynamicStates);
727
728 bool loadMsaaFromResolve = renderPassDesc.fColorResolveAttachment.fTextureInfo.isValid() &&
730
731 VkGraphicsPipelineCreateInfo pipelineCreateInfo;
732 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
734 pipelineCreateInfo.pNext = nullptr;
735 pipelineCreateInfo.flags = 0;
736 pipelineCreateInfo.stageCount = hasFragmentSkSL ? 2 : 1;
737 pipelineCreateInfo.pStages = &pipelineShaderStages[0];
738 pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
739 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
740 pipelineCreateInfo.pTessellationState = nullptr;
741 pipelineCreateInfo.pViewportState = &viewportInfo;
742 pipelineCreateInfo.pRasterizationState = &rasterInfo;
743 pipelineCreateInfo.pMultisampleState = &multisampleInfo;
744 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
745 pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
746 pipelineCreateInfo.pDynamicState = &dynamicInfo;
747 pipelineCreateInfo.layout = pipelineLayout;
748 pipelineCreateInfo.renderPass = compatibleRenderPass->renderPass();
749 pipelineCreateInfo.subpass = loadMsaaFromResolve ? 1 : 0;
750 pipelineCreateInfo.basePipelineHandle = VK_NULL_HANDLE;
751 pipelineCreateInfo.basePipelineIndex = -1;
752
753 VkPipeline vkPipeline;
755 {
756 TRACE_EVENT0_ALWAYS("skia.shaders", "VkCreateGraphicsPipeline");
758 result,
759 CreateGraphicsPipelines(sharedContext->device(),
760 pipelineCache,
761 /*createInfoCount=*/1,
762 &pipelineCreateInfo,
763 /*pAllocator=*/nullptr,
764 &vkPipeline));
765 }
766 if (result != VK_SUCCESS) {
767 SkDebugf("Failed to create pipeline. Error: %d\n", result);
768 return nullptr;
769 }
770
771 // After creating the pipeline object, we can clean up the VkShaderModule(s).
772 destroy_shader_modules(sharedContext, vsModule, fsModule);
773
774#if defined(GRAPHITE_TEST_UTILS)
775 GraphicsPipeline::PipelineInfo pipelineInfo = {pipelineDesc.renderStepID(),
776 pipelineDesc.paintParamsID(),
777 std::move(vsSkSL),
778 std::move(fsSkSL),
779 "SPIR-V disassembly not available",
780 "SPIR-V disassembly not available"};
781 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = &pipelineInfo;
782#else
783 GraphicsPipeline::PipelineInfo* pipelineInfoPtr = nullptr;
784#endif
785
788 pipelineInfoPtr,
789 pipelineLayout,
790 vkPipeline,
791 fsSkSLInfo.fNumPaintUniforms > 0,
792 !step->uniforms().empty(),
793 fsSkSLInfo.fNumTexturesAndSamplers,
794 /*ownsPipelineLayout=*/true));
795}
796
798 const VulkanSharedContext* sharedContext,
799 VkShaderModule* outVertexShaderModule,
800 VkShaderModule* outFragShaderModule,
801 VkPipelineShaderStageCreateInfo* outShaderStageInfo,
802 VkPipelineLayout* outPipelineLayout) {
803 SkSL::Program::Interface vsInterface, fsInterface;
805 settings.fForceNoRTFlip = true;
806 std::string vsSPIRV, fsSPIRV;
808
809 std::string vertShaderText;
810 vertShaderText.append(
811 "// MSAA Load Program VS\n"
812 "layout(vulkan, location=0) in float2 ndc_position;"
813
814 "void main() {"
815 "sk_Position.xy = ndc_position;"
816 "sk_Position.zw = half2(0, 1);"
817 "}");
818
819 std::string fragShaderText;
820 fragShaderText.append(
821 "layout(vulkan, input_attachment_index=0, set=0, binding=0) subpassInput uInput;"
822
823 "// MSAA Load Program FS\n"
824 "void main() {"
825 "sk_FragColor = subpassLoad(uInput);"
826 "}");
827
829 vertShaderText,
831 settings,
832 &vsSPIRV,
833 &vsInterface,
834 errorHandler)) {
835 return false;
836 }
838 fragShaderText,
840 settings,
841 &fsSPIRV,
842 &fsInterface,
843 errorHandler)) {
844 return false;
845 }
846 *outFragShaderModule =
848 if (*outFragShaderModule == VK_NULL_HANDLE) {
849 return false;
850 }
851
852 *outVertexShaderModule =
854 if (*outVertexShaderModule == VK_NULL_HANDLE) {
856 return false;
857 }
858
860 *outVertexShaderModule,
861 &outShaderStageInfo[0]);
862
864 *outFragShaderModule,
865 &outShaderStageInfo[1]);
866
867 // The load msaa pipeline takes no step or paint uniforms and no instance attributes. It only
868 // references one input attachment texture (which does not require a sampler) and one vertex
869 // attribute (NDC position)
870 skia_private::TArray<DescriptorData> inputAttachmentDescriptors(1);
872 *outPipelineLayout = setup_pipeline_layout(sharedContext,
873 /*usesIntrinsicConstantUbo=*/false,
874 /*hasStepUniforms=*/false,
875 /*numPaintUniforms=*/0,
876 /*numTextureSamplers=*/0,
877 /*numInputAttachments=*/1);
878
879 if (*outPipelineLayout == VK_NULL_HANDLE) {
880 destroy_shader_modules(sharedContext, *outVertexShaderModule, *outFragShaderModule);
881 return false;
882 }
883 return true;
884}
885
887 const VulkanSharedContext* sharedContext,
888 VkShaderModule vsModule,
889 VkShaderModule fsModule,
890 VkPipelineShaderStageCreateInfo* pipelineShaderStages,
891 VkPipelineLayout pipelineLayout,
892 sk_sp<VulkanRenderPass> compatibleRenderPass,
893 VkPipelineCache pipelineCache,
894 const TextureInfo& dstColorAttachmentTexInfo) {
895
896 int numSamples = dstColorAttachmentTexInfo.numSamples();
897
898 // Create vertex attribute list
899 Attribute vertexAttrib[1] = {{"ndc_position", VertexAttribType::kFloat2, SkSLType::kFloat2}};
900 SkSpan<const Attribute> loadMSAAVertexAttribs = {vertexAttrib};
901
905 setup_vertex_input_state(loadMSAAVertexAttribs,
906 /*instanceAttrs=*/{}, // Load msaa pipeline takes no instance attribs
907 &vertexInputInfo,
908 &bindingDescs,
909 &attributeDescs);
910
913
915 setup_depth_stencil_state(/*stencilSettings=*/{}, &depthStencilInfo);
916
918 setup_viewport_scissor_state(&viewportInfo);
919
921 setup_multisample_state(numSamples, &multisampleInfo);
922
923 // We will only have one color blend attachment per pipeline.
924 VkPipelineColorBlendAttachmentState attachmentStates[1];
926 setup_color_blend_state({}, &colorBlendInfo, attachmentStates);
927
929 // TODO: Check for wire frame mode once that is an available context option within graphite.
930 setup_raster_state(/*isWireframe=*/false, &rasterInfo);
931
932 VkDynamicState dynamicStates[3];
934 setup_dynamic_state(&dynamicInfo, dynamicStates);
935
936 VkGraphicsPipelineCreateInfo pipelineCreateInfo;
937 memset(&pipelineCreateInfo, 0, sizeof(VkGraphicsPipelineCreateInfo));
939 pipelineCreateInfo.pNext = nullptr;
940 pipelineCreateInfo.flags = 0;
941 pipelineCreateInfo.stageCount = 2;
942 pipelineCreateInfo.pStages = pipelineShaderStages;
943 pipelineCreateInfo.pVertexInputState = &vertexInputInfo;
944 pipelineCreateInfo.pInputAssemblyState = &inputAssemblyInfo;
945 pipelineCreateInfo.pTessellationState = nullptr;
946 pipelineCreateInfo.pViewportState = &viewportInfo;
947 pipelineCreateInfo.pRasterizationState = &rasterInfo;
948 pipelineCreateInfo.pMultisampleState = &multisampleInfo;
949 pipelineCreateInfo.pDepthStencilState = &depthStencilInfo;
950 pipelineCreateInfo.pColorBlendState = &colorBlendInfo;
951 pipelineCreateInfo.pDynamicState = &dynamicInfo;
952 pipelineCreateInfo.layout = pipelineLayout;
953 pipelineCreateInfo.renderPass = compatibleRenderPass->renderPass();
954
955 VkPipeline vkPipeline;
957 {
958 TRACE_EVENT0_ALWAYS("skia.shaders", "CreateGraphicsPipeline");
959 SkASSERT(pipelineCache != VK_NULL_HANDLE);
961 result,
962 CreateGraphicsPipelines(sharedContext->device(),
963 pipelineCache,
964 /*createInfoCount=*/1,
965 &pipelineCreateInfo,
966 /*pAllocator=*/nullptr,
967 &vkPipeline));
968 }
969 if (result != VK_SUCCESS) {
970 SkDebugf("Failed to create pipeline. Error: %d\n", result);
971 return nullptr;
972 }
973
974 // TODO: If we want to track GraphicsPipeline::PipelineInfo in debug, we'll need to add
975 // PipelineDesc as an argument for this method. For now, just pass in nullptr.
978 /*pipelineInfo=*/nullptr,
979 pipelineLayout,
980 vkPipeline,
981 /*hasFragmentUniforms=*/false,
982 /*hasStepUniforms=*/false,
983 /*numTextureSamplers*/0,
984 /*ownsPipelineLayout=*/false));
985}
986
987VulkanGraphicsPipeline::VulkanGraphicsPipeline(const skgpu::graphite::SharedContext* sharedContext,
988 PipelineInfo* pipelineInfo,
989 VkPipelineLayout pipelineLayout,
990 VkPipeline pipeline,
991 bool hasFragmentUniforms,
992 bool hasStepUniforms,
993 int numTextureSamplers,
994 bool ownsPipelineLayout)
995 : GraphicsPipeline(sharedContext, pipelineInfo)
996 , fPipelineLayout(pipelineLayout)
997 , fPipeline(pipeline)
998 , fHasFragmentUniforms(hasFragmentUniforms)
999 , fHasStepUniforms(hasStepUniforms)
1000 , fNumTextureSamplers(numTextureSamplers)
1001 , fOwnsPipelineLayout(ownsPipelineLayout) {}
1002
1003void VulkanGraphicsPipeline::freeGpuData() {
1004 auto sharedCtxt = static_cast<const VulkanSharedContext*>(this->sharedContext());
1005 if (fPipeline != VK_NULL_HANDLE) {
1006 VULKAN_CALL(sharedCtxt->interface(),
1007 DestroyPipeline(sharedCtxt->device(), fPipeline, nullptr));
1008 }
1009 if (fOwnsPipelineLayout && fPipelineLayout != VK_NULL_HANDLE) {
1010 VULKAN_CALL(sharedCtxt->interface(),
1011 DestroyPipelineLayout(sharedCtxt->device(), fPipelineLayout, nullptr));
1012 }
1013}
1014
1015} // namespace skgpu::graphite
static int step(int x, SkScalar min, SkScalar max)
Definition: BlurTest.cpp:215
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
#define SKGPU_LOG_E(fmt,...)
Definition: Log.h:38
#define SKGPU_LOG_W(fmt,...)
Definition: Log.h:40
#define SkUNREACHABLE
Definition: SkAssert.h:135
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define TRACE_EVENT0_ALWAYS(category_group, name)
#define VULKAN_CALL(IFACE, X)
#define VULKAN_CALL_RESULT(SHARED_CONTEXT, RESULT, X)
GLenum type
constexpr bool empty() const
Definition: SkSpan_impl.h:96
constexpr size_t size() const
Definition: SkSpan_impl.h:95
skgpu::ShaderErrorHandler * shaderErrorHandler() const
Definition: Caps.h:273
const ResourceBindingRequirements & resourceBindingRequirements() const
Definition: Caps.h:150
bool storageBufferPreferred() const
Definition: Caps.h:239
const SkSL::ShaderCaps * shaderCaps() const
Definition: Caps.h:75
UniquePaintParamsID paintParamsID() const
const RenderStep * lookup(uint32_t uniqueID) const
const SharedContext * sharedContext() const
Definition: Resource.h:189
const Caps * caps() const
Definition: SharedContext.h:39
ShaderCodeDictionary * shaderCodeDictionary()
Definition: SharedContext.h:49
const RendererProvider * rendererProvider() const
Definition: SharedContext.h:47
uint32_t numSamples() const
Definition: TextureInfo.h:78
static const DescriptorData kRenderStepUniformDescriptor
static sk_sp< VulkanGraphicsPipeline > Make(const VulkanSharedContext *, const RuntimeEffectDictionary *, const GraphicsPipelineDesc &, const RenderPassDesc &, const sk_sp< VulkanRenderPass > &compatibleRenderPass, VkPipelineCache)
static constexpr unsigned int kInstanceBufferIndex
static const DescriptorData kInputAttachmentDescriptor
static const DescriptorData kIntrinsicUniformBufferDescriptor
static constexpr unsigned int kVertexBufferIndex
static sk_sp< VulkanGraphicsPipeline > MakeLoadMSAAPipeline(const VulkanSharedContext *, VkShaderModule vsModule, VkShaderModule fsModule, VkPipelineShaderStageCreateInfo *pipelineShaderStages, VkPipelineLayout, sk_sp< VulkanRenderPass > compatibleRenderPass, VkPipelineCache, const TextureInfo &dstColorAttachmentTexInfo)
static const DescriptorData kPaintUniformDescriptor
static bool InitializeMSAALoadPipelineStructs(const VulkanSharedContext *, VkShaderModule *outVertexShaderModule, VkShaderModule *outFragShaderModule, VkPipelineShaderStageCreateInfo *outShaderStageInfo, VkPipelineLayout *outPipelineLayout)
const skgpu::VulkanInterface * interface() const
bool empty() const
Definition: SkTArray.h:199
int size() const
Definition: SkTArray.h:421
GAsyncResult * result
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
Definition: switches.h:259
static void setup_viewport_scissor_state(VkPipelineViewportStateCreateInfo *viewportInfo)
VertSkSLInfo BuildVertexSkSL(const ResourceBindingRequirements &bindingReqs, const RenderStep *step, bool useStorageBuffers, bool defineLocalCoordsVarying)
static constexpr int kCompareOpCount
Definition: DrawTypes.h:159
static VkDescriptorSetLayout descriptor_data_to_layout(const VulkanSharedContext *sharedContext, const SkSpan< DescriptorData > &descriptorData)
static VkBlendOp blend_equation_to_vk_blend_op(skgpu::BlendEquation equation)
static void setup_depth_stencil_state(const DepthStencilSettings &stencilSettings, VkPipelineDepthStencilStateCreateInfo *stencilInfo)
static VkPipelineLayout setup_pipeline_layout(const VulkanSharedContext *sharedContext, bool usesIntrinsicConstantUbo, bool hasStepUniforms, int numPaintUniforms, int numTextureSamplers, int numInputAttachments)
static void setup_raster_state(bool isWireframe, VkPipelineRasterizationStateCreateInfo *rasterInfo)
static void setup_color_blend_state(const skgpu::BlendInfo &blendInfo, VkPipelineColorBlendStateCreateInfo *colorBlendInfo, VkPipelineColorBlendAttachmentState *attachmentState)
static void setup_stencil_op_state(VkStencilOpState *opState, const DepthStencilSettings::Face &face, uint32_t referenceValue)
static VkPrimitiveTopology primitive_type_to_vk_topology(PrimitiveType primitiveType)
VkShaderModule createVulkanShaderModule(const VulkanSharedContext *context, const std::string &spirv, VkShaderStageFlagBits stage)
FragSkSLInfo BuildFragmentSkSL(const Caps *caps, const ShaderCodeDictionary *dict, const RuntimeEffectDictionary *rteDict, const RenderStep *step, UniquePaintParamsID paintID, bool useStorageBuffers, skgpu::Swizzle writeSwizzle)
static void destroy_shader_modules(const VulkanSharedContext *sharedContext, VkShaderModule vsModule, VkShaderModule fsModule)
static void destroy_desc_set_layouts(const VulkanSharedContext *sharedContext, skia_private::TArray< VkDescriptorSetLayout > &setLayouts)
static VkStencilOp stencil_op_to_vk_stencil_op(StencilOp op)
static void setup_dynamic_state(VkPipelineDynamicStateCreateInfo *dynamicInfo, VkDynamicState *dynamicStates)
static constexpr int kStencilOpCount
Definition: DrawTypes.h:173
void DescriptorDataToVkDescSetLayout(const VulkanSharedContext *ctxt, const SkSpan< DescriptorData > &requestedDescriptors, VkDescriptorSetLayout *outLayout)
static void setup_vertex_input_state(const SkSpan< const Attribute > &vertexAttrs, const SkSpan< const Attribute > &instanceAttrs, VkPipelineVertexInputStateCreateInfo *vertexInputInfo, skia_private::STArray< 2, VkVertexInputBindingDescription, true > *bindingDescs, skia_private::STArray< 16, VkVertexInputAttributeDescription > *attributeDescs)
static VkCompareOp compare_op_to_vk_compare_op(CompareOp op)
static void setup_input_assembly_state(PrimitiveType primitiveType, VkPipelineInputAssemblyStateCreateInfo *inputAssemblyInfo)
static void setup_multisample_state(int numSamples, VkPipelineMultisampleStateCreateInfo *multisampleInfo)
static VkFormat attrib_type_to_vkformat(VertexAttribType type)
static void setup_shader_stage_info(VkShaderStageFlagBits stage, VkShaderModule shaderModule, VkPipelineShaderStageCreateInfo *shaderStageInfo)
static VkBlendFactor blend_coeff_to_vk_blend(skgpu::BlendCoeff coeff)
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
static constexpr bool SampleCountToVkSampleCount(uint32_t samples, VkSampleCountFlagBits *vkSamples)
bool SkSLToSPIRV(const SkSL::ShaderCaps *caps, const std::string &sksl, SkSL::ProgramKind programKind, const SkSL::ProgramSettings &settings, std::string *spirv, SkSL::ProgramInterface *outInterface, ShaderErrorHandler *errorHandler)
const VkPipelineTessellationStateCreateInfo * pTessellationState
Definition: vulkan_core.h:3674
const VkPipelineDepthStencilStateCreateInfo * pDepthStencilState
Definition: vulkan_core.h:3678
const VkPipelineDynamicStateCreateInfo * pDynamicState
Definition: vulkan_core.h:3680
const VkPipelineColorBlendStateCreateInfo * pColorBlendState
Definition: vulkan_core.h:3679
VkPipelineCreateFlags flags
Definition: vulkan_core.h:3669
const VkPipelineInputAssemblyStateCreateInfo * pInputAssemblyState
Definition: vulkan_core.h:3673
const VkPipelineMultisampleStateCreateInfo * pMultisampleState
Definition: vulkan_core.h:3677
const VkPipelineVertexInputStateCreateInfo * pVertexInputState
Definition: vulkan_core.h:3672
const VkPipelineShaderStageCreateInfo * pStages
Definition: vulkan_core.h:3671
const VkPipelineRasterizationStateCreateInfo * pRasterizationState
Definition: vulkan_core.h:3676
const VkPipelineViewportStateCreateInfo * pViewportState
Definition: vulkan_core.h:3675
VkColorComponentFlags colorWriteMask
Definition: vulkan_core.h:3644
VkPipelineColorBlendStateCreateFlags flags
Definition: vulkan_core.h:3650
const VkPipelineColorBlendAttachmentState * pAttachments
Definition: vulkan_core.h:3654
VkPipelineDepthStencilStateCreateFlags flags
Definition: vulkan_core.h:3624
VkPipelineDynamicStateCreateFlags flags
Definition: vulkan_core.h:3661
const VkDynamicState * pDynamicStates
Definition: vulkan_core.h:3663
VkPipelineInputAssemblyStateCreateFlags flags
Definition: vulkan_core.h:3552
VkPipelineLayoutCreateFlags flags
Definition: vulkan_core.h:3697
const VkPushConstantRange * pPushConstantRanges
Definition: vulkan_core.h:3701
const VkDescriptorSetLayout * pSetLayouts
Definition: vulkan_core.h:3699
VkPipelineMultisampleStateCreateFlags flags
Definition: vulkan_core.h:3602
VkSampleCountFlagBits rasterizationSamples
Definition: vulkan_core.h:3603
VkPipelineRasterizationStateCreateFlags flags
Definition: vulkan_core.h:3586
VkPipelineShaderStageCreateFlags flags
Definition: vulkan_core.h:3509
const VkSpecializationInfo * pSpecializationInfo
Definition: vulkan_core.h:3513
VkShaderStageFlagBits stage
Definition: vulkan_core.h:3510
const VkVertexInputAttributeDescription * pVertexAttributeDescriptions
Definition: vulkan_core.h:3546
const VkVertexInputBindingDescription * pVertexBindingDescriptions
Definition: vulkan_core.h:3544
VkPipelineVertexInputStateCreateFlags flags
Definition: vulkan_core.h:3542
VkPipelineViewportStateCreateFlags flags
Definition: vulkan_core.h:3576
VkStencilOp failOp
Definition: vulkan_core.h:3612
VkStencilOp passOp
Definition: vulkan_core.h:3613
uint32_t reference
Definition: vulkan_core.h:3618
VkCompareOp compareOp
Definition: vulkan_core.h:3615
uint32_t writeMask
Definition: vulkan_core.h:3617
uint32_t compareMask
Definition: vulkan_core.h:3616
VkStencilOp depthFailOp
Definition: vulkan_core.h:3614
skgpu::BlendCoeff fDstBlend
Definition: Blend.h:96
bool fWritesColor
Definition: Blend.h:98
skgpu::BlendCoeff fSrcBlend
Definition: Blend.h:95
AttachmentDesc fColorResolveAttachment
VkShaderStageFlagBits
Definition: vulkan_core.h:2664
@ VK_SHADER_STAGE_VERTEX_BIT
Definition: vulkan_core.h:2665
@ VK_SHADER_STAGE_FRAGMENT_BIT
Definition: vulkan_core.h:2669
VkDynamicState
Definition: vulkan_core.h:1930
@ VK_DYNAMIC_STATE_BLEND_CONSTANTS
Definition: vulkan_core.h:1935
@ VK_DYNAMIC_STATE_VIEWPORT
Definition: vulkan_core.h:1931
@ VK_DYNAMIC_STATE_SCISSOR
Definition: vulkan_core.h:1932
VkStencilOp
Definition: vulkan_core.h:2056
@ VK_STENCIL_OP_INCREMENT_AND_CLAMP
Definition: vulkan_core.h:2060
@ VK_STENCIL_OP_DECREMENT_AND_CLAMP
Definition: vulkan_core.h:2061
@ VK_STENCIL_OP_INCREMENT_AND_WRAP
Definition: vulkan_core.h:2063
@ VK_STENCIL_OP_KEEP
Definition: vulkan_core.h:2057
@ VK_STENCIL_OP_REPLACE
Definition: vulkan_core.h:2059
@ VK_STENCIL_OP_ZERO
Definition: vulkan_core.h:2058
@ VK_STENCIL_OP_DECREMENT_AND_WRAP
Definition: vulkan_core.h:2064
@ VK_STENCIL_OP_INVERT
Definition: vulkan_core.h:2062
@ VK_CULL_MODE_NONE
Definition: vulkan_core.h:2695
VkCompareOp
Definition: vulkan_core.h:1918
@ VK_COMPARE_OP_LESS_OR_EQUAL
Definition: vulkan_core.h:1922
@ VK_COMPARE_OP_LESS
Definition: vulkan_core.h:1920
@ VK_COMPARE_OP_NOT_EQUAL
Definition: vulkan_core.h:1924
@ VK_COMPARE_OP_NEVER
Definition: vulkan_core.h:1919
@ VK_COMPARE_OP_ALWAYS
Definition: vulkan_core.h:1926
@ VK_COMPARE_OP_EQUAL
Definition: vulkan_core.h:1921
@ VK_COMPARE_OP_GREATER_OR_EQUAL
Definition: vulkan_core.h:1925
@ VK_COMPARE_OP_GREATER
Definition: vulkan_core.h:1923
VkBlendOp
Definition: vulkan_core.h:1863
@ VK_BLEND_OP_MULTIPLY_EXT
Definition: vulkan_core.h:1881
@ VK_BLEND_OP_ADD
Definition: vulkan_core.h:1864
@ VK_BLEND_OP_HARDLIGHT_EXT
Definition: vulkan_core.h:1888
@ VK_BLEND_OP_OVERLAY_EXT
Definition: vulkan_core.h:1883
@ VK_BLEND_OP_COLORDODGE_EXT
Definition: vulkan_core.h:1886
@ VK_BLEND_OP_SUBTRACT
Definition: vulkan_core.h:1865
@ VK_BLEND_OP_HSL_COLOR_EXT
Definition: vulkan_core.h:1902
@ VK_BLEND_OP_DARKEN_EXT
Definition: vulkan_core.h:1884
@ VK_BLEND_OP_SOFTLIGHT_EXT
Definition: vulkan_core.h:1889
@ VK_BLEND_OP_LIGHTEN_EXT
Definition: vulkan_core.h:1885
@ VK_BLEND_OP_HSL_HUE_EXT
Definition: vulkan_core.h:1900
@ VK_BLEND_OP_HSL_SATURATION_EXT
Definition: vulkan_core.h:1901
@ VK_BLEND_OP_SCREEN_EXT
Definition: vulkan_core.h:1882
@ VK_BLEND_OP_HSL_LUMINOSITY_EXT
Definition: vulkan_core.h:1903
@ VK_BLEND_OP_EXCLUSION_EXT
Definition: vulkan_core.h:1891
@ VK_BLEND_OP_COLORBURN_EXT
Definition: vulkan_core.h:1887
@ VK_BLEND_OP_DIFFERENCE_EXT
Definition: vulkan_core.h:1890
@ VK_BLEND_OP_REVERSE_SUBTRACT
Definition: vulkan_core.h:1866
#define VK_FALSE
Definition: vulkan_core.h:125
VkFlags VkPipelineLayoutCreateFlags
Definition: vulkan_core.h:2730
VkPrimitiveTopology
Definition: vulkan_core.h:2033
@ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST
Definition: vulkan_core.h:2037
@ VK_PRIMITIVE_TOPOLOGY_TRIANGLE_STRIP
Definition: vulkan_core.h:2038
@ VK_PRIMITIVE_TOPOLOGY_POINT_LIST
Definition: vulkan_core.h:2034
@ VK_FRONT_FACE_COUNTER_CLOCKWISE
Definition: vulkan_core.h:2022
VkResult
Definition: vulkan_core.h:140
@ VK_SUCCESS
Definition: vulkan_core.h:141
#define VK_NULL_HANDLE
Definition: vulkan_core.h:46
@ VK_VERTEX_INPUT_RATE_VERTEX
Definition: vulkan_core.h:2028
@ VK_VERTEX_INPUT_RATE_INSTANCE
Definition: vulkan_core.h:2029
@ VK_COLOR_COMPONENT_R_BIT
Definition: vulkan_core.h:2602
@ VK_COLOR_COMPONENT_A_BIT
Definition: vulkan_core.h:2605
@ VK_COLOR_COMPONENT_B_BIT
Definition: vulkan_core.h:2604
@ VK_COLOR_COMPONENT_G_BIT
Definition: vulkan_core.h:2603
VkFormat
Definition: vulkan_core.h:1458
@ VK_FORMAT_R16G16B16A16_UNORM
Definition: vulkan_core.h:1550
@ VK_FORMAT_R16G16_SFLOAT
Definition: vulkan_core.h:1542
@ VK_FORMAT_R32G32_SFLOAT
Definition: vulkan_core.h:1562
@ VK_FORMAT_R16_SFLOAT
Definition: vulkan_core.h:1535
@ VK_FORMAT_R32_SINT
Definition: vulkan_core.h:1558
@ VK_FORMAT_R16G16_UINT
Definition: vulkan_core.h:1540
@ VK_FORMAT_R8_UNORM
Definition: vulkan_core.h:1468
@ VK_FORMAT_R32G32B32A32_SFLOAT
Definition: vulkan_core.h:1568
@ VK_FORMAT_R32_SFLOAT
Definition: vulkan_core.h:1559
@ VK_FORMAT_R16G16B16A16_SINT
Definition: vulkan_core.h:1555
@ VK_FORMAT_R8G8B8A8_UNORM
Definition: vulkan_core.h:1496
@ VK_FORMAT_R16G16_SINT
Definition: vulkan_core.h:1541
@ VK_FORMAT_R8G8_SINT
Definition: vulkan_core.h:1480
@ VK_FORMAT_R32G32B32_SINT
Definition: vulkan_core.h:1564
@ VK_FORMAT_R16_UNORM
Definition: vulkan_core.h:1529
@ VK_FORMAT_R8_SINT
Definition: vulkan_core.h:1473
@ VK_FORMAT_R8_UINT
Definition: vulkan_core.h:1472
@ VK_FORMAT_R16G16B16A16_SFLOAT
Definition: vulkan_core.h:1556
@ VK_FORMAT_R16G16_UNORM
Definition: vulkan_core.h:1536
@ VK_FORMAT_R8G8B8A8_SINT
Definition: vulkan_core.h:1501
@ VK_FORMAT_R32G32B32A32_SINT
Definition: vulkan_core.h:1567
@ VK_FORMAT_R32G32B32_SFLOAT
Definition: vulkan_core.h:1565
@ VK_FORMAT_R8G8B8A8_UINT
Definition: vulkan_core.h:1500
@ VK_FORMAT_R8G8_UINT
Definition: vulkan_core.h:1479
@ VK_FORMAT_R32G32_SINT
Definition: vulkan_core.h:1561
@ VK_FORMAT_R32_UINT
Definition: vulkan_core.h:1557
VkBlendFactor
Definition: vulkan_core.h:1840
@ VK_BLEND_FACTOR_ONE
Definition: vulkan_core.h:1842
@ VK_BLEND_FACTOR_SRC1_ALPHA
Definition: vulkan_core.h:1858
@ VK_BLEND_FACTOR_ONE_MINUS_DST_ALPHA
Definition: vulkan_core.h:1850
@ VK_BLEND_FACTOR_ONE_MINUS_SRC1_COLOR
Definition: vulkan_core.h:1857
@ VK_BLEND_FACTOR_ONE_MINUS_SRC_COLOR
Definition: vulkan_core.h:1844
@ VK_BLEND_FACTOR_ONE_MINUS_CONSTANT_COLOR
Definition: vulkan_core.h:1852
@ VK_BLEND_FACTOR_SRC_COLOR
Definition: vulkan_core.h:1843
@ VK_BLEND_FACTOR_CONSTANT_COLOR
Definition: vulkan_core.h:1851
@ VK_BLEND_FACTOR_SRC_ALPHA
Definition: vulkan_core.h:1847
@ VK_BLEND_FACTOR_DST_ALPHA
Definition: vulkan_core.h:1849
@ VK_BLEND_FACTOR_ONE_MINUS_SRC1_ALPHA
Definition: vulkan_core.h:1859
@ VK_BLEND_FACTOR_ZERO
Definition: vulkan_core.h:1841
@ VK_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA
Definition: vulkan_core.h:1848
@ VK_BLEND_FACTOR_DST_COLOR
Definition: vulkan_core.h:1845
@ VK_BLEND_FACTOR_SRC1_COLOR
Definition: vulkan_core.h:1856
@ VK_BLEND_FACTOR_ONE_MINUS_DST_COLOR
Definition: vulkan_core.h:1846
@ VK_POLYGON_MODE_FILL
Definition: vulkan_core.h:2049
@ VK_POLYGON_MODE_LINE
Definition: vulkan_core.h:2050
@ VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO
Definition: vulkan_core.h:229
@ VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO
Definition: vulkan_core.h:228
@ VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO
Definition: vulkan_core.h:222
@ VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO
Definition: vulkan_core.h:232
@ VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO
Definition: vulkan_core.h:226
@ VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO
Definition: vulkan_core.h:225
@ VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
Definition: vulkan_core.h:220
@ VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO
Definition: vulkan_core.h:230
@ VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO
Definition: vulkan_core.h:224
@ VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO
Definition: vulkan_core.h:221
@ VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO
Definition: vulkan_core.h:227