#include <msp/core/algorithm.h>
#include <msp/core/hash.h>
#include <msp/core/maputils.h>
+#include <msp/core/raii.h>
#include <msp/gl/extensions/arb_es2_compatibility.h>
#include <msp/gl/extensions/arb_fragment_shader.h>
#include <msp/gl/extensions/arb_gl_spirv.h>
#include <msp/gl/extensions/arb_geometry_shader4.h>
+#include <msp/gl/extensions/arb_separate_shader_objects.h>
#include <msp/gl/extensions/arb_shader_objects.h>
#include <msp/gl/extensions/arb_uniform_buffer_object.h>
#include <msp/gl/extensions/arb_vertex_shader.h>
id = glCreateProgram();
module = 0;
+ bindings = 0;
linked = false;
}
compile_glsl_stage(stage_id);
}
+
+ if(!bindings)
+ bindings = new Bindings;
+ bindings->textures = compiler.get_texture_bindings();
+ bindings->blocks = compiler.get_uniform_block_bindings();
}
void Program::compile_glsl_stage(unsigned stage_id)
{
query_uniforms();
query_attributes();
+ if(bindings)
+ {
+ for(unsigned i=0; i<uniform_blocks.size(); ++i)
+ {
+ map<string, unsigned>::const_iterator j = bindings->blocks.find(uniform_blocks[i].name);
+ if(j!=bindings->blocks.end())
+ {
+ glUniformBlockBinding(id, i, j->second);
+ uniform_blocks[i].bind_point = j->second;
+ }
+ }
+
+ Conditional<BindRestore> _bind(!ARB_separate_shader_objects, this);
+ for(map<string, unsigned>::const_iterator i=bindings->textures.begin(); i!=bindings->textures.end(); ++i)
+ {
+ int location = get_uniform_location(i->first);
+ if(location>=0)
+ {
+ if(ARB_separate_shader_objects)
+ glProgramUniform1i(id, location, i->second);
+ else
+ glUniform1i(location, i->second);
+ }
+ }
+
+ delete bindings;
+ bindings = 0;
+ }
}
else if(module->get_format()==Module::SPIR_V)
{
void Program::query_uniform_blocks(const vector<UniformInfo *> &uniforms_by_index)
{
- std::set<unsigned> used_bind_points;
unsigned count = get_program_i(id, GL_ACTIVE_UNIFORM_BLOCKS);
// Reserve an extra index for the default block
uniform_blocks.reserve(count+1);
glGetActiveUniformBlockiv(id, i, GL_UNIFORM_BLOCK_DATA_SIZE, &value);
info.data_size = value;
+ glGetActiveUniformBlockiv(id, i, GL_UNIFORM_BLOCK_BINDING, &value);
+ info.bind_point = value;
+
glGetActiveUniformBlockiv(id, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &value);
vector<int> indices(value);
glGetActiveUniformBlockiv(id, i, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, &indices[0]);
sort(info.uniforms.begin(), info.uniforms.end(), uniform_location_compare);
info.layout_hash = compute_layout_hash(info.uniforms);
- 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);
}
}