1//
2// Copyright (c) 2002-2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#ifndef COMPILER_OUTPUTHLSL_H_
8#define COMPILER_OUTPUTHLSL_H_
9
10#include <list>
11#include <set>
12#include <map>
13
14#include <GLES3/gl3.h>
15#include <GLES2/gl2.h>
16
17#include "compiler/translator/intermediate.h"
18#include "compiler/translator/ParseContext.h"
19#include "common/shadervars.h"
20
21namespace sh
22{
23class UnfoldShortCircuit;
24
25class OutputHLSL : public TIntermTraverser
26{
27  public:
28    OutputHLSL(TParseContext &context, const ShBuiltInResources& resources, ShShaderOutput outputType);
29    ~OutputHLSL();
30
31    void output();
32
33    TInfoSinkBase &getBodyStream();
34    const std::vector<gl::Uniform> &getUniforms();
35    const std::vector<gl::InterfaceBlock> &getInterfaceBlocks() const;
36    const std::vector<gl::Attribute> &getOutputVariables() const;
37    const std::vector<gl::Attribute> &getAttributes() const;
38    const std::vector<gl::Varying> &getVaryings() const;
39
40    TString typeString(const TType &type);
41    TString textureString(const TType &type);
42    TString samplerString(const TType &type);
43    TString interpolationString(TQualifier qualifier);
44    TString structureString(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
45    TString structureTypeName(const TStructure &structure, bool useHLSLRowMajorPacking, bool useStd140Packing);
46    static TString qualifierString(TQualifier qualifier);
47    static TString arrayString(const TType &type);
48    static TString initializer(const TType &type);
49    static TString decorate(const TString &string);                      // Prepends an underscore to avoid naming clashes
50    static TString decorateUniform(const TString &string, const TType &type);
51    static TString decorateField(const TString &string, const TStructure &structure);
52
53  protected:
54    void header();
55
56    // Visit AST nodes and output their code to the body stream
57    void visitSymbol(TIntermSymbol*);
58    void visitRaw(TIntermRaw*);
59    void visitConstantUnion(TIntermConstantUnion*);
60    bool visitBinary(Visit visit, TIntermBinary*);
61    bool visitUnary(Visit visit, TIntermUnary*);
62    bool visitSelection(Visit visit, TIntermSelection*);
63    bool visitAggregate(Visit visit, TIntermAggregate*);
64    bool visitLoop(Visit visit, TIntermLoop*);
65    bool visitBranch(Visit visit, TIntermBranch*);
66
67    void traverseStatements(TIntermNode *node);
68    bool isSingleStatement(TIntermNode *node);
69    bool handleExcessiveLoop(TIntermLoop *node);
70    void outputTriplet(Visit visit, const TString &preString, const TString &inString, const TString &postString);
71    void outputLineDirective(int line);
72    TString argumentString(const TIntermSymbol *symbol);
73    int vectorSize(const TType &type) const;
74
75    void addConstructor(const TType &type, const TString &name, const TIntermSequence *parameters);
76    const ConstantUnion *writeConstantUnion(const TType &type, const ConstantUnion *constUnion);
77
78    TString structNameString(const TStructure &structure);
79
80    TParseContext &mContext;
81    const ShShaderOutput mOutputType;
82    UnfoldShortCircuit *mUnfoldShortCircuit;
83    bool mInsideFunction;
84
85    // Output streams
86    TInfoSinkBase mHeader;
87    TInfoSinkBase mBody;
88    TInfoSinkBase mFooter;
89
90    typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
91    ReferencedSymbols mReferencedUniforms;
92    ReferencedSymbols mReferencedInterfaceBlocks;
93    ReferencedSymbols mReferencedAttributes;
94    ReferencedSymbols mReferencedVaryings;
95    ReferencedSymbols mReferencedOutputVariables;
96
97    struct TextureFunction
98    {
99        enum Method
100        {
101            IMPLICIT,   // Mipmap LOD determined implicitly (standard lookup)
102            BIAS,
103            LOD,
104            LOD0,
105            LOD0BIAS,
106            SIZE,   // textureSize()
107            FETCH,
108            GRAD
109        };
110
111        TBasicType sampler;
112        int coords;
113        bool proj;
114        bool offset;
115        Method method;
116
117        TString name() const;
118
119        bool operator<(const TextureFunction &rhs) const;
120    };
121
122    typedef std::set<TextureFunction> TextureFunctionSet;
123
124    // Parameters determining what goes in the header output
125    TextureFunctionSet mUsesTexture;
126    bool mUsesFragColor;
127    bool mUsesFragData;
128    bool mUsesDepthRange;
129    bool mUsesFragCoord;
130    bool mUsesPointCoord;
131    bool mUsesFrontFacing;
132    bool mUsesPointSize;
133    bool mUsesFragDepth;
134    bool mUsesXor;
135    bool mUsesMod1;
136    bool mUsesMod2v;
137    bool mUsesMod2f;
138    bool mUsesMod3v;
139    bool mUsesMod3f;
140    bool mUsesMod4v;
141    bool mUsesMod4f;
142    bool mUsesFaceforward1;
143    bool mUsesFaceforward2;
144    bool mUsesFaceforward3;
145    bool mUsesFaceforward4;
146    bool mUsesAtan2_1;
147    bool mUsesAtan2_2;
148    bool mUsesAtan2_3;
149    bool mUsesAtan2_4;
150    bool mUsesDiscardRewriting;
151    bool mUsesNestedBreak;
152
153    int mNumRenderTargets;
154
155    typedef std::set<TString> Constructors;
156    Constructors mConstructors;
157
158    typedef std::set<TString> StructNames;
159    StructNames mStructNames;
160
161    typedef std::list<TString> StructDeclarations;
162    StructDeclarations mStructDeclarations;
163
164    int mUniqueIndex;   // For creating unique names
165
166    bool mContainsLoopDiscontinuity;
167    bool mOutputLod0Function;
168    bool mInsideDiscontinuousLoop;
169    int mNestedLoopDepth;
170
171    TIntermSymbol *mExcessiveLoopIndex;
172
173    int mUniformRegister;
174    int mInterfaceBlockRegister;
175    int mSamplerRegister;
176    int mPaddingCounter;
177
178    TString registerString(TIntermSymbol *operand);
179    int samplerRegister(TIntermSymbol *sampler);
180    int uniformRegister(TIntermSymbol *uniform);
181    void declareInterfaceBlockField(const TType &type, const TString &name, std::vector<gl::InterfaceBlockField>& output);
182    gl::Uniform declareUniformToList(const TType &type, const TString &name, int registerIndex, std::vector<gl::Uniform>& output);
183    void declareUniform(const TType &type, const TString &name, int index);
184    void declareVaryingToList(const TType &type, TQualifier baseTypeQualifier, const TString &name, std::vector<gl::Varying>& fieldsOut);
185
186    // Returns the uniform's register index
187    int declareUniformAndAssignRegister(const TType &type, const TString &name);
188
189    TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, const TField &field);
190    TString decoratePrivate(const TString &privateText);
191    TString interfaceBlockStructNameString(const TInterfaceBlock &interfaceBlockType);
192    TString interfaceBlockInstanceString(const TInterfaceBlock& interfaceBlock, unsigned int arrayIndex);
193    TString interfaceBlockFieldTypeString(const TField &field, TLayoutBlockStorage blockStorage);
194    TString interfaceBlockFieldString(const TInterfaceBlock &interfaceBlock, TLayoutBlockStorage blockStorage);
195    TString interfaceBlockStructString(const TInterfaceBlock &interfaceBlock);
196    TString interfaceBlockString(const TInterfaceBlock &interfaceBlock, unsigned int registerIndex, unsigned int arrayIndex);
197    TString std140PrePaddingString(const TType &type, int *elementIndex);
198    TString std140PostPaddingString(const TType &type, bool useHLSLRowMajorPacking);
199    TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
200
201    static GLenum glVariableType(const TType &type);
202    static GLenum glVariablePrecision(const TType &type);
203    static bool isVaryingIn(TQualifier qualifier);
204    static bool isVaryingOut(TQualifier qualifier);
205    static bool isVarying(TQualifier qualifier);
206
207    std::vector<gl::Uniform> mActiveUniforms;
208    std::vector<gl::InterfaceBlock> mActiveInterfaceBlocks;
209    std::vector<gl::Attribute> mActiveOutputVariables;
210    std::vector<gl::Attribute> mActiveAttributes;
211    std::vector<gl::Varying> mActiveVaryings;
212    std::map<TString, int> mStd140StructElementIndexes;
213    std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
214    std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
215
216    void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
217};
218}
219
220#endif   // COMPILER_OUTPUTHLSL_H_
221