指定管线着色器阶段
译者注:示例代码点击此处
在计算管线中,我们只能使用计算着色器。 但图形管线可能包含多个着色器阶段 - 顶点(这是必须的),几何,曲面细分控制和评估以及片段。 因此,为了正确创建管线,我们需要指定当给定管线绑定到命令缓冲区时,哪些可编程着色器阶段将处于活动状态。 我们还需要为所有启用的着色器提供源代码。
做好准备
为了简化内容并减少准备所启用的着色器阶段描述所需的参数数量,引入了自定义ShaderStageParameters类型。 它具有以下定义:
structShaderStageParameters {
VkShaderStageFlagBits ShaderStage;
VkShaderModule ShaderModule;
char const * EntryPointName;
VkSpecializationInfo const * SpecializationInfo;
};
在前面的结构中,ShaderStage定义了一个管线阶段,其中指定了其余的参数。 ShaderModule是一个模块,可以从该模块获取给定阶段的SPIR-V源代码,并与EntryPointName成员中提供名称的函数关联。 SpecializationInfo参数是指向VkSpecializationInfo类型的变量的指针。 它允许在管线创建期间在运行时修改着色器源代码中定义的常量变量的值。 但是如果我们不想指定常量值,我们可以提供nullptr值。
怎么做...
1.为每个将在给定管道中处于活动状态的着色器阶段创建一个或多个包含源代码的着色器模块(请参阅创建着色器模块内容)。
2.创建一个名为shader_stage_create_infos的std::vector<VkPipelineShaderStageCreateInfo>类型变量。
3.对于应在给定管线中启用的每个着色器阶段,生成一个元素添加到shader_stage_create_infos向量并使用以下值初始化其成员:
·sType为VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO
·pNext为nullptr
·flags为0
·stage为选定的着色器阶段
·module为具有给定着色器阶段的源代码的着色器模块
·pName为着色器模块中实现给定着色器的函数入口的名称(通常为main)。
·pSpecializationInfo如果需要特化设置VkSpecializationInfo类型变量的指针,否则设置nullptr。
这个怎么运作...
定义将在给定管线中处于活动状态的一组着色器阶段需要我们使用VkPipelineShaderStageCreateInfo类型的元素准备数组(或向量)变量。 每个着色器阶段都需要一个单独的条目,我们需要在其中指定着色器模块以及在提供的模块中实现给定着色器行为的入口点的名称。 我们还可以提供指向特化信息的指针,该指针允许我们在管道创建期间(运行时)修改着色器常量变量的值。 这允许我们多次使用相同的着色器代码,只有轻微的变化。
提示:指定管线着色器阶段信息对于图形和计算管线都是必需的。
假设我们只想使用顶点和片段着色。我们可以准备一个带有自定义shaderstageParameters类型的元素的向量,如下所示:
std::vector<ShaderStageParameters>shader_stage_params
{
VK_SHADER_STAGE_VERTEX_BIT,
*vertex_shader_module,
"main",
nullptr
},
{
VK_SHADER_STAGE_FRAGMENT_BIT,
*fragment_shader_module,
"main",
nullptr
}
};
使用上述向量中的数据的前一节内容的实现可能如下所示:
shader_stage_create_infos.clear();
for( auto & shader_stage : shader_stage_params ) {
shader_stage_create_infos.push_back( {
VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
nullptr,
0,
shader_stage.ShaderStage,
shader_stage.ShaderModule,
shader_stage.EntryPointName,
shader_stage.SpecializationInfo
} );
}
提示:数组中提供的每个着色器阶段都必须是唯一的。