08/18/2020
特化常量(Specialization constants)
VkPipelineShaderStageCreateInfo的最后一个字段是一个指向结构体VkSpecializationInfo的实例的指针。这个结构体包含特化一个着色器所需的信息,“特化”是指构建着色器时将一些常量编译进去。
应用
- 通过分支产生特殊执行路:在一个布尔特化常量上包含一个条件将导致最终着色器只运行条件语句的一个分支。没有采用的分支将有可能被优化掉。如果你有两个相似的着色器,两者只有很少几处地方不同,那么这是一种将它们合并为一个着色器的办法。请见下面的例子
- 通过Switch语句产生的特殊情形:
- 循环展开
- 常量折叠
- 运算符简化
特化常量数据
把下面的数据传入到片元着色器中
- 一个结构体,两个成员变量,一个光模型,另一个关于减饱和度
// Host data to take specialization constants from
struct SpecializationData {
// Sets the lighting model used in the fragment "uber" shader
uint32_t lightingModel;
// Parameter for the toon shading part of the fragment shader
float toonDesaturationFactor = 0.5f;
} specializationData;
创建特化常量
- VkSpecializationMapEntry
- pShaderStage: 与着色器模块有关
- 设置实际数据在创建管道之前
struct SpecializationData {
// Sets the lighting model used in the fragment "uber" shader
uint32_t lightingModel;
// Parameter for the toon shading part of the fragment shader
float toonDesaturationFactor = 0.5f; //赋值
} specializationData;
std::array<VkSpecializationMapEntry, 2> specializationMapEntries;
//着色器声明部分
// layout (constant_id = 0) const int LIGHTING_MODEL = 0;
// layout (constant_id = 1) const float PARAM_TOON_DESATURATION = 0.0f;
specializationMapEntries[0].constantID = 0;
specializationMapEntries[0].size = sizeof(specializationData.lightingModel);
specializationMapEntries[0].offset = 0;
specializationMapEntries[1].constantID = 1;
specializationMapEntries[1].size = sizeof(specializationData.toonDesaturationFactor);
specializationMapEntries[1].offset = offsetof(SpecializationData, toonDesaturationFactor);