]> git.tdb.fi Git - libs/gl.git/blobdiff - source/glsl/spirv.h
Add a SPIR-V backend to the GLSL compiler
[libs/gl.git] / source / glsl / spirv.h
diff --git a/source/glsl/spirv.h b/source/glsl/spirv.h
new file mode 100644 (file)
index 0000000..21f0ed5
--- /dev/null
@@ -0,0 +1,172 @@
+#ifndef MSP_GL_SL_SPIRV
+#define MSP_GL_SL_SPIRV
+
+#include <map>
+#include <string>
+#include <vector>
+#include "spirvconstants.h"
+#include "spirvwriter.h"
+#include "visitor.h"
+
+namespace Msp {
+namespace GL {
+namespace SL {
+
+/** Creates SPIR-V binary from a module. */
+class SpirVGenerator: private NodeVisitor
+{
+private:
+       typedef SpirVCapability Capability;
+       typedef SpirVStorageClass StorageClass;
+       typedef SpirVOpcode Opcode;
+       typedef SpirVDecoration Decoration;
+       typedef SpirVBuiltin BuiltinSemantic;
+       typedef SpirVContent::Word Word;
+       typedef SpirVWriter::Id Id;
+
+       struct BuiltinFunctionInfo
+       {
+               char function[22];
+               char arg_types[5];
+               char extension[13];
+               Word opcode;
+               UInt8 arg_order[4];
+               void (SpirVGenerator::*handler)(FunctionCall &, const std::vector<Id> &);
+       };
+
+       struct Declaration
+       {
+               Id id;
+               Id type_id;
+
+               Declaration(Id i, Id t): id(i), type_id(t) { }
+       };
+
+       struct TypeKey
+       {
+               Id type_id;
+               unsigned detail;
+
+               TypeKey(Id i, unsigned d): type_id(i), detail(d) { }
+
+               bool operator<(const TypeKey &) const;
+       };
+
+       struct ConstantKey
+       {
+               Id type_id;
+               union
+               {
+                       int int_value;
+                       float float_value;
+               };
+
+               ConstantKey(Id t, int i): type_id(t), int_value(i) { }
+               ConstantKey(Id t, float f): type_id(t), float_value(f) { }
+
+               bool operator<(const ConstantKey &) const;
+       };
+
+       Stage *stage;
+       FunctionDeclaration *current_function;
+       std::vector<const InterfaceLayout *> interface_layouts;
+       SpirVContent content;
+       SpirVWriter writer;
+       std::set<Capability> used_capabilities;
+       std::map<std::string, Id> imported_extension_ids;
+       std::map<Node *, Declaration> declared_ids;
+       std::map<std::string, Id> declared_uniform_ids;
+       std::map<TypeKey, Id> standard_type_ids;
+       std::map<TypeKey, Id> array_type_ids;
+       std::map<TypeKey, Id> pointer_type_ids;
+       std::map<std::string, Id> function_type_ids;
+       std::map<ConstantKey, Id> constant_ids;
+       std::map<const VariableDeclaration *, Id> variable_load_ids;
+       Id next_id;
+       Id r_expression_result_id;
+       bool constant_expression;
+       bool spec_constant;
+       bool reachable;
+       bool composite_access;
+       Id r_composite_base_id;
+       Node *r_composite_base;
+       std::vector<unsigned> r_composite_chain;
+       Id assignment_source_id;
+       Id loop_merge_block_id;
+       Id loop_continue_target_id;
+
+       static const BuiltinFunctionInfo builtin_functions[];
+
+public:
+       SpirVGenerator();
+
+       void apply(Module &);
+       const std::vector<Word> &get_code() const { return content.code; }
+
+private:
+       static StorageClass get_interface_storage(const std::string &, bool);
+       static SpirVBuiltin get_builtin_semantic(const std::string &);
+       void use_capability(Capability);
+       Id import_extension(const std::string &);
+       Id get_id(Node &) const;
+       Id allocate_id(Node &, Id);
+       Id write_constant(Id, Word, bool);
+       static ConstantKey get_constant_key(Id, const Variant &value);
+       Id get_constant_id(Id, const Variant &value);
+       Id get_vector_constant_id(Id, unsigned, Id);
+       Id get_standard_type_id(BasicTypeDeclaration::Kind, unsigned);
+       bool is_scalar_type(Id, BasicTypeDeclaration::Kind) const;
+       Id get_array_type_id(TypeDeclaration &, unsigned);
+       Id get_pointer_type_id(Id, StorageClass);
+       Id get_variable_type_id(const VariableDeclaration &);
+       Id get_load_id(VariableDeclaration &);
+       void prune_loads(Id);
+       Id begin_expression(Opcode, Id, unsigned = 0);
+       void end_expression(Opcode);
+       Id write_expression(Opcode, Id, Id);
+       Id write_expression(Opcode, Id, Id, Id);
+       void write_deconstruct(Id, Id, Id *, unsigned);
+       Id write_construct(Id, const Id *, unsigned);
+       static BasicTypeDeclaration &get_element_type(BasicTypeDeclaration &);
+
+       virtual void visit(Block &);
+       virtual void visit(Literal &);
+       virtual void visit(VariableReference &);
+       virtual void visit(InterfaceBlockReference &);
+       void generate_composite_access(TypeDeclaration &);
+       void visit_composite(Expression &, unsigned, TypeDeclaration &);
+       void visit_isolated(Expression &);
+       virtual void visit(MemberAccess &);
+       virtual void visit(Swizzle &);
+       virtual void visit(UnaryExpression &);
+       virtual void visit(BinaryExpression &);
+       virtual void visit(Assignment &);
+       virtual void visit(TernaryExpression &);
+       virtual void visit(FunctionCall &);
+       void visit_constructor(FunctionCall &, const std::vector<Id> &);
+       void visit_builtin_matrix_comp_mult(FunctionCall &, const std::vector<Id> &);
+       void visit_builtin_texture(FunctionCall &, const std::vector<Id> &);
+       void visit_builtin_texel_fetch(FunctionCall &, const std::vector<Id> &);
+       void visit_builtin_interpolate(FunctionCall &, const std::vector<Id> &);
+       virtual void visit(ExpressionStatement &);
+       virtual void visit(InterfaceLayout &);
+       bool check_duplicate_type(TypeDeclaration &);
+       bool check_standard_type(BasicTypeDeclaration &);
+       virtual void visit(BasicTypeDeclaration &);
+       virtual void visit(ImageTypeDeclaration &);
+       virtual void visit(StructDeclaration &);
+       virtual void visit(VariableDeclaration &);
+       virtual void visit(InterfaceBlock &);
+       void visit_entry_point(FunctionDeclaration &, Id);
+       virtual void visit(FunctionDeclaration &);
+       virtual void visit(Conditional &);
+       virtual void visit(Iteration &);
+       virtual void visit(Return &);
+       virtual void visit(Jump &);
+};
+
+} // namespace SL
+} // namespace GL
+} // namespace Msp
+
+#endif