}
-void LocationAllocator::apply(Module &module, const Features &features, bool a)
+void LocationAllocator::apply(Module &module, const Features &f, bool a)
{
+ features = f;
alloc_new = a;
for(Stage &s: module.stages)
apply(s);
void LocationAllocator::bind_uniform(RefPtr<Layout> &layout, const string &name, unsigned range)
{
auto i = uniforms.find(name);
+
+ int desc_set = (i!=uniforms.end() ? i->second.desc_set : 0);
+ if(features.target_api==VULKAN && get_layout_value(layout.get(), "set")<0)
+ add_layout_qualifier(layout, Layout::Qualifier("set", desc_set));
+
if(i!=uniforms.end() && i->second.bind_point>=0)
add_layout_qualifier(layout, Layout::Qualifier("binding", i->second.bind_point));
else if(alloc_new)
{
- set<unsigned> &used = used_bindings[0];
+ set<unsigned> &used = used_bindings[desc_set];
unsigned bind_point = fold32(hash64(name))%range;
while(used.count(bind_point))
bool LocationAllocator::visit_uniform(const string &name, RefPtr<Layout> &layout)
{
+ int desc_set = 0;
int bind_point = get_layout_value(layout.get(), "binding");
+
+ if(features.target_api==VULKAN)
+ {
+ desc_set = get_layout_value(layout.get(), "set");
+ if(desc_set<0 && bind_point>=0)
+ {
+ desc_set = 0;
+ add_layout_qualifier(layout, Layout::Qualifier("set", desc_set));
+ }
+
+ if(desc_set>=0)
+ uniforms[name].desc_set = desc_set;
+ }
+
if(bind_point>=0)
{
- used_bindings[0].insert(bind_point);
+ used_bindings[desc_set].insert(bind_point);
uniforms[name].bind_point = bind_point;
}
+
return bind_point>=0;
}
int desc_set;
int bind_point;
- Uniform(): location(-1), desc_set(-1), bind_point(-1) { }
+ Uniform(): location(-1), desc_set(0), bind_point(-1) { }
};
+ Features features;
bool alloc_new = true;
std::map<std::string, std::set<unsigned> > used_locations;
std::map<std::string, Uniform> uniforms;
error(*uni.node, format("Mismatched location %d for uniform '%s'", uni.location, uni.name));
add_info(*i->second->node, format("Previously declared here with location %d", i->second->location));
}
+ if(i->second->desc_set!=uni.desc_set)
+ {
+ error(*uni.node, format("Mismatched descriptor set %d for uniform '%s'", uni.desc_set, uni.name));
+ add_info(*i->second->node, format("Previously declared here with descriptor set %d", i->second->desc_set));
+ }
if(uni.bind_point>=0 && i->second->bind_point>=0 && i->second->bind_point!=uni.bind_point)
{
error(*uni.node, format("Mismatched binding %d for uniform '%s'", uni.bind_point, uni.name));