X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fcompiler.h;h=a515a326f2b10b21ce866fd4591e65b38558263d;hp=853a399aa2d72c4990112880c8cdb531edd04ecb;hb=7335009e18ecbf53ad9f59d64eed2ed5abbe7b8b;hpb=c1b0303f65ee966a973197cbdbf177c571478674 diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index 853a399a..a515a326 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -1,10 +1,10 @@ #ifndef MSP_GL_SL_COMPILER_H_ #define MSP_GL_SL_COMPILER_H_ -#include +#include +#include +#include #include "parser.h" -#include "program.h" -#include "resources.h" #include "syntax.h" namespace Msp { @@ -13,401 +13,138 @@ namespace SL { class Compiler { -private: - struct Visitor: TraversingVisitor - { - typedef void ResultType; - - Stage *stage; - - Visitor(); - - virtual void apply(Stage &); - void get_result() const { } - }; - - struct BlockModifier: Visitor - { - bool remove_node; - std::vector > insert_nodes; - - BlockModifier(); - - void flatten_block(Block &); - void apply_and_increment(Block &, NodeList::iterator &); - using Visitor::visit; - virtual void visit(Block &); - }; - - struct Formatter: Visitor - { - typedef std::string ResultType; - - std::string formatted; - unsigned source_index; - unsigned source_line; - unsigned indent; - bool parameter_list; - std::string block_interface; - - Formatter(); - - virtual void apply(Stage &); - const std::string &get_result() const { return formatted; } - using Visitor::visit; - void append(const std::string &); - void append(char); - void set_source(unsigned, unsigned); - virtual void visit(Block &); - virtual void visit(Literal &); - virtual void visit(ParenthesizedExpression &); - virtual void visit(VariableReference &); - virtual void visit(MemberAccess &); - virtual void visit(UnaryExpression &); - virtual void visit(BinaryExpression &); - virtual void visit(Assignment &); - virtual void visit(FunctionCall &); - virtual void visit(ExpressionStatement &); - virtual void visit(Import &); - virtual void visit(Precision &); - virtual void visit(Layout &); - virtual void visit(InterfaceLayout &); - virtual void visit(StructDeclaration &); - virtual void visit(VariableDeclaration &); - virtual void visit(InterfaceBlock &); - virtual void visit(FunctionDeclaration &); - virtual void visit(Conditional &); - virtual void visit(Iteration &); - virtual void visit(Return &); - virtual void visit(Jump &); - }; - - template - struct NodeGatherer: Visitor +public: + enum Mode { - typedef std::vector ResultType; - - std::vector nodes; - - const ResultType &get_result() const { return nodes; } - using Visitor::visit; - virtual void visit(T &n) { nodes.push_back(&n); } + MODULE, + PROGRAM }; - struct DeclarationCombiner: BlockModifier +private: + enum OptimizeResult { - bool toplevel; - std::map > functions; - std::map variables; - - DeclarationCombiner(); - - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(FunctionDeclaration &); - virtual void visit(VariableDeclaration &); + NEXT_STAGE, + REDO_STAGE, + REDO_PREVIOUS }; - struct VariableResolver: Visitor + enum ResolveFlags { - std::vector blocks; - StructDeclaration *type; - bool anonymous; - std::string block_interface; - bool record_target; - VariableDeclaration *assignment_target; - bool self_referencing; - - VariableResolver(); - - virtual void apply(Stage &); - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(VariableReference &); - virtual void visit(MemberAccess &); - virtual void visit(BinaryExpression &); - virtual void visit(Assignment &); - virtual void visit(StructDeclaration &); - virtual void visit(VariableDeclaration &); - virtual void visit(InterfaceBlock &); + RESOLVE_BLOCKS = 1, + RESOLVE_TYPES = 2, + RESOLVE_VARIABLES = 4, + RESOLVE_EXPRESSIONS = 8, + RESOLVE_FUNCTIONS = 16, + RESOLVE_ALL = 31 }; - struct FunctionResolver: Visitor - { - std::map > functions; - - using Visitor::visit; - virtual void visit(FunctionCall &); - virtual void visit(FunctionDeclaration &); - }; + Features features; + Module *module; + std::vector imported_names; + bool specialized; + std::map spec_values; - struct InterfaceGenerator: BlockModifier - { - std::string in_prefix; - std::string out_prefix; - unsigned scope_level; - std::map > iface_declarations; - - InterfaceGenerator(); - - static std::string get_out_prefix(StageType); - virtual void apply(Stage &); - using Visitor::visit; - virtual void visit(Block &); - std::string change_prefix(const std::string &, const std::string &) const; - bool generate_interface(VariableDeclaration &, const std::string &, const std::string &); - ExpressionStatement &insert_assignment(const std::string &, Expression *); - virtual void visit(VariableReference &); - virtual void visit(VariableDeclaration &); - virtual void visit(Passthrough &); - }; +public: + /** Creates a compiler using features from the current OpenGL context. */ + Compiler(); - struct DeclarationReorderer: Visitor - { - enum DeclarationKind - { - NO_DECLARATION, - LAYOUT, - STRUCT, - VARIABLE, - FUNCTION - }; - - unsigned scope_level; - DeclarationKind kind; - std::set ordered_funcs; - std::set needed_funcs; - - DeclarationReorderer(); - - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(FunctionCall &); - virtual void visit(InterfaceLayout &) { kind = LAYOUT; } - virtual void visit(StructDeclaration &) { kind = STRUCT; } - virtual void visit(VariableDeclaration &); - virtual void visit(InterfaceBlock &) { kind = VARIABLE; } - virtual void visit(FunctionDeclaration &); - }; + /** Creates a compiler targeting a specific set of features. */ + Compiler(const Features &); - struct InlineableFunctionLocator: Visitor - { - typedef std::set ResultType; + ~Compiler(); - std::map refcounts; - std::set inlineable; - FunctionDeclaration *in_function; +private: + void clear(); - InlineableFunctionLocator(); +public: + /** Sets the source code to be compiled. Only builtin imports are + available. */ + void set_source(const std::string &, const std::string & = ""); - const ResultType &get_result() const { return inlineable; } - using Visitor::visit; - virtual void visit(FunctionCall &); - virtual void visit(FunctionDeclaration &); - }; + /** Loads source code from an I/O object. If a collection is used, imports + can be fetched from it. */ + void load_source(IO::Base &, DataFile::Collection * = 0, const std::string & = ""); - struct FunctionInliner: Visitor - { - std::set inlineable; - unsigned extract_result; - RefPtr inline_result; - - FunctionInliner(); - FunctionInliner(const std::set &); - - void visit_and_inline(RefPtr &); - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(UnaryExpression &); - virtual void visit(BinaryExpression &); - virtual void visit(MemberAccess &); - virtual void visit(FunctionCall &); - virtual void visit(VariableDeclaration &); - virtual void visit(Return &); - }; + /** Loads source code from an I/O object. Only builtin imports are + available. */ + void load_source(IO::Base &, const std::string &); - struct ExpressionEvaluator: NodeVisitor - { - typedef std::map ValueMap; + /** Specializes the shader. All specialization constants are considered + specialized, even if they do not appear in the map. */ + void specialize(const std::map &); - const ValueMap *variable_values; - float result; - bool result_valid; + /** Compiles the shader. */ + void compile(Mode); - ExpressionEvaluator(); - ExpressionEvaluator(const ValueMap &); + /** Returns combined GLSL source for all shader stages. The result is + suitable for feeding back to the compiler. */ + std::string get_combined_glsl() const; - using NodeVisitor::visit; - virtual void visit(Literal &); - virtual void visit(ParenthesizedExpression &); - virtual void visit(VariableReference &); - virtual void visit(UnaryExpression &); - virtual void visit(BinaryExpression &); - }; + /** Returns a list of compiled stage types. */ + std::vector get_stages() const; - struct ConstantConditionEliminator: BlockModifier - { - unsigned scope_level; - bool record_only; - ExpressionEvaluator::ValueMap variable_values; - - ConstantConditionEliminator(); - - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(UnaryExpression &); - virtual void visit(Assignment &); - virtual void visit(VariableDeclaration &); - virtual void visit(Conditional &); - virtual void visit(Iteration &); - }; + /** Returns GLSL source for a single shader stage. The result is standard + GLSL suitable for OpenGL or an external GLSL compiler. */ + std::string get_stage_glsl(Stage::Type) const; - struct UnusedVariableLocator: Visitor - { - struct VariableInfo - { - bool local; - std::vector assignments; - bool conditionally_assigned; - bool referenced; - - VariableInfo(); - }; - - typedef std::set ResultType; - typedef std::map BlockVariableMap; - - std::set unused_nodes; - std::map aggregates; - Node *aggregate; - std::vector variables; - Assignment *assignment; - bool assignment_target; - bool assign_to_subscript; - bool global_scope; - - UnusedVariableLocator(); - - virtual void apply(Stage &); - const ResultType &get_result() const { return unused_nodes; } - using Visitor::visit; - virtual void visit(VariableReference &); - virtual void visit(MemberAccess &); - virtual void visit(BinaryExpression &); - virtual void visit(Assignment &); - void record_assignment(VariableDeclaration &, Node &, bool); - void clear_assignments(VariableInfo &, bool); - virtual void visit(ExpressionStatement &); - virtual void visit(StructDeclaration &); - virtual void visit(VariableDeclaration &); - virtual void visit(InterfaceBlock &); - virtual void visit(FunctionDeclaration &); - void merge_down_variables(); - virtual void visit(Conditional &); - virtual void visit(Iteration &); - }; + /** Returns a map of vertex attribute locations. If the target GLSL version + supports interface layouts, the map is empty (locations are included in the + GLSL soucre). */ + const std::map &get_vertex_attributes() const; - struct UnusedFunctionLocator: Visitor - { - typedef std::set ResultType; + /** Returns a map of fragment output locations. If the target GLSL version + supports interface layouts, the map is empty (locations are included in the + GLSL soucre). */ + const std::map &get_fragment_outputs() const; - std::set unused_nodes; - std::set used_definitions; + /** Returns the mapping of source indices to filenames. Can be used to + translate error messages. */ + const SourceMap &get_source_map() const; - const ResultType &get_result() const { return unused_nodes; } - using Visitor::visit; - virtual void visit(FunctionCall &); - virtual void visit(FunctionDeclaration &); - }; + /** Returns a textual representation of the syntax tree for a shader stage. + Intended for debugging purposes. */ + std::string get_stage_debug(Stage::Type) const; - struct NodeRemover: Visitor - { - std::set to_remove; + /** Returns diagnostics from compilation. The output is intended to be + viewed by humans. */ + std::string get_diagnostics() const; - NodeRemover() { } - NodeRemover(const std::set &); +private: + /** Appends a module to the target, processing any imports found in it. */ + void append_module(Module &, DataFile::Collection *); - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(VariableDeclaration &); - virtual void visit(Iteration &); - }; + /** Appends a single stage to the matching stage of the target. */ + void append_stage(Stage &); - struct PrecisionRemover: BlockModifier - { - using Visitor::visit; - virtual void visit(Precision &); - virtual void visit(VariableDeclaration &); - }; + /// Imports a module by name and appends it to the target. */ + void import(DataFile::Collection *, const std::string &); - struct DefaultPrecisionGenerator: BlockModifier - { - bool toplevel; - std::set have_default; + /** Generates any implicitly defines syntactic structures and resolves + variables. */ + void generate(Stage &, Mode); - DefaultPrecisionGenerator(); + template + bool resolve(Stage &, unsigned &, unsigned); - using Visitor::visit; - virtual void visit(Block &); - virtual void visit(Precision &); - virtual void visit(VariableDeclaration &); - }; + /** Resolves various references between nodes. Flags can be specified to + request resolving particular aspects. Resolving may ripple into other + aspects as necessary. */ + void resolve(Stage &, unsigned = RESOLVE_ALL); - struct LegacyConverter: BlockModifier - { - GLApi target_api; - Version target_version; - std::string type; - VariableDeclaration *frag_out; - - LegacyConverter(); - LegacyConverter(const Version &); - - bool check_version(const Version &) const; - bool check_extension(const Extension &) const; - using Visitor::visit; - bool supports_unified_interface_syntax() const; - virtual void visit(VariableReference &); - virtual void visit(Assignment &); - bool supports_unified_sampling_functions() const; - virtual void visit(FunctionCall &); - bool supports_interface_layouts() const; - bool supports_centroid_sampling() const; - bool supports_sample_sampling() const; - virtual void visit(VariableDeclaration &); - bool supports_interface_blocks(const std::string &) const; - virtual void visit(InterfaceBlock &); - }; + /** Checks the validity of the module. If the return value is false, the + module's diagnostics list will contain additional information of errors. */ + bool validate(Stage &); - Resources *resources; - Module *module; - std::vector imported_names; + static bool diagnostic_line_order(const Diagnostic &, const Diagnostic &); -public: - Compiler(); - ~Compiler(); + /** Applies optimizations to a stage. The return value indicates which + stage should be optimized next. */ + OptimizeResult optimize(Stage &); - void compile(const std::string &, const std::string & = ""); - void compile(IO::Base &, Resources * = 0, const std::string & = ""); - void compile(IO::Base &, const std::string &); - void add_shaders(Program &); + /** Performs final adjustments on a stage after compilation. */ + void finalize(Stage &, Mode); -private: - static Module *create_builtins_module(); - static Module &get_builtins_module(); - static Stage *get_builtins(StageType); - void append_module(Module &); - void append_stage(Stage &); - void process(); - void import(const std::string &); - void generate(Stage &); - bool optimize(Stage &); - void finalize(Stage &); static void inject_block(Block &, const Block &); - template - static typename T::ResultType apply(Stage &); - template - static typename T::ResultType apply(Stage &, const A &); }; } // namespace SL