@@ -143,41 +143,51 @@ class IPipelineLayout
143143 }
144144
145145 // 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+ };
147155 // 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
149157 {
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 () ;
153161 if (!layout)
154- return " #error \" ::nbl::hlsl::SBindingInfo ::set layout is nullptr!\" " ;
162+ return " #error \" IPipelineLayout::SBindingKey::binding ::set layout is nullptr!\" " ;
155163 //
156164 using redirect_t = IDescriptorSetLayoutBase::CBindingRedirect;
157165 using storage_range_index_t = redirect_t ::storage_range_index_t ;
158166 const redirect_t * redirect;
159167 storage_range_index_t found;
160168 {
161- const redirect_t ::binding_number_t binding (info .binding );
169+ const redirect_t ::binding_number_t binding (key. binding .binding );
162170 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))
164172 {
165173 redirect = &layout->getDescriptorRedirect (static_cast <IDescriptor::E_TYPE>(t));
166174 found = redirect->findBindingStorageIndex (binding);
167175 if (found)
168176 break ;
169177 }
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)))
171179 {
172180 redirect = &layout->getImmutableSamplerRedirect ();
173181 found = redirect->findBindingStorageIndex (binding);
174182 }
175183 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!\" " ;
177185 }
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!\" " ;
178188 const auto count = redirect->getCount (found);
179189 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)+" >" ;
181191 }
182192
183193 protected:
0 commit comments