Line data Source code
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_TRANSLATOR_OUTPUTHLSL_H_
8 : #define COMPILER_TRANSLATOR_OUTPUTHLSL_H_
9 :
10 : #include <list>
11 : #include <map>
12 : #include <stack>
13 :
14 : #include "angle_gl.h"
15 : #include "compiler/translator/ASTMetadataHLSL.h"
16 : #include "compiler/translator/IntermNode.h"
17 : #include "compiler/translator/ParseContext.h"
18 :
19 : class BuiltInFunctionEmulator;
20 :
21 : namespace sh
22 : {
23 : class StructureHLSL;
24 : class TextureFunctionHLSL;
25 : class UnfoldShortCircuit;
26 : class UniformHLSL;
27 :
28 : typedef std::map<TString, TIntermSymbol*> ReferencedSymbols;
29 :
30 : class OutputHLSL : public TIntermTraverser
31 : {
32 : public:
33 : OutputHLSL(sh::GLenum shaderType,
34 : int shaderVersion,
35 : const TExtensionBehavior &extensionBehavior,
36 : const char *sourcePath,
37 : ShShaderOutput outputType,
38 : int numRenderTargets,
39 : const std::vector<Uniform> &uniforms,
40 : ShCompileOptions compileOptions);
41 :
42 : ~OutputHLSL();
43 :
44 : void output(TIntermNode *treeRoot, TInfoSinkBase &objSink);
45 :
46 : const std::map<std::string, unsigned int> &getInterfaceBlockRegisterMap() const;
47 : const std::map<std::string, unsigned int> &getUniformRegisterMap() const;
48 :
49 : static TString initializer(const TType &type);
50 :
51 0 : TInfoSinkBase &getInfoSink() { ASSERT(!mInfoSinkStack.empty()); return *mInfoSinkStack.top(); }
52 :
53 : static bool canWriteAsHLSLLiteral(TIntermTyped *expression);
54 :
55 : protected:
56 : void header(TInfoSinkBase &out, const BuiltInFunctionEmulator *builtInFunctionEmulator);
57 :
58 : void writeFloat(TInfoSinkBase &out, float f);
59 : void writeSingleConstant(TInfoSinkBase &out, const TConstantUnion *const constUnion);
60 : const TConstantUnion *writeConstantUnionArray(TInfoSinkBase &out,
61 : const TConstantUnion *const constUnion,
62 : const size_t size);
63 :
64 : // Visit AST nodes and output their code to the body stream
65 : void visitSymbol(TIntermSymbol*);
66 : void visitRaw(TIntermRaw*);
67 : void visitConstantUnion(TIntermConstantUnion*);
68 : bool visitSwizzle(Visit visit, TIntermSwizzle *node) override;
69 : bool visitBinary(Visit visit, TIntermBinary*);
70 : bool visitUnary(Visit visit, TIntermUnary*);
71 : bool visitTernary(Visit visit, TIntermTernary *);
72 : bool visitIfElse(Visit visit, TIntermIfElse *);
73 : bool visitSwitch(Visit visit, TIntermSwitch *);
74 : bool visitCase(Visit visit, TIntermCase *);
75 : bool visitFunctionDefinition(Visit visit, TIntermFunctionDefinition *node) override;
76 : bool visitAggregate(Visit visit, TIntermAggregate*);
77 : bool visitBlock(Visit visit, TIntermBlock *node);
78 : bool visitDeclaration(Visit visit, TIntermDeclaration *node);
79 : bool visitLoop(Visit visit, TIntermLoop*);
80 : bool visitBranch(Visit visit, TIntermBranch*);
81 :
82 : bool handleExcessiveLoop(TInfoSinkBase &out, TIntermLoop *node);
83 :
84 : // Emit one of three strings depending on traverse phase. Called with literal strings so using const char* instead of TString.
85 : void outputTriplet(TInfoSinkBase &out,
86 : Visit visit,
87 : const char *preString,
88 : const char *inString,
89 : const char *postString);
90 : void outputLineDirective(TInfoSinkBase &out, int line);
91 : TString argumentString(const TIntermSymbol *symbol);
92 : int vectorSize(const TType &type) const;
93 :
94 : // Emit constructor. Called with literal names so using const char* instead of TString.
95 : void outputConstructor(TInfoSinkBase &out,
96 : Visit visit,
97 : const TType &type,
98 : const char *name,
99 : const TIntermSequence *parameters);
100 : const TConstantUnion *writeConstantUnion(TInfoSinkBase &out,
101 : const TType &type,
102 : const TConstantUnion *constUnion);
103 :
104 : void outputEqual(Visit visit, const TType &type, TOperator op, TInfoSinkBase &out);
105 :
106 : void writeEmulatedFunctionTriplet(TInfoSinkBase &out, Visit visit, const char *preStr);
107 : void makeFlaggedStructMaps(const std::vector<TIntermTyped *> &flaggedStructs);
108 :
109 : // Returns true if it found a 'same symbol' initializer (initializer that references the variable it's initting)
110 : bool writeSameSymbolInitializer(TInfoSinkBase &out, TIntermSymbol *symbolNode, TIntermTyped *expression);
111 : // Returns true if variable initializer could be written using literal {} notation.
112 : bool writeConstantInitialization(TInfoSinkBase &out,
113 : TIntermSymbol *symbolNode,
114 : TIntermTyped *expression);
115 :
116 : void writeDeferredGlobalInitializers(TInfoSinkBase &out);
117 : void writeIfElse(TInfoSinkBase &out, TIntermIfElse *node);
118 :
119 : // Returns the function name
120 : TString addStructEqualityFunction(const TStructure &structure);
121 : TString addArrayEqualityFunction(const TType &type);
122 : TString addArrayAssignmentFunction(const TType &type);
123 : TString addArrayConstructIntoFunction(const TType &type);
124 :
125 : // Ensures if the type is a struct, the struct is defined
126 : void ensureStructDefined(const TType &type);
127 :
128 : sh::GLenum mShaderType;
129 : int mShaderVersion;
130 : const TExtensionBehavior &mExtensionBehavior;
131 : const char *mSourcePath;
132 : const ShShaderOutput mOutputType;
133 : ShCompileOptions mCompileOptions;
134 :
135 : bool mInsideFunction;
136 :
137 : // Output streams
138 : TInfoSinkBase mHeader;
139 : TInfoSinkBase mBody;
140 : TInfoSinkBase mFooter;
141 :
142 : // A stack is useful when we want to traverse in the header, or in helper functions, but not always
143 : // write to the body. Instead use an InfoSink stack to keep our current state intact.
144 : // TODO (jmadill): Just passing an InfoSink in function parameters would be simpler.
145 : std::stack<TInfoSinkBase *> mInfoSinkStack;
146 :
147 : ReferencedSymbols mReferencedUniforms;
148 : ReferencedSymbols mReferencedInterfaceBlocks;
149 : ReferencedSymbols mReferencedAttributes;
150 : ReferencedSymbols mReferencedVaryings;
151 : ReferencedSymbols mReferencedOutputVariables;
152 :
153 : StructureHLSL *mStructureHLSL;
154 : UniformHLSL *mUniformHLSL;
155 : TextureFunctionHLSL *mTextureFunctionHLSL;
156 :
157 : // Parameters determining what goes in the header output
158 : bool mUsesFragColor;
159 : bool mUsesFragData;
160 : bool mUsesDepthRange;
161 : bool mUsesFragCoord;
162 : bool mUsesPointCoord;
163 : bool mUsesFrontFacing;
164 : bool mUsesPointSize;
165 : bool mUsesInstanceID;
166 : bool mUsesVertexID;
167 : bool mUsesFragDepth;
168 : bool mUsesXor;
169 : bool mUsesDiscardRewriting;
170 : bool mUsesNestedBreak;
171 : bool mRequiresIEEEStrictCompiling;
172 :
173 :
174 : int mNumRenderTargets;
175 :
176 : int mUniqueIndex; // For creating unique names
177 :
178 : CallDAG mCallDag;
179 : MetadataList mASTMetadataList;
180 : ASTMetadataHLSL *mCurrentFunctionMetadata;
181 : bool mOutputLod0Function;
182 : bool mInsideDiscontinuousLoop;
183 : int mNestedLoopDepth;
184 :
185 : TIntermSymbol *mExcessiveLoopIndex;
186 :
187 : TString structInitializerString(int indent, const TStructure &structure, const TString &rhsStructName);
188 :
189 : std::map<TIntermTyped*, TString> mFlaggedStructMappedNames;
190 : std::map<TIntermTyped*, TString> mFlaggedStructOriginalNames;
191 :
192 0 : struct HelperFunction
193 : {
194 : TString functionName;
195 : TString functionDefinition;
196 :
197 0 : virtual ~HelperFunction() {}
198 : };
199 :
200 : // A list of all equality comparison functions. It's important to preserve the order at
201 : // which we add the functions, since nested structures call each other recursively, and
202 : // structure equality functions may need to call array equality functions and vice versa.
203 : // The ownership of the pointers is maintained by the type-specific arrays.
204 : std::vector<HelperFunction*> mEqualityFunctions;
205 :
206 0 : struct StructEqualityFunction : public HelperFunction
207 : {
208 : const TStructure *structure;
209 : };
210 : std::vector<StructEqualityFunction*> mStructEqualityFunctions;
211 :
212 0 : struct ArrayHelperFunction : public HelperFunction
213 : {
214 : TType type;
215 : };
216 : std::vector<ArrayHelperFunction*> mArrayEqualityFunctions;
217 :
218 : std::vector<ArrayHelperFunction> mArrayAssignmentFunctions;
219 :
220 : // The construct-into functions are functions that fill an N-element array passed as an out parameter
221 : // with the other N parameters of the function. This is used to work around that arrays can't be
222 : // return values in HLSL.
223 : std::vector<ArrayHelperFunction> mArrayConstructIntoFunctions;
224 :
225 : private:
226 : TString samplerNamePrefixFromStruct(TIntermTyped *node);
227 : bool ancestorEvaluatesToSamplerInStruct(Visit visit);
228 : };
229 :
230 : }
231 :
232 : #endif // COMPILER_TRANSLATOR_OUTPUTHLSL_H_
|