X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fcore%2Fprogram.cpp;fp=source%2Fcore%2Fprogram.cpp;h=fdbfa6d4be08004f38be801c3a46c69ae0745b04;hb=fbfd4b52102e06398ff162be07d6799f005a04a8;hp=acdb20e88a5488063c3778a598af10f411b1b541;hpb=4f79ac1988e401b5242db437caccc0a98cf5dba1;p=libs%2Fgl.git diff --git a/source/core/program.cpp b/source/core/program.cpp index acdb20e8..fdbfa6d4 100644 --- a/source/core/program.cpp +++ b/source/core/program.cpp @@ -36,9 +36,11 @@ void Program::add_stages(const Module &mod, const map &spec_values) if(mod.get_format()==Module::SPIR_V) { - collect_uniforms(static_cast(mod)); - collect_attributes(static_cast(mod)); - collect_builtins(static_cast(mod)); + const SpirVModule &spirv_mod = static_cast(mod); + vector used_variables = collect_used_variables(spirv_mod, spec_values); + collect_uniforms(spirv_mod, used_variables); + collect_attributes(spirv_mod, used_variables); + collect_builtins(spirv_mod); } finalize_uniforms(); @@ -49,15 +51,79 @@ void Program::add_stages(const Module &mod, const map &spec_values) require_type(a.type); } -void Program::collect_uniforms(const SpirVModule &mod) +vector Program::collect_used_variables(const SpirVModule &mod, const map &spec_values) +{ + std::map spec_values_by_id; + for(const SpirVModule::Constant &c: mod.get_spec_constants()) + { + auto i = spec_values.find(c.name); + if(i!=spec_values.end()) + spec_values_by_id[c.constant_id] = i->second; + } + + const vector &blocks = mod.get_blocks(); + vector visited(blocks.size(), 4); + for(unsigned i=0; ii_value; + auto j = spec_values_by_id.find(b.condition->constant_id); + if(j!=spec_values_by_id.end()) + cond = j->second; + if(b.negate_condition) + cond = !cond; + } + + visited[i] |= cond*2; + for(const SpirVModule::InstructionBlock *s: b.successors) + visited[s-blocks.data()] &= 3; + } + + for(unsigned i=0; i &variables = mod.get_variables(); + vector used(variables.size()); + for(unsigned i=0; i &blocks, unsigned i, vector &visited) +{ + visited[i] |= 1; + for(const SpirVModule::InstructionBlock *s: blocks[i].successors) + { + unsigned j = s-blocks.data(); + if((visited[j]&3)==2) + collect_visited_blocks(blocks, j, visited); + } +} + +void Program::collect_uniforms(const SpirVModule &mod, const vector &used_variables) { // Prepare the default block reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo()); vector > block_uniform_names(1); + const vector &variables = mod.get_variables(); unsigned n_descriptor_sets = 0; - for(const SpirVModule::Variable &v: mod.get_variables()) + for(unsigned i=0; i &used_variables) { + const vector &variables = mod.get_variables(); for(const SpirVModule::EntryPoint &e: mod.get_entry_points()) if(e.stage==SpirVModule::VERTEX && e.name=="main") { for(const SpirVModule::Variable *v: e.globals) - if(v->storage==SpirVModule::INPUT) + if(v->storage==SpirVModule::INPUT && used_variables[v-variables.data()]) { reflect_data.attributes.push_back(ReflectData::AttributeInfo()); ReflectData::AttributeInfo &info = reflect_data.attributes.back();