namespace GL {
namespace SL {
+/** Generates default precision declarations if they are missing, to satisfy
+GLSL ES requirements. */
class DefaultPrecisionGenerator: private TraversingVisitor
{
private:
virtual void visit(VariableDeclaration &);
};
+/** Removes precision qualifiers from variable declarations, as well as
+default precision declarations. */
class PrecisionRemover: private TraversingVisitor
{
private:
virtual void visit(VariableDeclaration &);
};
+/** Converts structures of the syntax tree to match a particular set of
+features. */
class LegacyConverter: private TraversingVisitor
{
private:
inject_block(stage.content, module->shared.content);
DeclarationReorderer().apply(stage);
- BlockResolver().apply(stage);
+
+ // Initial resolving pass
+ BlockHierarchyResolver().apply(stage);
FunctionResolver().apply(stage);
VariableResolver().apply(stage);
+
+ /* All variables local to a stage have been resolved. Resolve non-local
+ variables through interfaces. */
InterfaceGenerator().apply(stage);
VariableResolver().apply(stage);
+
DeclarationReorderer().apply(stage);
FunctionResolver().apply(stage);
ConstantSpecializer().apply(stage, (mode==PROGRAM && specialized ? &spec_values : 0));
ConstantConditionEliminator().apply(stage);
FunctionInliner().apply(stage);
- BlockResolver().apply(stage);
+ BlockHierarchyResolver().apply(stage);
VariableResolver().apply(stage);
+ /* Removing variables or functions may cause things from the previous stage
+ to become unused. */
bool result = UnusedVariableRemover().apply(stage);
result |= UnusedFunctionRemover().apply(stage);
std::map<std::string, int> 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();
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 & = "<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 & = "<file>");
+
+ /** 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<std::string, int> &);
+
+ /** 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<Stage::Type> 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 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<std::string, unsigned> &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<std::string, unsigned> &get_fragment_outputs() 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;
private:
+ /** Appends a module to the target, processing any imports found in it. */
void append_module(Module &, DataFile::Collection *);
+
+ /** Appends a single stage to the matching stage of the target. */
void append_stage(Stage &);
+
+ /// Imports a module by name and appends it to the target. */
void import(DataFile::Collection *, const std::string &);
+
+ /** Generates any implicitly defines syntactic structures and resolves
+ variables. */
void generate(Stage &, Mode);
+
+ /** Applies optimizations to a stage. The return value indicates if the
+ preceding stage should be processed again. */
bool optimize(Stage &);
+
+ /** Performs final adjustments on a stage after compilation. */
void finalize(Stage &, Mode);
+
static void inject_block(Block &, const Block &);
};
namespace GL {
namespace SL {
+/** Creates a textual representation of the syntax tree. The result is encoded
+as UTF-8. */
class DumpTree: private TraversingVisitor
{
private:
namespace GL {
namespace SL {
+/** Evaluates an expression. Only expressions consisting entirely of compile-
+time constants can be evaluated. */
class ExpressionEvaluator: public NodeVisitor
{
public:
}
-void BlockResolver::enter(Block &block)
+void BlockHierarchyResolver::enter(Block &block)
{
block.parent = current_block;
}
namespace GL {
namespace SL {
+/** Combines multiple declarations of the same identifier into one. */
class DeclarationCombiner: private TraversingVisitor
{
private:
virtual void visit(VariableDeclaration &);
};
+/** Manipulates specialization constants. If values are specified, turns
+specialization constants into normal constants. Without values assigns
+automatic constant_ids to specialization constants. */
class ConstantSpecializer: private TraversingVisitor
{
private:
virtual void visit(VariableDeclaration &);
};
-class BlockResolver: private TraversingVisitor
+/** Forms links between nested blocks in the syntax tree. */
+class BlockHierarchyResolver: private TraversingVisitor
{
public:
void apply(Stage &s) { s.content.visit(*this); }
virtual void enter(Block &);
};
+/** Resolves variable references. Variable references which match the name
+of an interface block are turned into interface block references. */
class VariableResolver: private TraversingVisitor
{
private:
virtual void visit(InterfaceBlock &);
};
+/** Resolves function declarations and calls. */
class FunctionResolver: private TraversingVisitor
{
private:
+ Stage *stage;
std::map<std::string, std::vector<FunctionDeclaration *> > functions;
public:
- void apply(Stage &s) { s.content.visit(*this); }
+ void apply(Stage &);
private:
virtual void visit(FunctionCall &);
virtual void visit(FunctionDeclaration &);
};
+/** Materializes implicitly declared interfaces.
+
+Out variable declarations inside functions are moved to the global scope.
+
+Passthrough statements are processed, generating out variables to match in
+variables and copying values.
+
+Unresolved variables are looked up in the previous stage's out variables. */
class InterfaceGenerator: private TraversingVisitor
{
private:
virtual void visit(Passthrough &);
};
+/** Reorders declarations to ensure that declarations always appear before
+references. */
class DeclarationReorderer: private TraversingVisitor
{
private:
namespace GL {
namespace SL {
+/** Finds functions which are candidates for inlining. Currently this means
+functions which have no parameters, are only called once, and that call occurs
+after the definition of the function. */
class InlineableFunctionLocator: private TraversingVisitor
{
private:
virtual void visit(FunctionDeclaration &);
};
+/** Inlines functions. Internally uses InlineableFunctionLocator to find
+candidate functions. Only functions which consist of a single return statement
+are inlined. */
class FunctionInliner: private TraversingVisitor
{
private:
virtual void visit(Return &);
};
+/** Removes conditional statements and loops where the condition can be
+determined as constant at compile time. */
class ConstantConditionEliminator: private TraversingVisitor
{
private:
virtual void visit(Iteration &);
};
+/** Removes variable declarations with no references to them. Assignment
+statements where the result is not used are also removed. */
class UnusedVariableRemover: private TraversingVisitor
{
private:
virtual void visit(Iteration &);
};
+/** Removes function declarations with no references to them. */
class UnusedFunctionRemover: private TraversingVisitor
{
private:
namespace GL {
namespace SL {
+/** Formats the syntax tree as GLSL. */
class Formatter: private TraversingVisitor
{
private:
namespace GL {
namespace SL {
+/** Base class for all node visitors. */
class NodeVisitor
{
protected:
virtual void visit(Jump &) { }
};
+/** An intermediate base visitor class which traverses the syntax tree. */
class TraversingVisitor: public NodeVisitor
{
protected:
virtual void visit(Return &);
};
+/** Gathers nodes of a particular type from the syntax tree. */
template<typename T>
class NodeGatherer: private TraversingVisitor
{
virtual void visit(T &n) { nodes.push_back(&n); }
};
+/** Removes a set of nodes from the syntax tree. */
class NodeRemover: private TraversingVisitor
{
private: