]> git.tdb.fi Git - libs/gl.git/blobdiff - source/program.cpp
Introduce a typedef for uniform layout hashes in Program
[libs/gl.git] / source / program.cpp
index baeba9f5c33d1091da815f0d14d7f6be45807b3b..a81d80ae378ca457adb70817474109b3d3fc10c3 100644 (file)
@@ -1,5 +1,6 @@
 #include <algorithm>
 #include <cstring>
+#include <set>
 #include <msp/core/hash.h>
 #include <msp/core/maputils.h>
 #include <msp/gl/extensions/arb_shader_objects.h>
@@ -125,7 +126,7 @@ void Program::link()
                if(len && strncmp(name, "gl_", 3))
                {
                        /* Some implementations report the first element of a uniform array,
-                       others report just the name of an array. */
+                       others report just the name of the array itself. */
                        if(len>3 && !strcmp(name+len-3, "[0]"))
                                name[len-3] = 0;
 
@@ -156,6 +157,7 @@ void Program::link()
 
        if(ARB_uniform_buffer_object)
        {
+               std::set<unsigned> used_bind_points;
                count = get_program_i(id, GL_ACTIVE_UNIFORM_BLOCKS);
                for(unsigned i=0; i<count; ++i)
                {
@@ -194,7 +196,7 @@ void Program::link()
                        {
                                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];
+                                       uniforms_by_index[indices2[j]]->array_stride = values[j];
                        }
 
                        indices2.clear();
@@ -210,13 +212,17 @@ void Program::link()
                        {
                                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];
+                                       uniforms_by_index[indices2[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();
+                       unsigned n_bindings = BufferRange::get_n_uniform_buffer_bindings();
+                       info.bind_point = info.layout_hash%n_bindings;
+                       while(used_bind_points.count(info.bind_point))
+                               info.bind_point = (info.bind_point+1)%n_bindings;
                        glUniformBlockBinding(id, i, info.bind_point);
+                       used_bind_points.insert(info.bind_point);
                }
        }
 
@@ -231,7 +237,7 @@ void Program::link()
        uniform_layout_hash = compute_layout_hash(blockless_uniforms);
 }
 
-unsigned Program::compute_layout_hash(const vector<const UniformInfo *> &uniforms)
+Program::LayoutHash Program::compute_layout_hash(const vector<const UniformInfo *> &uniforms)
 {
        string layout_descriptor;
        for(vector<const UniformInfo *>::const_iterator i = uniforms.begin(); i!=uniforms.end(); ++i)