X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fcore%2Fprogram.cpp;h=acdb20e88a5488063c3778a598af10f411b1b541;hp=6458b4779d396ae3fe5072f4ec9381c1ba4b05e3;hb=7ef75a4c4dbfc437e466381dd67c23357e607b82;hpb=160e9eea29bd10034733d59507fa1bcca36be401 diff --git a/source/core/program.cpp b/source/core/program.cpp index 6458b477..acdb20e8 100644 --- a/source/core/program.cpp +++ b/source/core/program.cpp @@ -17,6 +17,8 @@ void Program::add_stages(const Module &mod, const map &spec_values) if(has_stages()) throw invalid_operation("Program::add_stages"); + reflect_data = ReflectData(); + TransientData transient; switch(mod.get_format()) { @@ -24,55 +26,60 @@ void Program::add_stages(const Module &mod, const map &spec_values) add_glsl_stages(static_cast(mod), spec_values, transient); break; case Module::SPIR_V: - add_spirv_stages(static_cast(mod), spec_values, transient); + add_spirv_stages(static_cast(mod), spec_values); break; default: throw invalid_argument("Program::add_stages"); } - reflect_data = ReflectData(); - - finalize(mod); + finalize(mod, transient); - if(mod.get_format()==Module::GLSL) - { - query_uniforms(); - query_attributes(); - apply_bindings(transient); - } - else if(mod.get_format()==Module::SPIR_V) + if(mod.get_format()==Module::SPIR_V) { - collect_uniforms(static_cast(mod), transient.spec_values); + collect_uniforms(static_cast(mod)); collect_attributes(static_cast(mod)); + collect_builtins(static_cast(mod)); } + finalize_uniforms(); + for(const ReflectData::UniformInfo &u: reflect_data.uniforms) require_type(u.type); for(const ReflectData::AttributeInfo &a: reflect_data.attributes) require_type(a.type); } -void Program::collect_uniforms(const SpirVModule &mod, const map &spec_values) +void Program::collect_uniforms(const SpirVModule &mod) { // Prepare the default block reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo()); vector > block_uniform_names(1); + unsigned n_descriptor_sets = 0; for(const SpirVModule::Variable &v: mod.get_variables()) { - if(v.storage==SpirVModule::UNIFORM && v.struct_type) + if((v.storage==SpirVModule::UNIFORM || v.storage==SpirVModule::PUSH_CONSTANT) && v.struct_type) { reflect_data.uniform_blocks.push_back(ReflectData::UniformBlockInfo()); ReflectData::UniformBlockInfo &info = reflect_data.uniform_blocks.back(); info.name = v.struct_type->name; - info.bind_point = v.binding; + if(v.storage==SpirVModule::PUSH_CONSTANT) + info.bind_point = ReflectData::PUSH_CONSTANT; + else + { + if(v.binding>=0) + info.bind_point = v.binding | (v.descriptor_set<<20); + else + info.bind_point = ReflectData::DEFAULT_BLOCK; + n_descriptor_sets = max(n_descriptor_sets, v.descriptor_set+1); + } info.data_size = v.struct_type->size; string prefix; if(!v.name.empty()) prefix = v.struct_type->name+"."; block_uniform_names.push_back(vector()); - collect_block_uniforms(*v.struct_type, prefix, 0, spec_values, block_uniform_names.back()); + collect_block_uniforms(*v.struct_type, prefix, 0, block_uniform_names.back()); } else if(v.storage==SpirVModule::UNIFORM_CONSTANT && v.location>=0) { @@ -82,14 +89,22 @@ void Program::collect_uniforms(const SpirVModule &mod, const map info.name = v.name; info.tag = v.name; info.location = v.location; - info.binding = v.binding; - info.array_size = v.array_size; + if(v.binding>=0) + info.binding = v.binding | (v.descriptor_set<<20); + n_descriptor_sets = max(n_descriptor_sets, v.descriptor_set+1); + info.array_size = max(v.array_size, 1U); info.type = v.type; } } sort_member(reflect_data.uniforms, &ReflectData::UniformInfo::tag); + if(block_uniform_names.front().empty()) + { + reflect_data.uniform_blocks.erase(reflect_data.uniform_blocks.begin()); + block_uniform_names.erase(block_uniform_names.begin()); + } + for(unsigned i=0; i block.update_layout_hash(); } + reflect_data.n_descriptor_sets = n_descriptor_sets; reflect_data.update_layout_hash(); } -void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const string &prefix, unsigned base_offset, const map &spec_values, vector &uniform_names) +void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const string &prefix, unsigned base_offset, vector &uniform_names) { for(const SpirVModule::StructMember &m: strct.members) { unsigned offset = base_offset+m.offset; if(m.struct_type) { - unsigned array_size = m.array_size; - if(m.array_size_spec) - { - array_size = m.array_size_spec->i_value; - auto j = spec_values.find(m.array_size_spec->constant_id); - if(j!=spec_values.end()) - array_size = j->second; - } - - if(array_size) + if(m.array_size) { - for(unsigned j=0; j