@@ -107,43 +107,53 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
107
107
return shaders[index].shader ->getStage ();
108
108
};
109
109
110
- if (shaderGroups.raygen .index >= shaders.size ())
111
- return false ;
112
- if (getShaderStage (shaderGroups.raygen .index ) != ICPUShader::E_SHADER_STAGE::ESS_RAYGEN)
113
- return false ;
114
-
115
- auto isValidShaderIndex = [this , getShaderStage](size_t index, ICPUShader::E_SHADER_STAGE expectedStage) -> bool
110
+ auto isValidShaderIndex = [this , getShaderStage](size_t index, ICPUShader::E_SHADER_STAGE expectedStage, bool is_unused_shader_forbidden) -> bool
116
111
{
117
112
if (index == SShaderGroupsParams::SIndex::Unused)
118
- return true ;
113
+ return !is_unused_shader_forbidden ;
119
114
if (index >= shaders.size ())
120
115
return false ;
121
116
if (getShaderStage (index) != expectedStage)
122
117
return false ;
123
118
return true ;
124
119
};
125
120
121
+ if (isValidShaderIndex (shaderGroups.raygen .index , ICPUShader::E_SHADER_STAGE::ESS_RAYGEN, true ))
122
+ {
123
+ return false ;
124
+ }
125
+
126
126
for (const auto & shaderGroup : shaderGroups.hits )
127
127
{
128
- if (!isValidShaderIndex (shaderGroup.anyHit , ICPUShader::E_SHADER_STAGE::ESS_ANY_HIT))
128
+ // https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkRayTracingPipelineCreateInfoKHR-flags-03470
129
+ if (!isValidShaderIndex (shaderGroup.anyHit ,
130
+ ICPUShader::E_SHADER_STAGE::ESS_ANY_HIT,
131
+ bool (flags & FLAGS::NO_NULL_ANY_HIT_SHADERS)))
129
132
return false ;
130
133
131
- if (!isValidShaderIndex (shaderGroup.closestHit , ICPUShader::E_SHADER_STAGE::ESS_CLOSEST_HIT))
134
+ // https://docs.vulkan.org/spec/latest/chapters/pipelines.html#VUID-VkRayTracingPipelineCreateInfoKHR-flags-03471
135
+ if (!isValidShaderIndex (shaderGroup.closestHit ,
136
+ ICPUShader::E_SHADER_STAGE::ESS_CLOSEST_HIT,
137
+ bool (flags & FLAGS::NO_NULL_CLOSEST_HIT_SHADERS)))
132
138
return false ;
133
139
134
- if (!isValidShaderIndex (shaderGroup.intersectionShader , ICPUShader::E_SHADER_STAGE::ESS_INTERSECTION))
140
+ if (!isValidShaderIndex (shaderGroup.intersectionShader ,
141
+ ICPUShader::E_SHADER_STAGE::ESS_INTERSECTION,
142
+ false ))
135
143
return false ;
136
144
}
137
145
138
146
for (const auto & shaderGroup : shaderGroups.misses )
139
147
{
140
- if (!isValidShaderIndex (shaderGroup.index , ICPUShader::E_SHADER_STAGE::ESS_MISS))
148
+ if (!isValidShaderIndex (shaderGroup.index ,
149
+ ICPUShader::E_SHADER_STAGE::ESS_MISS,
150
+ false ))
141
151
return false ;
142
152
}
143
153
144
154
for (const auto & shaderGroup : shaderGroups.callables )
145
155
{
146
- if (!isValidShaderIndex (shaderGroup.index , ICPUShader::E_SHADER_STAGE::ESS_CALLABLE))
156
+ if (!isValidShaderIndex (shaderGroup.index , ICPUShader::E_SHADER_STAGE::ESS_CALLABLE, false ))
147
157
return false ;
148
158
}
149
159
return true ;
@@ -163,6 +173,8 @@ class IRayTracingPipeline : public IPipeline<PipelineLayoutType>, public IRayTra
163
173
std::span<const SpecInfo> shaders = {};
164
174
SShaderGroupsParams shaderGroups;
165
175
SCachedCreationParams cached = {};
176
+ // TODO: Could guess the required flags from SPIR-V introspection of declared caps
177
+ core::bitflag<FLAGS> flags = FLAGS::NONE;
166
178
};
167
179
168
180
inline const SCachedCreationParams& getCachedCreationParams () const { return m_params; }
0 commit comments