]> git.tdb.fi Git - libs/gl.git/blobdiff - source/core/program.cpp
Handle SPIR-V arrays with specialization constant for size
[libs/gl.git] / source / core / program.cpp
index 81da5b96e7b50fd858e6a82d4017412711b9bb97..038c031393ae33a5fcaeee27a1c00910f5da0c3c 100644 (file)
@@ -214,6 +214,9 @@ void Program::add_spirv_stages(const SpirVModule &mod, const map<string, int> &s
        const vector<UInt32> &code = mod.get_code();
        glShaderBinary(stage_ids.size(), &stage_ids[0], GL_SHADER_BINARY_FORMAT_SPIR_V, &code[0], code.size()*4);
 
+       if(!spec_values.empty() && !transient)
+               transient = new TransientData;
+
        const vector<SpirVModule::Constant> &spec_consts = mod.get_spec_constants();
        vector<unsigned> spec_id_array;
        vector<unsigned> spec_value_array;
@@ -226,6 +229,7 @@ void Program::add_spirv_stages(const SpirVModule &mod, const map<string, int> &s
                {
                        spec_id_array.push_back(i->constant_id);
                        spec_value_array.push_back(j->second);
+                       transient->spec_values[i->constant_id] = j->second;
                }
        }
 
@@ -333,9 +337,6 @@ void Program::link()
                                                glUniform1i(location, i->second);
                                }
                        }
-
-                       delete transient;
-                       transient = 0;
                }
        }
        else if(module->get_format()==Module::SPIR_V)
@@ -344,6 +345,9 @@ void Program::link()
                collect_attributes();
        }
 
+       delete transient;
+       transient = 0;
+
        for(vector<UniformInfo>::const_iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
                require_type(i->type);
        for(vector<AttributeInfo>::const_iterator i=attributes.begin(); i!=attributes.end(); ++i)
@@ -570,9 +574,21 @@ void Program::collect_block_uniforms(const SpirVModule::Structure &strct, const
                unsigned offset = base_offset+i->offset;
                if(i->struct_type)
                {
-                       if(i->array_size)
+                       unsigned array_size = i->array_size;
+                       if(i->array_size_spec)
+                       {
+                               array_size = i->array_size_spec->i_value;
+                               if(transient)
+                               {
+                                       map<unsigned, int>::const_iterator j = transient->spec_values.find(i->array_size_spec->constant_id);
+                                       if(j!=transient->spec_values.end())
+                                               array_size = j->second;
+                               }
+                       }
+
+                       if(array_size)
                        {
-                               for(unsigned j=0; j<i->array_size; ++j, offset+=i->array_stride)
+                               for(unsigned j=0; j<array_size; ++j, offset+=i->array_stride)
                                        collect_block_uniforms(*i->struct_type, format("%s%s[%d].", prefix, i->name, j), offset, uniform_names);
                        }
                        else