Recognize #version directive in GLSL
authorMikko Rasa <tdb@tdb.fi>
Thu, 11 Jul 2019 22:22:59 +0000 (01:22 +0300)
committerMikko Rasa <tdb@tdb.fi>
Thu, 11 Jul 2019 22:22:59 +0000 (01:22 +0300)
This allows shaders to explicitly specify the required version in
case there's a feature which is not detected by the program compiler
framework.

source/programcompiler.cpp
source/programparser.cpp
source/programparser.h

index 989098d7d0cf6410b4d26faed46f9c400bc06a3c..f30ccfa6233ad6b6dc8115488210c7f1dbd4c7a5 100644 (file)
@@ -209,6 +209,8 @@ void ProgramCompiler::append_stage(Stage &stage)
                target = &*i;
        }
 
+       if(stage.required_version>target->required_version)
+               target->required_version = stage.required_version;
        for(NodeList<Statement>::iterator i=stage.content.body.begin(); i!=stage.content.body.end(); ++i)
                target->content.body.push_back(*i);
        apply<DeclarationCombiner>(*target);
@@ -245,6 +247,8 @@ void ProgramCompiler::import(const string &name)
 
 void ProgramCompiler::generate(Stage &stage)
 {
+       if(module->shared.required_version>stage.required_version)
+               stage.required_version = module->shared.required_version;
        inject_block(stage.content, module->shared.content);
 
        apply<DeclarationReorderer>(stage);
index ca554f427464b8863b03ed8211c0f8598e2c7c03..7477f38bc9a6ad01d1f0182ed2429caaa6f49d39 100644 (file)
@@ -369,8 +369,10 @@ void ProgramParser::preprocess()
        string token = peek_token();
        if(token=="pragma")
                preprocess_pragma();
+       else if(token=="version")
+               preprocess_version();
        else if(token=="define" || token=="undef" || token=="if" || token=="ifdef" || token=="ifndef" || token=="else" ||
-               token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="version" || token=="line")
+               token=="elif" || token=="endif" || token=="error" || token=="extension" || token=="line")
                throw runtime_error(format_error(format("Unsupported preprocessor directive '%s'", token)));
        else if(!token.empty())
                throw runtime_error(format_syntax_error("a preprocessor directive"));
@@ -378,6 +380,18 @@ void ProgramParser::preprocess()
        iter = line_end;
 }
 
+void ProgramParser::preprocess_version()
+{
+       expect("version");
+       string token = parse_token();
+       unsigned version = lexical_cast<unsigned>(token);
+       cur_stage->required_version = Version(version/100, version%100);
+
+       token = parse_token();
+       if(!token.empty())
+               throw runtime_error(format_syntax_error("end of line"));
+}
+
 void ProgramParser::preprocess_pragma()
 {
        expect("pragma");
index dc94bd0044443bd01ca862584e6784a58da4fb9f..e36604736b9f5cf4dfd28548038b87c371d76834 100644 (file)
@@ -87,6 +87,7 @@ private:
        bool is_identifier(const std::string &);
 
        void preprocess();
+       void preprocess_version();
        void preprocess_pragma();
        void preprocess_pragma_msp();
        void preprocess_stage();