From 3bb1cda37e23840236b46c4de20cab2c70b02327 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 31 Mar 2021 22:25:38 +0300 Subject: [PATCH] Combine the precision handling visitors and rewrite the logic 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 | 6 +--- source/glsl/finalize.cpp | 76 ++++++++++++++++++++-------------------- source/glsl/finalize.h | 24 +++---------- 3 files changed, 44 insertions(+), 62 deletions(-) diff --git a/source/glsl/compiler.cpp b/source/glsl/compiler.cpp index e8b06c86..d8b060ea 100644 --- a/source/glsl/compiler.cpp +++ b/source/glsl/compiler.cpp @@ -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) diff --git a/source/glsl/finalize.cpp b/source/glsl/finalize.cpp index fb76ab6d..0725b739 100644 --- a/source/glsl/finalize.cpp +++ b/source/glsl/finalize.cpp @@ -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::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(type)) + { + default_prec = "lowp"; + break; + } + else if(const BasicTypeDeclaration *basic = dynamic_cast(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) { } diff --git a/source/glsl/finalize.h b/source/glsl/finalize.h index 21200713..21b4e316 100644 --- a/source/glsl/finalize.h +++ b/source/glsl/finalize.h @@ -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 have_default; NodeList::iterator insert_point; + std::set 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 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 -- 2.45.2