]> git.tdb.fi Git - libs/gl.git/blobdiff - source/program.cpp
Sort the uniforms in Program::UniformBlockInfo by offset
[libs/gl.git] / source / program.cpp
index 40a388191e650ef83cb71bc7f3d976027b6b7e80..d962751994d38fe1e7fd93550bb51a545eaec9f6 100644 (file)
@@ -251,20 +251,20 @@ void Program::link()
                if(len && strncmp(name, "gl_", 3))
                {
                        UniformInfo &info = uniforms[name];
+                       info.block = 0;
                        info.name = name;
                        info.size = size;
+                       info.array_stride = 0;
+                       info.matrix_stride = 0;
                        info.type = type;
                        uniforms_by_index[i] = &info;
                }
        }
 
-       vector<const UniformInfo *> blockless_uniforms;
-
        if(is_supported("GL_ARB_uniform_buffer_object"))
        {
                glGetObjectParameterivARB(id, GL_ACTIVE_UNIFORM_BLOCKS, &value);
                count = value;
-               vector<bool> uniforms_in_blocks(uniforms_by_index.size());
                for(unsigned i=0; i<count; ++i)
                {
                        char name[128];
@@ -284,7 +284,7 @@ void Program::link()
                                if(!uniforms_by_index[*j])
                                        throw logic_error("Program::link");
                                info.uniforms.push_back(uniforms_by_index[*j]);
-                               uniforms_in_blocks[*j] = true;
+                               uniforms_by_index[*j]->block = &info;
                        }
 
                        vector<unsigned> indices2(indices.begin(), indices.end());
@@ -297,9 +297,12 @@ void Program::link()
                        for(vector<int>::iterator j=indices.begin(); j!=indices.end(); ++j)
                                if(uniforms_by_index[*j]->size>1)
                                        indices2.push_back(*j);
-                       glGetActiveUniformsiv(id, indices2.size(), &indices2[0], GL_UNIFORM_ARRAY_STRIDE, &values[0]);
-                       for(unsigned j=0; j<indices2.size(); ++j)
-                               uniforms_by_index[indices[j]]->array_stride = values[j];
+                       if(!indices2.empty())
+                       {
+                               glGetActiveUniformsiv(id, indices2.size(), &indices2[0], GL_UNIFORM_ARRAY_STRIDE, &values[0]);
+                               for(unsigned j=0; j<indices2.size(); ++j)
+                                       uniforms_by_index[indices[j]]->array_stride = values[j];
+                       }
 
                        indices2.clear();
                        for(vector<int>::iterator j=indices.begin(); j!=indices.end(); ++j)
@@ -310,31 +313,27 @@ void Program::link()
                                        t==GL_FLOAT_MAT3x4 || t==GL_FLOAT_MAT4x2 || t==GL_FLOAT_MAT4x3)
                                        indices2.push_back(*j);
                        }
-                       glGetActiveUniformsiv(id, indices2.size(), &indices2[0], GL_UNIFORM_MATRIX_STRIDE, &values[0]);
-                       for(unsigned j=0; j<indices2.size(); ++j)
-                               uniforms_by_index[indices[j]]->matrix_stride = values[j];
+                       if(!indices2.empty())
+                       {
+                               glGetActiveUniformsiv(id, indices2.size(), &indices2[0], GL_UNIFORM_MATRIX_STRIDE, &values[0]);
+                               for(unsigned j=0; j<indices2.size(); ++j)
+                                       uniforms_by_index[indices[j]]->matrix_stride = values[j];
+                       }
 
+                       sort(info.uniforms.begin(), info.uniforms.end(), uniform_location_compare);
                        info.layout_hash = compute_layout_hash(info.uniforms);
                        info.bind_point = info.layout_hash%BufferRange::get_n_uniform_buffer_bindings();
                        glUniformBlockBinding(id, i, info.bind_point);
                }
-
-               for(unsigned i=0; i<uniforms_by_index.size(); ++i)
-                       if(uniforms_by_index[i] && !uniforms_in_blocks[i])
-                       {
-                               UniformInfo *info = uniforms_by_index[i];
-                               info->location = glGetUniformLocationARB(id, info->name.c_str());
-                               blockless_uniforms.push_back(info);
-                       }
        }
-       else
-       {
-               for(UniformMap::iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
+
+       vector<const UniformInfo *> blockless_uniforms;
+       for(UniformMap::iterator i=uniforms.begin(); i!=uniforms.end(); ++i)
+               if(!i->second.block)
                {
                        i->second.location = glGetUniformLocationARB(id, i->second.name.c_str());
                        blockless_uniforms.push_back(&i->second);
                }
-       }
 
        uniform_layout_hash = compute_layout_hash(blockless_uniforms);
 }
@@ -347,6 +346,11 @@ unsigned Program::compute_layout_hash(const vector<const UniformInfo *> &uniform
        return hash32(layout_descriptor);
 }
 
+bool Program::uniform_location_compare(const UniformInfo *uni1, const UniformInfo *uni2)
+{
+       return uni1->location<uni2->location;
+}
+
 string Program::get_info_log() const
 {
        GLsizei len = 0;
@@ -383,14 +387,14 @@ int Program::get_uniform_location(const string &n) const
                                add an offset. */
                                unsigned offset = lexical_cast<unsigned>(n.substr(open_bracket+1, n.size()-2-open_bracket));
                                i = uniforms.find(n.substr(0, open_bracket)+"[0]");
-                               if(i!=uniforms.end() && offset<i->second.size)
+                               if(i!=uniforms.end() && !i->second.block && offset<i->second.size)
                                        return i->second.location+offset;
                        }
                }
                return -1;
        }
 
-       return i->second.location;
+       return i->second.block ? -1 : i->second.location;
 }
 
 void Program::bind() const