void ProgramCompiler::Formatter::apply(ProgramSyntax::Stage &s)
{
+ GLApi api = get_gl_api();
const Version &ver = s.required_version;
+
if(ver.major)
- formatted += format("#version %d%d\n", ver.major, ver.minor);
+ {
+ formatted += format("#version %d%d", ver.major, ver.minor);
+ if(api==OPENGL_ES2 && ver>=Version(3, 0))
+ formatted += " es";
+ formatted += '\n';
+ }
+
+ if(api==OPENGL_ES2)
+ {
+ if(s.type==FRAGMENT)
+ formatted += "precision mediump float;\n";
+ }
+
Visitor::apply(s);
}
ProgramCompiler::LegacyConverter::LegacyConverter():
+ target_api(get_gl_api()),
target_version(get_glsl_version()),
frag_out(0)
{ }
ProgramCompiler::LegacyConverter::LegacyConverter(const Version &v):
+ target_api(get_gl_api()),
target_version(v),
frag_out(0)
{ }
-bool ProgramCompiler::LegacyConverter::check_version(const Version &feature_version)
+bool ProgramCompiler::LegacyConverter::check_version(const Version &feature_version) const
{
if(target_version<feature_version)
return false;
return true;
}
+bool ProgramCompiler::LegacyConverter::supports_unified_interface_syntax() const
+{
+ if(target_api==OPENGL_ES2)
+ return check_version(Version(3, 0));
+ else
+ return check_version(Version(1, 30));
+}
+
void ProgramCompiler::LegacyConverter::visit(VariableReference &var)
{
- if(var.declaration==frag_out && !check_version(Version(1, 30)))
+ if(var.declaration==frag_out && !supports_unified_interface_syntax())
{
var.name = "gl_FragColor";
var.declaration = 0;
void ProgramCompiler::LegacyConverter::visit(Assignment &assign)
{
TraversingVisitor::visit(assign);
- if(assign.target_declaration==frag_out && !check_version(Version(1, 30)))
+ if(assign.target_declaration==frag_out && !supports_unified_interface_syntax())
assign.target_declaration = 0;
}
+bool ProgramCompiler::LegacyConverter::supports_unified_sampling_functions() const
+{
+ if(target_api==OPENGL_ES2)
+ return check_version(Version(3, 0));
+ else
+ return check_version(Version(1, 30));
+}
+
void ProgramCompiler::LegacyConverter::visit(FunctionCall &call)
{
- if(call.name=="texture" && !call.declaration && !check_version(Version(1, 30)))
+ if(call.name=="texture" && !call.declaration && !supports_unified_sampling_functions())
{
vector<RefPtr<Expression> >::iterator i = call.arguments.begin();
if(i!=call.arguments.end())
TraversingVisitor::visit(call);
}
+bool ProgramCompiler::LegacyConverter::supports_interface_layouts() const
+{
+ if(target_api==OPENGL_ES2)
+ return check_version(Version(3, 0));
+ else
+ return check_version(Version(3, 30));
+}
+
void ProgramCompiler::LegacyConverter::visit(VariableDeclaration &var)
{
- if(var.layout && !check_version(Version(3, 30)))
+ if(var.layout && !supports_interface_layouts())
{
vector<Layout::Qualifier>::iterator i;
for(i=var.layout->qualifiers.begin(); (i!=var.layout->qualifiers.end() && i->identifier!="location"); ++i) ;
}
}
- if((var.interface=="in" || var.interface=="out") && !check_version(Version(1, 30)))
+ if((var.interface=="in" || var.interface=="out") && !supports_unified_interface_syntax())
{
if(stage->type==FRAGMENT && var.interface=="out")
{
TraversingVisitor::visit(var);
}
+bool ProgramCompiler::LegacyConverter::supports_interface_blocks(const string &iface) const
+{
+ if(target_api==OPENGL_ES2)
+ {
+ if(iface=="uniform")
+ return check_version(Version(3, 0));
+ else
+ return check_version(Version(3, 20));
+ }
+ else
+ return check_version(Version(1, 50));
+}
+
void ProgramCompiler::LegacyConverter::visit(InterfaceBlock &iface)
{
- if(!check_version(Version(1, 50)))
+ if(!supports_interface_blocks(iface.interface))
flatten_block(iface.members);
}
struct LegacyConverter: BlockModifier
{
+ GLApi target_api;
Version target_version;
std::string type;
ProgramSyntax::VariableDeclaration *frag_out;
LegacyConverter();
LegacyConverter(const Version &);
- bool check_version(const Version &);
+ bool check_version(const Version &) const;
using Visitor::visit;
+ bool supports_unified_interface_syntax() const;
virtual void visit(ProgramSyntax::VariableReference &);
virtual void visit(ProgramSyntax::Assignment &);
+ bool supports_unified_sampling_functions() const;
virtual void visit(ProgramSyntax::FunctionCall &);
+ bool supports_interface_layouts() const;
virtual void visit(ProgramSyntax::VariableDeclaration &);
+ bool supports_interface_blocks(const std::string &) const;
virtual void visit(ProgramSyntax::InterfaceBlock &);
};