1 //=============================================================================
2 //
3 // Render/GLSLGenerator.h
4 //
5 // Created by Max McGuire (max@unknownworlds.com)
6 // Copyright (c) 2013, Unknown Worlds Entertainment, Inc.
7 //
8 //=============================================================================
9 
10 #ifndef GLSL_GENERATOR_H
11 #define GLSL_GENERATOR_H
12 
13 #include "CodeWriter.h"
14 #include "HLSLTree.h"
15 
16 namespace M4
17 {
18 
19 class GLSLGenerator
20 {
21 
22 public:
23     enum Target
24     {
25         Target_VertexShader,
26         Target_FragmentShader,
27     };
28 
29     enum Version
30     {
31         Version_110, // OpenGL 2.0
32         Version_120, // OpenGL 2.1
33         Version_140, // OpenGL 3.1
34         Version_150, // OpenGL 3.2
35         Version_330, // OpenGL 3.3
36         Version_100_ES, // OpenGL ES 2.0
37         Version_300_ES, // OpenGL ES 3.0
38     };
39 
40     enum Flags
41     {
42         Flag_FlipPositionOutput = 1 << 0,
43         Flag_EmulateConstantBuffer = 1 << 1,
44         Flag_PackMatrixRowMajor = 1 << 2,
45         Flag_LowerMatrixMultiplication = 1 << 3,
46     };
47 
48     struct Options
49     {
50         unsigned int flags;
51         const char* constantBufferPrefix;
52 
OptionsOptions53         Options()
54         {
55             flags = 0;
56             constantBufferPrefix = "";
57         }
58     };
59 
60     GLSLGenerator();
61 
62     bool Generate(HLSLTree* tree, Target target, Version versiom, const char* entryName, const Options& options = Options());
63     const char* GetResult() const;
64 
65 private:
66 
67     enum AttributeModifier
68     {
69         AttributeModifier_In,
70         AttributeModifier_Out,
71     };
72 
73     void OutputExpressionList(HLSLExpression* expression, HLSLArgument* argument = NULL);
74     void OutputExpression(HLSLExpression* expression, const HLSLType* dstType = NULL);
75     void OutputIdentifier(const char* name);
76     void OutputArguments(HLSLArgument* argument);
77 
78     /**
79      * If the statements are part of a function, then returnType can be used to specify the type
80      * that a return statement is expected to produce so that correct casts will be generated.
81      */
82     void OutputStatements(int indent, HLSLStatement* statement, const HLSLType* returnType = NULL);
83 
84     void OutputAttribute(const HLSLType& type, const char* semantic, AttributeModifier modifier);
85     void OutputAttributes(HLSLFunction* entryFunction);
86     void OutputEntryCaller(HLSLFunction* entryFunction);
87     void OutputDeclaration(HLSLDeclaration* declaration, const bool skipAssignment);
88 	void OutputDeclarationType( const HLSLType& type );
89 	void OutputDeclarationBody( const HLSLType& type, const char* name );
90     void OutputDeclaration(const HLSLType& type, const char* name);
91     void OutputDeclarationAssignment(HLSLDeclaration* declaration);
92     void OutputCast(const HLSLType& type);
93 
94     void OutputSetOutAttribute(const char* semantic, const char* resultName);
95 
96     void LayoutBuffer(HLSLBuffer* buffer, unsigned int& offset);
97     void LayoutBuffer(const HLSLType& type, unsigned int& offset);
98     void LayoutBufferElement(const HLSLType& type, unsigned int& offset);
99     void LayoutBufferAlign(const HLSLType& type, unsigned int& offset);
100 
101     HLSLBuffer* GetBufferAccessExpression(HLSLExpression* expression);
102     void OutputBufferAccessExpression(HLSLBuffer* buffer, HLSLExpression* expression, const HLSLType& type, unsigned int postOffset);
103     unsigned int OutputBufferAccessIndex(HLSLExpression* expression, unsigned int postOffset);
104 
105     void OutputBuffer(int indent, HLSLBuffer* buffer);
106 
107     HLSLFunction* FindFunction(HLSLRoot* root, const char* name);
108     HLSLStruct* FindStruct(HLSLRoot* root, const char* name);
109 
110     void Error(const char* format, ...);
111 
112     /** GLSL contains some reserved words that don't exist in HLSL. This function will
113      * sanitize those names. */
114     const char* GetSafeIdentifierName(const char* name) const;
115 
116     /** Generates a name of the format "base+n" where n is an integer such that the name
117      * isn't used in the syntax tree. */
118     bool ChooseUniqueName(const char* base, char* dst, int dstLength) const;
119 
120     const char* GetBuiltInSemantic(const char* semantic, AttributeModifier modifier, int* outputIndex = 0);
121     const char* GetAttribQualifier(AttributeModifier modifier);
122     void CompleteConstructorArguments(HLSLExpression* expression, HLSLBaseType dstType);
123     void OutputMatrixCtors();
124 
125 private:
126 
127     static const int    s_numReservedWords = 9;
128     static const char*  s_reservedWord[s_numReservedWords];
129 
130     CodeWriter          m_writer;
131 
132     HLSLTree*           m_tree;
133     const char*         m_entryName;
134     Target              m_target;
135     Version             m_version;
136     bool                m_versionLegacy;
137     Options             m_options;
138 
139     bool                m_outputPosition;
140     int                 m_outputTargets;
141 
142     const char*         m_outAttribPrefix;
143     const char*         m_inAttribPrefix;
144 
145     char                m_matrixRowFunction[64];
146     char                m_matrixCtorFunction[64];
147     char                m_matrixMulFunction[64];
148     char                m_clipFunction[64];
149     char                m_tex2DlodFunction[64];
150     char                m_tex2DbiasFunction[64];
151     char                m_tex2DgradFunction[64];
152     char                m_tex3DlodFunction[64];
153     char                m_texCUBEbiasFunction[64];
154 	char                m_texCUBElodFunction[ 64 ];
155     char                m_scalarSwizzle2Function[64];
156     char                m_scalarSwizzle3Function[64];
157     char                m_scalarSwizzle4Function[64];
158     char                m_sinCosFunction[64];
159 	char                m_bvecTernary[ 64 ];
160 	char                m_modfFunction[64];
161 
162     bool                m_error;
163 
164     char                m_reservedWord[s_numReservedWords][64];
165 
166     std::vector<matrixCtor> matrixCtors;
167     std::map<matrixCtor,std::string> matrixCtorsId;
168     std::vector<HLSLDeclaration*> globalVarsAssignments;
169 
170 };
171 
172 }
173 
174 #endif
175