]> git.tdb.fi Git - libs/gl.git/commitdiff
Basic OpenGL ES support in ProgramCompiler
authorMikko Rasa <tdb@tdb.fi>
Tue, 14 Nov 2017 08:53:47 +0000 (10:53 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 14 Nov 2017 10:56:02 +0000 (12:56 +0200)
Check language features against the correct version depending on the API
and emit a default precision qualifier for float types.

source/programcompiler.cpp
source/programcompiler.h

index fd27839da25e1f7cb377a7fdf46079bfb1e862f3..6b8eb6e6135ddb68702537cbc4d3c9b626a341c1 100644 (file)
@@ -228,9 +228,23 @@ ProgramCompiler::Formatter::Formatter():
 
 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);
 }
 
@@ -1494,16 +1508,18 @@ void ProgramCompiler::NodeRemover::visit(VariableDeclaration &var)
 
 
 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;
@@ -1513,9 +1529,17 @@ bool ProgramCompiler::LegacyConverter::check_version(const Version &feature_vers
        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;
@@ -1530,13 +1554,21 @@ void ProgramCompiler::LegacyConverter::visit(VariableReference &var)
 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())
@@ -1561,9 +1593,17 @@ void ProgramCompiler::LegacyConverter::visit(FunctionCall &call)
                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) ;
@@ -1586,7 +1626,7 @@ void ProgramCompiler::LegacyConverter::visit(VariableDeclaration &var)
                }
        }
 
-       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")
                {
@@ -1598,9 +1638,22 @@ void ProgramCompiler::LegacyConverter::visit(VariableDeclaration &var)
        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);
 }
 
index e159078a647a4aea0573e7f03f9b8c423fc0db84..a84ccb8ac001d9a6fe49d93cab4f47998591ad9d 100644 (file)
@@ -328,6 +328,7 @@ private:
 
        struct LegacyConverter: BlockModifier
        {
+               GLApi target_api;
                Version target_version;
                std::string type;
                ProgramSyntax::VariableDeclaration *frag_out;
@@ -335,12 +336,16 @@ private:
                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 &);
        };