else if(result!=REDO_STAGE)
++i;
}
+
+ LocationAllocator().apply(*module);
for(list<Stage>::iterator i=module->stages.begin(); i!=module->stages.end(); ++i)
finalize(*i, mode);
#include <msp/strings/lexicalcast.h>
#include "finalize.h"
#include "glsl_error.h"
+#include "reflect.h"
using namespace std;
namespace GL {
namespace SL {
+void LocationAllocator::apply(Module &module)
+{
+ for(list<Stage>::iterator i=module.stages.begin(); i!=module.stages.end(); ++i)
+ apply(*i);
+ allocate_locations("uniform");
+}
+
+void LocationAllocator::apply(Stage &stage)
+{
+ swap(used_locations["in"], used_locations["out"]);
+ used_locations["out"].clear();
+
+ stage.content.visit(*this);
+
+ allocate_locations("in");
+ allocate_locations("out");
+}
+
+void LocationAllocator::allocate_locations(const string &iface)
+{
+ vector<VariableDeclaration *>::iterator write = unplaced_variables.begin();
+ unsigned next = 0;
+ for(vector<VariableDeclaration *>::const_iterator i=unplaced_variables.begin(); i!=unplaced_variables.end(); ++i)
+ {
+ if((*i)->interface!=iface)
+ {
+ if(write!=i)
+ *write = *i;
+ ++write;
+ continue;
+ }
+
+ if((*i)->interface=="uniform")
+ {
+ map<string, unsigned>::const_iterator j = uniform_locations.find((*i)->name);
+ if(j!=uniform_locations.end())
+ {
+ add_location((*i)->layout, j->second);
+ continue;
+ }
+ }
+
+ set<unsigned> &used = used_locations[(*i)->interface];
+
+ unsigned size = LocationCounter().apply(**i);
+ while(1)
+ {
+ int blocking = -1;
+ for(unsigned j=0; j<size; ++j)
+ if(used.count(next+j))
+ blocking = next+j;
+ if(blocking<0)
+ break;
+ next = blocking+1;
+ }
+
+ add_location((*i)->layout, next);
+ if((*i)->interface=="uniform")
+ uniform_locations[(*i)->name] = next;
+
+ for(unsigned j=0; j<size; ++j)
+ used.insert(next+j);
+ next += size;
+ }
+
+ unplaced_variables.erase(write, unplaced_variables.end());
+}
+
+void LocationAllocator::add_location(RefPtr<Layout> &layout, unsigned location)
+{
+ if(!layout)
+ layout = new Layout;
+
+ Layout::Qualifier qual;
+ qual.name = "location";
+ qual.has_value = true;
+ qual.value = location;
+ layout->qualifiers.push_back(qual);
+}
+
+void LocationAllocator::visit(VariableDeclaration &var)
+{
+ if(!var.interface.empty() && var.name.compare(0, 3, "gl_"))
+ {
+ int location = (var.layout ? get_layout_value(*var.layout, "location") : -1);
+
+ if(location<0 && var.linked_declaration && var.linked_declaration->layout)
+ {
+ location = get_layout_value(*var.linked_declaration->layout, "location");
+ if(location>=0)
+ add_location(var.layout, location);
+ }
+
+ if(location>=0)
+ {
+ unsigned size = LocationCounter().apply(var);
+ for(unsigned i=0; i<size; ++i)
+ used_locations[var.interface].insert(location+i);
+ if(var.interface=="uniform")
+ uniform_locations[var.name] = location;
+ }
+ else
+ unplaced_variables.push_back(&var);
+ }
+}
+
+
PrecisionConverter::PrecisionConverter():
stage(0)
{ }
namespace GL {
namespace SL {
+class LocationAllocator: private TraversingVisitor
+{
+private:
+ std::map<std::string, std::set<unsigned> > used_locations;
+ std::map<std::string, unsigned> uniform_locations;
+ std::vector<VariableDeclaration *> unplaced_variables;
+
+public:
+ void apply(Module &);
+private:
+ void apply(Stage &);
+
+ void allocate_locations(const std::string &);
+ void add_location(RefPtr<Layout> &, unsigned);
+
+ virtual void visit(VariableDeclaration &);
+ virtual void visit(InterfaceBlock &) { }
+ virtual void visit(FunctionDeclaration &) { }
+};
+
/** Generates default precision declarations or removes precision declarations
according to the requirements of the target API. */
class PrecisionConverter: private TraversingVisitor
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
void main()
{
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=1) in vec3 normal;
layout(location=2) in vec2 texcoord;
-out float light;
-out vec2 _vs_out_texcoord;
+layout(location=0) out float light;
+layout(location=1) out vec2 _vs_out_texcoord;
void main()
{
light = normal.z;
*/
/* Expected output: fragment
-uniform sampler2D tex;
-uniform vec3 tint;
-uniform vec3 ambient;
-out vec4 frag_color;
-in vec2 _vs_out_texcoord;
-in float light;
+layout(location=4) uniform sampler2D tex;
+layout(location=5) uniform vec3 tint;
+layout(location=6) uniform vec3 ambient;
+layout(location=0) out vec4 frag_color;
+layout(location=1) in vec2 _vs_out_texcoord;
+layout(location=0) in float light;
void main()
{
vec3 color = texture(tex, _vs_out_texcoord).rgb;
/* Expected output: vertex
layout(location=0) in vec4 position;
layout(location=1) in vec4 color;
-out vec4 _vs_out_color;
+layout(location=0) out vec4 _vs_out_color;
void main()
{
gl_Position = position;
/* Expected output: fragment
layout(location=0) out vec4 frag_color;
-in vec4 _vs_out_color;
+layout(location=0) in vec4 _vs_out_color;
void main()
{
frag_color = _vs_out_color;
/* Expected output: vertex
layout(location=0) in vec4 position;
-out vec2 texcoord;
+layout(location=0) out vec2 texcoord;
void main()
{
texcoord = position.xy*0.5+0.5;
*/
/* Expected output: geometry
-uniform bool flag;
+layout(location=0) uniform bool flag;
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
-in vec2 texcoord[];
-out vec2 _gs_out_texcoord;
+layout(location=0) in vec2 texcoord[];
+layout(location=0) out vec2 _gs_out_texcoord;
void main()
{
gl_Position = gl_in[0].gl_Position;
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=1) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _gs_out_texcoord;
+layout(location=0) in vec2 _gs_out_texcoord;
void main()
{
frag_color = texture(tex, _gs_out_texcoord);
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=1) in vec2 texcoord;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
void main()
{
gl_Position = mvp*position;
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=4) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
+layout(location=0) in vec2 _vs_out_texcoord;
void main()
{
frag_color = textureLod(tex, _vs_out_texcoord, 0.0)*0.8;
}
/* Expected output: vertex
-uniform mat4 model;
-uniform mat4 view_projection;
-uniform vec3 light_dir;
+layout(location=0) uniform mat4 model;
+layout(location=4) uniform mat4 view_projection;
+layout(location=8) uniform vec3 light_dir;
layout(location=0) in vec3 position;
layout(location=1) in vec3 normal;
layout(location=2) in vec3 tangent;
layout(location=3) in vec3 binormal;
layout(location=4) in vec2 texcoord;
-out vec3 tbn_light_dir;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec3 tbn_light_dir;
+layout(location=1) out vec2 _vs_out_texcoord;
void main()
{
mat3 normal_matrix = mat3(model[0].xyz, model[1].xyz, model[2].xyz);
*/
/* Expected output: fragment
-uniform sampler2D normalmap;
+layout(location=9) uniform sampler2D normalmap;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
-in vec3 tbn_light_dir;
+layout(location=1) in vec2 _vs_out_texcoord;
+layout(location=0) in vec3 tbn_light_dir;
void main()
{
frag_color = vec4(vec3(dot(vec3(texture(normalmap, _vs_out_texcoord).xyz)*2.0-1.0, normalize(tbn_light_dir))), float(1));
}
/* Expected output: vertex
-uniform mat4 model_matrix;
-uniform mat4 vp_matrix;
+layout(location=0) uniform mat4 model_matrix;
+layout(location=4) uniform mat4 vp_matrix;
layout(location=0) in vec4 position;
void main()
{
*/
/* Expected output: fragment
-uniform vec3 ambient;
+layout(location=8) uniform vec3 ambient;
layout(location=0) out vec4 frag_color;
void main()
{
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
void main()
{
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=1) in vec4 offset;
void main()
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=1) in vec2 texcoord;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
void main()
{
_vs_out_texcoord = texcoord;
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=4) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
+layout(location=0) in vec2 _vs_out_texcoord;
void main()
{
vec4 color = texture(tex, _vs_out_texcoord);
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=0) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
in GeometryOut
{
/* Expected output: vertex
layout(location=0) in vec4 position;
-out vec2 texcoord;
+layout(location=0) out vec2 texcoord;
void main()
{
texcoord = position.xy*0.5+0.5;
/* Expected output: geometry
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
-in vec2 texcoord[];
-out vec2 _gs_out_texcoord;
+layout(location=0) in vec2 texcoord[];
+layout(location=0) out vec2 _gs_out_texcoord;
void main()
{
for(int i = 0; i<3; ++i)
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=0) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _gs_out_texcoord;
+layout(location=0) in vec2 _gs_out_texcoord;
void main()
{
frag_color = texture(tex, _gs_out_texcoord);
}
/* Expected output: vertex
-uniform mat4 vp_matrix;
+layout(location=0) uniform mat4 vp_matrix;
layout(location=0) in vec4 position;
layout(location=1) in vec2 texcoord;
layout(location=2) in vec4 instance_transform[3];
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
void main()
{
_vs_out_texcoord = texcoord;
/* Expected output: geometry
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
-in vec2 _vs_out_texcoord[];
-out vec2 _gs_out_texcoord;
+layout(location=0) in vec2 _vs_out_texcoord[];
+layout(location=0) out vec2 _gs_out_texcoord;
void main()
{
for(int i = 0; i<3; ++i)
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=4) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _gs_out_texcoord;
+layout(location=0) in vec2 _gs_out_texcoord;
void main()
{
frag_color = texture(tex, _gs_out_texcoord);
// Compile mode: module
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=1) in vec4 color;
layout(location=2) in vec2 texcoord;
-out vec4 _vs_out_color;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec4 _vs_out_color;
+layout(location=1) out vec2 _vs_out_texcoord;
void main()
{
_vs_out_color = color;
/* Expected output: fragment
layout(constant_id=0) const bool use_texture = false;
layout(constant_id=1) const bool use_vertex_color = false;
-uniform sampler2D tex;
+layout(location=4) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
-in vec4 _vs_out_color;
+layout(location=1) in vec2 _vs_out_texcoord;
+layout(location=0) in vec4 _vs_out_color;
void main()
{
frag_color = vec4(1.0);
/* Expected output: vertex
layout(location=0) in vec4 position;
-out vec2 texcoord;
+layout(location=0) out vec2 texcoord;
void main()
{
texcoord = position.xy*0.5+0.5;
/* Expected output: geometry
layout(triangles) in;
layout(triangle_strip, max_vertices=3) out;
-in vec2 texcoord[];
-out vec2 _gs_out_texcoord;
+layout(location=0) in vec2 texcoord[];
+layout(location=0) out vec2 _gs_out_texcoord;
void main()
{
gl_Position = gl_in[0].gl_Position;
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=0) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _gs_out_texcoord;
+layout(location=0) in vec2 _gs_out_texcoord;
void main()
{
frag_color = texture(tex, _gs_out_texcoord);
}
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
void main()
{
}
/* Expected output: vertex
-uniform mat4 mvp;
-uniform vec3 offset;
+layout(location=0) uniform mat4 mvp;
+layout(location=4) uniform vec3 offset;
layout(location=0) in vec4 position;
layout(location=1) in vec3 normal;
layout(location=2) in vec2 texcoord;
-out vec3 _vs_out_normal;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec3 _vs_out_normal;
+layout(location=1) out vec2 _vs_out_texcoord;
void main()
{
gl_Position = mvp*(position+vec4(offset, 1.0));
float intensity;
vec3 dir;
};
-uniform LightParams light;
-uniform vec3 material_color;
-uniform sampler2D occlusion_map;
+layout(location=5) uniform LightParams light;
+layout(location=9) uniform vec3 material_color;
+layout(location=10) uniform sampler2D occlusion_map;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
-in vec3 _vs_out_normal;
+layout(location=1) in vec2 _vs_out_texcoord;
+layout(location=0) in vec3 _vs_out_normal;
void main()
{
frag_color = vec4(material_color*(light.ambient+light.color*light.intensity*max(dot(light.dir, normalize(_vs_out_normal)), 0.0))*float(texture(occlusion_map, _vs_out_texcoord).x), 1.0);
/* Expected output: vertex
layout(location=0) in vec4 position;
layout(location=1) in vec4 color;
-out vec4 _vs_out_color;
+layout(location=0) out vec4 _vs_out_color;
void main()
{
gl_Position = position;
/* Expected output: fragment
layout(location=0) out vec4 frag_color;
-in vec4 _vs_out_color;
+layout(location=0) in vec4 _vs_out_color;
void main()
{
frag_color = _vs_out_color;
/* Expected output: vertex
layout(location=0) in vec4 position;
layout(location=1) in vec4 color;
-out vec4 _vs_out_color;
+layout(location=0) out vec4 _vs_out_color;
void main()
{
gl_Position = position;
/* Expected output: fragment
layout(location=0) out vec4 frag_color;
-in vec4 _vs_out_color;
+layout(location=0) in vec4 _vs_out_color;
void main()
{
frag_color = _vs_out_color;
}
/* Expected output: vertex
-uniform mat4 projection;
-out vec4 eye_vertex;
+layout(location=0) uniform mat4 projection;
+layout(location=0) out vec4 eye_vertex;
out VertexOut
{
vec4 color;
};
-out float alpha;
+layout(location=1) out float alpha;
void main()
{
gl_Position = projection*eye_vertex;
{
vec4 color;
};
-in float alpha;
+layout(location=1) in float alpha;
void main()
{
frag_color = vec4(color.rgb, alpha);
// Specialize: use_texture true
/* Expected output: vertex
-uniform mat4 mvp;
+layout(location=0) uniform mat4 mvp;
layout(location=0) in vec4 position;
layout(location=2) in vec2 texcoord;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
void main()
{
_vs_out_texcoord = texcoord;
*/
/* Expected output: fragment
-uniform sampler2D tex;
+layout(location=4) uniform sampler2D tex;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
+layout(location=0) in vec2 _vs_out_texcoord;
void main()
{
frag_color = vec4(1.0);
} transform;
layout(location=0) in vec4 position;
layout(location=1) in vec2 texcoord;
-out vec2 _vs_out_texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
void main()
{
_vs_out_texcoord = texcoord;
vec4 color1;
vec4 color2;
};
-uniform sampler2D mask;
+layout(location=0) uniform sampler2D mask;
layout(location=0) out vec4 frag_color;
-in vec2 _vs_out_texcoord;
+layout(location=0) in vec2 _vs_out_texcoord;
void main()
{
frag_color = texture(mask, _vs_out_texcoord).r>0.5?color1:color2;
--- /dev/null
+#pragma MSP stage(vertex)
+uniform mat4 mvp;
+uniform sampler2D heightmap;
+layout(location=0) in vec2 position;
+layout(location=1) in vec2 texcoord;
+void main()
+{
+ gl_Position = mvp*vec4(position, texture(heightmap, texcoord).r, 1.0);
+ passthrough;
+}
+
+#pragma MSP stage(fragment)
+layout(location=0) uniform sampler2D heightmap;
+uniform vec4 color;
+out vec4 frag_color;
+void main()
+{
+ frag_color = color*vec4(texture(heightmap, texcoord).rrr, 1.0);
+}
+
+/* Expected output: vertex
+layout(location=1) uniform mat4 mvp;
+layout(location=0) uniform sampler2D heightmap;
+layout(location=0) in vec2 position;
+layout(location=1) in vec2 texcoord;
+layout(location=0) out vec2 _vs_out_texcoord;
+void main()
+{
+ gl_Position = mvp*vec4(position, texture(heightmap, texcoord).r, 1.0);
+ _vs_out_texcoord = texcoord;
+}
+*/
+
+/* Expected output: fragment
+layout(location=0) uniform sampler2D heightmap;
+layout(location=5) uniform vec4 color;
+layout(location=0) out vec4 frag_color;
+layout(location=0) in vec2 _vs_out_texcoord;
+void main()
+{
+ frag_color = color*vec4(texture(heightmap, _vs_out_texcoord).rrr, 1.0);
+}
+*/
}
/* Expected output: vertex
-uniform mat4 mvp;
-uniform int mask_index;
+layout(location=0) uniform mat4 mvp;
+layout(location=4) uniform int mask_index;
layout(location=0) in vec4 position;
layout(location=1) in vec4 color;
out VertexOut