]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/program.cpp
Always set uniform array size to at least one
[libs/gl.git] / source / core / program.cpp
index 5c8257b2fc60de50bf0e767beb90a5f8da5784e2..476a9c7d6aba319c9e42cb3fd345a0a889d014aa 100644 (file)
@@ -17,6 +17,8 @@ void Program::add_stages(const Module &mod, const map<string, int> &spec_values)
        if(has_stages())
                throw invalid_operation("Program::add_stages");
 
+       reflect_data = ReflectData();
+
        TransientData transient;
        switch(mod.get_format())
        {
@@ -30,28 +32,15 @@ void Program::add_stages(const Module &mod, const map<string, int> &spec_values)
                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<const SpirVModule &>(mod), transient.spec_values);
                collect_attributes(static_cast<const SpirVModule &>(mod));
        }
 
-       for(ReflectData::UniformBlockInfo &b: reflect_data.uniform_blocks)
-               if(!b.data_size && !b.uniforms.empty())
-               {
-                       const ReflectData::UniformInfo &uni = *b.uniforms.back();
-                       b.data_size = uni.location*16+uni.array_size*get_type_size(uni.type);
-               }
+       finalize_uniforms();
 
        for(const ReflectData::UniformInfo &u: reflect_data.uniforms)
                require_type(u.type);
@@ -90,7 +79,7 @@ void Program::collect_uniforms(const SpirVModule &mod, const map<unsigned, int>
                        info.tag = v.name;
                        info.location = v.location;
                        info.binding = v.binding;
-                       info.array_size = v.array_size;
+                       info.array_size = max(v.array_size, 1U);
                        info.type = v.type;
                }
        }
@@ -147,7 +136,7 @@ void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const
                        info.name = name;
                        info.tag = name;
                        info.offset = offset;
-                       info.array_size = m.array_size;
+                       info.array_size = max(m.array_size, 1U);
                        info.array_stride = m.array_stride;
                        info.matrix_stride = m.matrix_stride;
                        info.type = m.type;
@@ -173,6 +162,20 @@ void Program::collect_attributes(const SpirVModule &mod)
                }
 }
 
+void Program::collect_builtins(const SpirVModule &mod)
+{
+       for(const SpirVModule::Variable &v: mod.get_variables())
+               if(v.storage==SpirVModule::OUTPUT && v.struct_type)
+                       collect_builtins(*v.struct_type);
+}
+
+void Program::collect_builtins(const SpirVModule::Structure &strct)
+{
+       for(const SpirVModule::StructMember &m: strct.members)
+               if(m.builtin==SpirVModule::CLIP_DISTANCE)
+                       reflect_data.n_clip_distances = m.array_size;
+}
+
 const ReflectData::UniformBlockInfo &Program::get_uniform_block_info(const string &name) const
 {
        auto i = find_member(reflect_data.uniform_blocks, name, &ReflectData::UniformBlockInfo::name);