]> git.tdb.fi Git - libs/gl.git/commitdiff
Combine the precision handling visitors and rewrite the logic
authorMikko Rasa <tdb@tdb.fi>
Wed, 31 Mar 2021 19:25:38 +0000 (22:25 +0300)
committerMikko Rasa <tdb@tdb.fi>
Wed, 31 Mar 2021 19:25:38 +0000 (22:25 +0300)
It had fallen befind the times and still used the textual type
information.  The logic of what to do is now also contained in the
visitor.

source/glsl/compiler.cpp
source/glsl/finalize.cpp
source/glsl/finalize.h

index e8b06c865dece84b471efff19f1608bed56916aa..d8b060ea4e3873285980373e45974ee1b6b84950 100644 (file)
@@ -357,12 +357,8 @@ void Compiler::finalize(Stage &stage, Mode mode)
        {
                LegacyConverter().apply(stage, features);
                resolve(stage, RESOLVE_VARIABLES|RESOLVE_FUNCTIONS);
+               PrecisionConverter().apply(stage);
        }
-
-       if(get_gl_api()==OPENGL_ES2 && mode==PROGRAM)
-               DefaultPrecisionGenerator().apply(stage);
-       else if(mode==MODULE)
-               PrecisionRemover().apply(stage);
 }
 
 void Compiler::inject_block(Block &target, const Block &source)
index fb76ab6d57dc49c22997ad7a64b07e030ed45b34..0725b7394213f9defb1553d728425009c1d66567 100644 (file)
@@ -10,17 +10,18 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-DefaultPrecisionGenerator::DefaultPrecisionGenerator():
+PrecisionConverter::PrecisionConverter():
        stage(0)
 { }
 
-void DefaultPrecisionGenerator::apply(Stage &s)
+void PrecisionConverter::apply(Stage &s)
 {
        stage = &s;
        s.content.visit(*this);
+       NodeRemover().apply(s, nodes_to_remove);
 }
 
-void DefaultPrecisionGenerator::visit(Block &block)
+void PrecisionConverter::visit(Block &block)
 {
        for(NodeList<Statement>::iterator i=block.body.begin(); i!=block.body.end(); ++i)
        {
@@ -30,56 +31,55 @@ void DefaultPrecisionGenerator::visit(Block &block)
        }
 }
 
-void DefaultPrecisionGenerator::visit(Precision &prec)
+void PrecisionConverter::visit(Precision &prec)
 {
-       have_default.insert(prec.type);
+       if(stage->required_features.gl_api==OPENGL_ES2)
+               have_default.insert(prec.type);
+       else
+               nodes_to_remove.insert(&prec);
 }
 
-void DefaultPrecisionGenerator::visit(VariableDeclaration &var)
+void PrecisionConverter::visit(VariableDeclaration &var)
 {
-       if(var.type_declaration)
+       if(stage->required_features.gl_api!=OPENGL_ES2)
+       {
+               var.precision.clear();
                return;
+       }
 
-       string type = var.type;
-       if(!type.compare(0, 3, "vec") || !type.compare(0, 3, "mat"))
-               type = "float";
-       else if(!type.compare(0, 3, "ivec") || type=="uint")
-               type = "int";
+       const char *default_prec = (stage->type==Stage::FRAGMENT ? "mediump" : "highp");
+       const TypeDeclaration *type = var.type_declaration;
+       while(type)
+       {
+               if(dynamic_cast<const ImageTypeDeclaration *>(type))
+               {
+                       default_prec = "lowp";
+                       break;
+               }
+               else if(const BasicTypeDeclaration *basic = dynamic_cast<const BasicTypeDeclaration *>(type))
+               {
+                       if(basic->kind==BasicTypeDeclaration::INT || basic->kind==BasicTypeDeclaration::FLOAT)
+                               break;
+                       type = basic->base_type;
+               }
+               else
+                       return;
+       }
+       if(!type)
+               return;
 
-       if(!have_default.count(type))
+       if(!have_default.count(type->name))
        {
                Precision *prec = new Precision;
-               if(!type.compare(0, 7, "sampler"))
-                       prec->precision = "lowp";
-               else if(stage->type==Stage::FRAGMENT)
-                       prec->precision = "mediump";
-               else
-                       prec->precision = "highp";
-               prec->type = type;
+               prec->precision = default_prec;
+               prec->type = type->name;
                stage->content.body.insert(insert_point, prec);
 
-               have_default.insert(type);
+               have_default.insert(type->name);
        }
 }
 
 
-void PrecisionRemover::apply(Stage &stage)
-{
-       stage.content.visit(*this);
-       NodeRemover().apply(stage, nodes_to_remove);
-}
-
-void PrecisionRemover::visit(Precision &prec)
-{
-       nodes_to_remove.insert(&prec);
-}
-
-void PrecisionRemover::visit(VariableDeclaration &var)
-{
-       var.precision.clear();
-}
-
-
 LegacyConverter::LegacyConverter():
        frag_out(0)
 { }
index 212007131e80a3d0e37173364005d68f3b8d1166..21b4e316d0eec52ae34e5c5c050d15e024656bb7 100644 (file)
@@ -8,17 +8,18 @@ namespace Msp {
 namespace GL {
 namespace SL {
 
-/** Generates default precision declarations if they are missing, to satisfy
-GLSL ES requirements. */
-class DefaultPrecisionGenerator: private TraversingVisitor
+/** Generates default precision declarations or removes precision declarations
+according to the requirements of the target API. */
+class PrecisionConverter: private TraversingVisitor
 {
 private:
        Stage *stage;
        std::set<std::string> have_default;
        NodeList<Statement>::iterator insert_point;
+       std::set<Node *> nodes_to_remove;
 
 public:
-       DefaultPrecisionGenerator();
+       PrecisionConverter();
 
        void apply(Stage &);
 
@@ -28,21 +29,6 @@ private:
        virtual void visit(VariableDeclaration &);
 };
 
-/** Removes precision qualifiers from variable declarations, as well as
-default precision declarations. */
-class PrecisionRemover: private TraversingVisitor
-{
-private:
-       std::set<Node *> nodes_to_remove;
-
-public:
-       void apply(Stage &);
-
-private:
-       virtual void visit(Precision &);
-       virtual void visit(VariableDeclaration &);
-};
-
 /** Converts structures of the syntax tree to match a particular set of
 features. */
 class LegacyConverter: private TraversingVisitor