@@ -143,41 +143,51 @@ class IPipelineLayout
143
143
}
144
144
145
145
// utility function, if you compile shaders for specific layouts, not create layouts given shaders
146
- using desc_type_bitset_t = std::bitset<static_cast <size_t >(IDescriptor::E_TYPE::ET_COUNT)>;
146
+ struct SBindingKey
147
+ {
148
+ using type_bitset_t = std::bitset<static_cast <size_t >(IDescriptor::E_TYPE::ET_COUNT)>;
149
+
150
+ hlsl::SBindingInfo binding = {};
151
+ core::bitflag<IShader::E_SHADER_STAGE> requiredStages = IShader::E_SHADER_STAGE::ESS_UNKNOWN;
152
+ // could have just initialized with `~type_bitset_t()` in C++23
153
+ type_bitset_t allowedTypes = type_bitset_t ((0x1u <<static_cast <size_t >(IDescriptor::E_TYPE::ET_COUNT))-1 );
154
+ };
147
155
// TODO: add constraints for stage and creation flags, or just return the storage index & redirect?
148
- core::string getBindingInfoForHLSL (const hlsl::SBindingInfo& info, const desc_type_bitset_t allowedTypes= desc_type_bitset_t ().set() ) const
156
+ core::string getBindingInfoForHLSL (const SBindingKey& key ) const
149
157
{
150
- if (info .set >=DESCRIPTOR_SET_COUNT)
151
- return " #error \" ::nbl::hlsl::SBindingInfo ::set out of range!\" " ;
152
- const auto * layout = m_descSetLayouts[info. set ];
158
+ if (key. binding .set >=DESCRIPTOR_SET_COUNT)
159
+ return " #error \" IPipelineLayout::SBindingKey::binding ::set out of range!\" " ;
160
+ const auto * layout = m_descSetLayouts[key. binding . set ]. get () ;
153
161
if (!layout)
154
- return " #error \" ::nbl::hlsl::SBindingInfo ::set layout is nullptr!\" " ;
162
+ return " #error \" IPipelineLayout::SBindingKey::binding ::set layout is nullptr!\" " ;
155
163
//
156
164
using redirect_t = IDescriptorSetLayoutBase::CBindingRedirect;
157
165
using storage_range_index_t = redirect_t ::storage_range_index_t ;
158
166
const redirect_t * redirect;
159
167
storage_range_index_t found;
160
168
{
161
- const redirect_t ::binding_number_t binding (info .binding );
169
+ const redirect_t ::binding_number_t binding (key. binding .binding );
162
170
for (auto t=0u ; t<static_cast <size_t >(IDescriptor::E_TYPE::ET_COUNT); t++)
163
- if (allowedTypes.test (t))
171
+ if (key. allowedTypes .test (t))
164
172
{
165
173
redirect = &layout->getDescriptorRedirect (static_cast <IDescriptor::E_TYPE>(t));
166
174
found = redirect->findBindingStorageIndex (binding);
167
175
if (found)
168
176
break ;
169
177
}
170
- if (!found && allowedTypes.test (static_cast <size_t >(IDescriptor::E_TYPE::ET_SAMPLER)))
178
+ if (!found && key. allowedTypes .test (static_cast <size_t >(IDescriptor::E_TYPE::ET_SAMPLER)))
171
179
{
172
180
redirect = &layout->getImmutableSamplerRedirect ();
173
181
found = redirect->findBindingStorageIndex (binding);
174
182
}
175
183
if (!found)
176
- return " #error \" Could not find `::nbl::hlsl::SBindingInfo:: binding` in `::nbl::hlsl::SBindingInfo ::set`'s layout!\" " ;
184
+ return " #error \" Could not find `IPipelineLayout::SBindingKey::binding:: binding` in `IPipelineLayout::SBindingKey::binding ::set`'s layout!\" " ;
177
185
}
186
+ if (redirect->getStageFlags (found).hasFlags (key.requiredStages ))
187
+ return " #error \" Binding found in the layout doesn't have all the `IPipelineLayout::SBindingKey::binding::requiredStages` flags!\" " ;
178
188
const auto count = redirect->getCount (found);
179
189
assert (count); // this layout should have never passed validation
180
- return " ::nbl::hlsl::ConstevalBindingInfo<" +std::to_string (info. set )+" ," +std::to_string (info .binding )+" ," +std::to_string (count)+" >" ;
190
+ return " ::nbl::hlsl::ConstevalBindingInfo<" +std::to_string (key. binding . set )+" ," +std::to_string (key. binding .binding )+" ," +std::to_string (count)+" >" ;
181
191
}
182
192
183
193
protected:
0 commit comments