Drawing a triangle/Graphics pipeline basics/Conclusion

我们现在可以结合前面章节中的所有结构和对象来创建图形管道!以下是我们现在拥有的对象类型,作为快速回顾:

  • 着色器阶段:定义图形管道可编程阶段功能的着色器模块
  • 固定功能状态:定义管道固定功能阶段的所有结构,如输入装配、光栅化器、视口和颜色混合
  • 管道布局:着色器引用的可在绘制时更新的统一值和推送值
  • 渲染过程:管道阶段引用的附件及其用法

所有这些组合完全定义了图形管道的功能,因此我们现在可以在createGraphicsPipeline函数的末尾填充VkGraphicsPipelineCreateInfo结构。但在调用vkDestroyShaderModule之前,因为在创建过程中仍将使用这些。

VkGraphicsPipelineCreateInfo pipelineInfo{};
pipelineInfo.sType = VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO;
pipelineInfo.stageCount = 2;
pipelineInfo.pStages = shaderStages;

我们首先引用VkPipelineShaderStageCreateInfo结构的数组。

pipelineInfo.pVertexInputState = &vertexInputInfo;
pipelineInfo.pInputAssemblyState = &inputAssembly;
pipelineInfo.pViewportState = &viewportState;
pipelineInfo.pRasterizationState = &rasterizer;
pipelineInfo.pMultisampleState = &multisampling;
pipelineInfo.pDepthStencilState = nullptr; // Optional
pipelineInfo.pColorBlendState = &colorBlending;
pipelineInfo.pDynamicState = &dynamicState;

然后我们引用描述固定功能阶段的所有结构。

pipelineInfo.layout = pipelineLayout;

之后是管道布局,它是一个Vulkan句柄,而不是一个结构指针。

pipelineInfo.renderPass = renderPass;
pipelineInfo.subpass = 0;

最后,我们有了对渲染过程的引用和将使用此图形管道的子过程的索引。也可以将其他渲染过程用于此管道而不是此特定实例,但它们必须与renderPass兼容。这里描述了兼容性的要求,但我们不会在本教程中使用该功能。

pipelineInfo.basePipelineHandle = VK_NULL_HANDLE; // Optional
pipelineInfo.basePipelineIndex = -1; // Optional

实际上还有两个参数:basePipelineHandle和basePipelineIndex。Vulkan允许您通过从现有管道派生来创建新的图形管道。管道衍生产品的理念是,当管道与现有管道具有许多共同功能时,设置管道的成本较低,并且在来自同一父管道的管道之间进行切换也可以更快。您可以使用basePipelineHandle指定现有管道的句柄,也可以使用basePipelineIndex引用将由索引创建的另一个管道。现在只有一个管道,所以我们只需指定一个空句柄和一个无效索引。只有在VkGraphicsPipelineCreateInfo的标志字段中也指定了VK_PIPELINE_CREATE_DERIVATIVE_BIT标志时,才使用这些值。

现在通过创建一个类成员来保存VkPipeline对象来准备最后一步:

VkPipeline graphicsPipeline;

最后创建图形管道:

if (vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipelineInfo, nullptr, &graphicsPipeline) != VK_SUCCESS) {
    throw std::runtime_error("failed to create graphics pipeline!");
}

vkCreateGraphicsPipelines函数实际上比Vulkan中常用的对象创建函数具有更多的参数。它被设计为在一次调用中获取多个VkGraphicsPipelineCreateInfo对象并创建多个VkPipeline对象。

第二个参数(我们已为其传递了VK_NULL_HANDLE参数)引用了可选的VkPipelineCache对象。管道缓存可用于存储和重用与多个调用vkCreateGraphicsPPipelines的管道创建相关的数据,如果缓存存储到文件中,甚至可以跨程序执行。这使得以后可以显著加快管道创建速度。我们将在管道缓存一章中讨论这个问题。

所有常见的绘图操作都需要图形管道,因此它也只能在程序结束时销毁:

void cleanup() {
    vkDestroyPipeline(device, graphicsPipeline, nullptr);
    vkDestroyPipelineLayout(device, pipelineLayout, nullptr);
    ...
}

现在运行您的程序,以确认所有这些艰苦的工作都已成功创建了管道!我们已经很接近看到屏幕上出现了一些东西。在接下来的几章中,我们将从交换链图像设置实际的帧缓冲区,并准备绘制命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值