X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fglsl%2Fcompiler.h;h=1c07f3250d9bc4d964168a7fd868a16346e5cd06;hp=c8cb565fa1270c12d94c290a8479b0adef6f2084;hb=38712d8ecc57d043a2419ffbaeeb57f7a6586f14;hpb=696a97bd7411d69953c1a9e4b5f3dfb4c1d848f1 diff --git a/source/glsl/compiler.h b/source/glsl/compiler.h index c8cb565f..1c07f325 100644 --- a/source/glsl/compiler.h +++ b/source/glsl/compiler.h @@ -2,9 +2,9 @@ #define MSP_GL_SL_COMPILER_H_ #include +#include +#include #include "parser.h" -#include "program.h" -#include "resources.h" #include "syntax.h" namespace Msp { @@ -13,33 +13,157 @@ namespace SL { class Compiler { +public: + enum Mode + { + MODULE, + PROGRAM, + SPIRV + }; + private: - Resources *resources; - Module *module; + enum OptimizeResult + { + NEXT_STAGE, + REDO_STAGE, + REDO_PREVIOUS + }; + + enum ResolveFlags + { + RESOLVE_BLOCKS = 1, + RESOLVE_TYPES = 2, + RESOLVE_VARIABLES = 4, + RESOLVE_EXPRESSIONS = 8, + RESOLVE_FUNCTIONS = 16, + RESOLVE_ALL = 31 + }; + + Features features; + Module *module = 0; std::vector imported_names; + bool compiled = false; + bool specialized = false; + std::map spec_values; public: + /** Creates a compiler using features from the current OpenGL context. */ Compiler(); + + /** Creates a compiler targeting a specific set of features. */ + Compiler(const Features &); + ~Compiler(); - 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 &); +private: + void clear(); + +public: + /** Sets the source code to be compiled. Only builtin imports are + available. */ + void set_source(const std::string &, const std::string & = ""); + + /** 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 & = ""); + + /** Loads source code from an I/O object. Only builtin imports are + available. */ + void load_source(IO::Base &, const std::string &); + + /** Specializes the shader. All specialization constants are considered + specialized, even if they do not appear in the map. */ + void specialize(const std::map &); + + /** Compiles the shader. */ + void compile(Mode); + + /** Returns combined GLSL source for all shader stages. The result is + suitable for feeding back to the compiler. */ + std::string get_combined_glsl() const; + + /** Returns a list of compiled stage types. */ + std::vector get_stages() const; + + /** 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; + + /** Returns a combined SPIR-V binary for all shader stages. The result is + suitable for use with OpenGL or Vulkan. */ + std::vector get_combined_spirv() const; + + /** 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; + + /** 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; + + /** Returns a map of texture bindings. If the target GLSL version supports + bindings, the map is empty (bindings are included in the GLSL source). */ + const std::map &get_texture_bindings() const; + + /** Returns a map of uniform block bindings. If the target GLSL version + supports bindings, the map is empty (bindings are included in the GLSL + source). */ + const std::map &get_uniform_block_bindings() const; + + /** Returns the mapping of source indices to filenames. Can be used to + translate error messages. */ + const SourceMap &get_source_map() const; + + /** Returns a textual representation of the syntax tree for a shader stage. + Intended for debugging purposes. */ + std::string get_stage_debug(Stage::Type) const; + + /** Returns diagnostics from compilation. The output is intended to be + viewed by humans. */ + std::string get_diagnostics() const; private: - void append_module(Module &); - void append_stage(Stage &); - void process(); - void import(const std::string &); + /** Appends a module to the target, processing any imports found in it. */ + void append_module(const Module &, ModuleCache &); + + /** Appends a single stage to the matching stage of the target. */ + void append_stage(const Stage &); + + /// Imports a module by name and appends it to the target. */ + void import(ModuleCache &, const std::string &); + + /** Generates any implicitly defines syntactic structures and resolves + variables. */ 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 &); + bool resolve(Stage &, unsigned &, unsigned); + + /** 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); + + /** Runs validators on a stage. Diagnostic messages are recorded in the + stage for later inspection. */ + void validate(Stage &); + + /** Checks a stage's recorded diagnostics for errors. If any are found, + returns true. */ + bool check_errors(Stage &); + + static bool diagnostic_line_order(const Diagnostic &, const Diagnostic &); + + /** Applies optimizations to a stage. The return value indicates which + stage should be optimized next. */ + OptimizeResult optimize(Stage &); + + /** Performs final adjustments on a stage after compilation. */ + void finalize(Stage &, Mode); + + static void inject_block(Block &, const Block &); }; } // namespace SL