OSDN Git Service

Fix attribute location binding
[android-x86/external-swiftshader.git] / src / OpenGL / compiler / OutputASM.h
1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #ifndef COMPILER_OUTPUTASM_H_
16 #define COMPILER_OUTPUTASM_H_
17
18 #include "intermediate.h"
19 #include "ParseHelper.h"
20 #include "Shader/PixelShader.hpp"
21 #include "Shader/VertexShader.hpp"
22
23 #include <list>
24 #include <set>
25 #include <map>
26
27 namespace es2
28 {
29         class Shader;
30 }
31
32 typedef unsigned int GLenum;
33
34 namespace glsl
35 {
36         struct BlockMemberInfo
37         {
38                 BlockMemberInfo() : offset(-1), arrayStride(-1), matrixStride(-1), isRowMajorMatrix(false) {}
39
40                 BlockMemberInfo(int offset, int arrayStride, int matrixStride, bool isRowMajorMatrix)
41                         : offset(offset),
42                         arrayStride(arrayStride),
43                         matrixStride(matrixStride),
44                         isRowMajorMatrix(isRowMajorMatrix)
45                 {}
46
47                 static BlockMemberInfo getDefaultBlockInfo()
48                 {
49                         return BlockMemberInfo(-1, -1, -1, false);
50                 }
51
52                 int offset;
53                 int arrayStride;
54                 int matrixStride;
55                 bool isRowMajorMatrix;
56         };
57
58         struct Uniform
59         {
60                 Uniform(GLenum type, GLenum precision, const std::string &name, int arraySize, int registerIndex, int blockId, const BlockMemberInfo& blockMemberInfo);
61
62                 GLenum type;
63                 GLenum precision;
64                 std::string name;
65                 int arraySize;
66
67                 int registerIndex;
68
69                 int blockId;
70                 BlockMemberInfo blockInfo;
71         };
72
73         typedef std::vector<Uniform> ActiveUniforms;
74
75         struct UniformBlock
76         {
77                 UniformBlock(const std::string& name, unsigned int dataSize, unsigned int arraySize,
78                              TLayoutBlockStorage layout, bool isRowMajorLayout, int registerIndex, int blockId);
79
80                 std::string name;
81                 unsigned int dataSize;
82                 unsigned int arraySize;
83                 TLayoutBlockStorage layout;
84                 bool isRowMajorLayout;
85                 std::vector<int> fields;
86
87                 int registerIndex;
88
89                 int blockId;
90         };
91
92         class BlockLayoutEncoder
93         {
94         public:
95                 BlockLayoutEncoder(bool rowMajor);
96                 virtual ~BlockLayoutEncoder() {}
97
98                 BlockMemberInfo encodeType(const TType &type);
99
100                 size_t getBlockSize() const { return mCurrentOffset * BytesPerComponent; }
101
102                 virtual void enterAggregateType() = 0;
103                 virtual void exitAggregateType() = 0;
104
105                 static const size_t BytesPerComponent = 4u;
106                 static const unsigned int ComponentsPerRegister = 4u;
107
108                 static size_t getBlockRegister(const BlockMemberInfo &info);
109                 static size_t getBlockRegisterElement(const BlockMemberInfo &info);
110
111         protected:
112                 size_t mCurrentOffset;
113                 bool isRowMajor;
114
115                 void nextRegister();
116
117                 virtual void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) = 0;
118                 virtual void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) = 0;
119         };
120
121         // Block layout according to the std140 block layout
122         // See "Standard Uniform Block Layout" in Section 2.11.6 of the OpenGL ES 3.0 specification
123         class Std140BlockEncoder : public BlockLayoutEncoder
124         {
125         public:
126                 Std140BlockEncoder(bool rowMajor);
127
128                 void enterAggregateType() override;
129                 void exitAggregateType() override;
130
131         protected:
132                 void getBlockLayoutInfo(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int *arrayStrideOut, int *matrixStrideOut) override;
133                 void advanceOffset(const TType &type, unsigned int arraySize, bool isRowMajorMatrix, int arrayStride, int matrixStride) override;
134         };
135
136         typedef std::vector<UniformBlock> ActiveUniformBlocks;
137
138         struct Attribute
139         {
140                 Attribute();
141                 Attribute(GLenum type, const std::string &name, int arraySize, int location, int registerIndex);
142
143                 GLenum type;
144                 std::string name;
145                 int arraySize;
146                 int location;
147
148                 int registerIndex;
149         };
150
151         typedef std::vector<Attribute> ActiveAttributes;
152
153         struct Varying
154         {
155                 Varying(GLenum type, const std::string &name, int arraySize, int reg = -1, int col = -1)
156                         : type(type), name(name), arraySize(arraySize), reg(reg), col(col)
157                 {
158                 }
159
160                 bool isArray() const
161                 {
162                         return arraySize >= 1;
163                 }
164
165                 int size() const   // Unify with es2::Uniform?
166                 {
167                         return arraySize > 0 ? arraySize : 1;
168                 }
169
170                 GLenum type;
171                 std::string name;
172                 int arraySize;
173
174                 int reg;    // First varying register, assigned during link
175                 int col;    // First register element, assigned during link
176         };
177
178         typedef std::list<Varying> VaryingList;
179
180         class Shader
181         {
182                 friend class OutputASM;
183         public:
184                 virtual ~Shader() {};
185                 virtual sw::Shader *getShader() const = 0;
186                 virtual sw::PixelShader *getPixelShader() const;
187                 virtual sw::VertexShader *getVertexShader() const;
188                 int getShaderVersion() const { return shaderVersion; }
189
190         protected:
191                 VaryingList varyings;
192                 ActiveUniforms activeUniforms;
193                 ActiveAttributes activeAttributes;
194                 ActiveUniformBlocks activeUniformBlocks;
195                 int shaderVersion;
196         };
197
198         struct Function
199         {
200                 Function(int label, const char *name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
201                 {
202                 }
203
204                 Function(int label, const TString &name, TIntermSequence *arg, TIntermTyped *ret) : label(label), name(name), arg(arg), ret(ret)
205                 {
206                 }
207
208                 int label;
209                 TString name;
210                 TIntermSequence *arg;
211                 TIntermTyped *ret;
212         };
213
214         typedef sw::Shader::Instruction Instruction;
215
216         class Temporary;
217
218         class OutputASM : public TIntermTraverser
219         {
220         public:
221                 explicit OutputASM(TParseContext &context, Shader *shaderObject);
222                 ~OutputASM();
223
224                 void output();
225
226                 void freeTemporary(Temporary *temporary);
227
228         private:
229                 enum Scope
230                 {
231                         GLOBAL,
232                         FUNCTION
233                 };
234
235                 struct TextureFunction
236                 {
237                         TextureFunction(const TString& name);
238
239                         enum Method
240                         {
241                                 IMPLICIT,   // Mipmap LOD determined implicitly (standard lookup)
242                                 LOD,
243                                 SIZE,   // textureSize()
244                                 FETCH,
245                                 GRAD
246                         };
247
248                         Method method;
249                         bool proj;
250                         bool offset;
251                 };
252
253                 void emitShader(Scope scope);
254
255                 // Visit AST nodes and output their code to the body stream
256                 void visitSymbol(TIntermSymbol*) override;
257                 bool visitBinary(Visit visit, TIntermBinary*) override;
258                 bool visitUnary(Visit visit, TIntermUnary*) override;
259                 bool visitSelection(Visit visit, TIntermSelection*) override;
260                 bool visitAggregate(Visit visit, TIntermAggregate*) override;
261                 bool visitLoop(Visit visit, TIntermLoop*) override;
262                 bool visitBranch(Visit visit, TIntermBranch*) override;
263                 bool visitSwitch(Visit, TIntermSwitch*) override;
264
265                 sw::Shader::Opcode getOpcode(sw::Shader::Opcode op, TIntermTyped *in) const;
266                 Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0, TIntermNode *src3 = 0, TIntermNode *src4 = 0);
267                 Instruction *emit(sw::Shader::Opcode op, TIntermTyped *dst, int dstIndex, TIntermNode *src0 = 0, int index0 = 0, TIntermNode *src1 = 0, int index1 = 0,
268                                   TIntermNode *src2 = 0, int index2 = 0, TIntermNode *src3 = 0, int index3 = 0, TIntermNode *src4 = 0, int index4 = 0);
269                 Instruction *emitCast(TIntermTyped *dst, TIntermTyped *src);
270                 Instruction *emitCast(TIntermTyped *dst, int dstIndex, TIntermTyped *src, int srcIndex);
271                 void emitBinary(sw::Shader::Opcode op, TIntermTyped *dst = 0, TIntermNode *src0 = 0, TIntermNode *src1 = 0, TIntermNode *src2 = 0);
272                 void emitAssign(sw::Shader::Opcode op, TIntermTyped *result, TIntermTyped *lhs, TIntermTyped *src0, TIntermTyped *src1 = 0);
273                 void emitCmp(sw::Shader::Control cmpOp, TIntermTyped *dst, TIntermNode *left, TIntermNode *right, int index = 0);
274                 void emitDeterminant(TIntermTyped *result, TIntermTyped *arg, int size, int col = -1, int row = -1, int outCol = 0, int outRow = 0);
275                 void source(sw::Shader::SourceParameter &parameter, TIntermNode *argument, int index = 0);
276                 void destination(sw::Shader::DestinationParameter &parameter, TIntermTyped *argument, int index = 0);
277                 void copy(TIntermTyped *dst, TIntermNode *src, int offset = 0);
278                 void assignLvalue(TIntermTyped *dst, TIntermTyped *src);
279                 void evaluateRvalue(TIntermTyped *node);
280                 int lvalue(sw::Shader::DestinationParameter &dst, TIntermTyped *node);
281                 int lvalue(TIntermTyped *&root, unsigned int &offset, sw::Shader::Relative &rel, unsigned char &mask, Temporary &address, TIntermTyped *node);
282                 sw::Shader::ParameterType registerType(TIntermTyped *operand);
283                 bool hasFlatQualifier(TIntermTyped *operand);
284                 unsigned int registerIndex(TIntermTyped *operand);
285                 int writeMask(TIntermTyped *destination, int index = 0);
286                 int readSwizzle(TIntermTyped *argument, int size);
287                 bool trivial(TIntermTyped *expression, int budget);   // Fast to compute and no side effects
288                 int cost(TIntermNode *expression, int budget);
289                 const Function *findFunction(const TString &name);
290
291                 int temporaryRegister(TIntermTyped *temporary);
292                 int varyingRegister(TIntermTyped *varying);
293                 void setPixelShaderInputs(const TType& type, int var, bool flat);
294                 void declareVarying(TIntermTyped *varying, int reg);
295                 void declareVarying(const TType &type, const TString &name, int registerIndex);
296                 int uniformRegister(TIntermTyped *uniform);
297                 int attributeRegister(TIntermTyped *attribute);
298                 int fragmentOutputRegister(TIntermTyped *fragmentOutput);
299                 int samplerRegister(TIntermTyped *sampler);
300                 int samplerRegister(TIntermSymbol *sampler);
301                 bool isSamplerRegister(TIntermTyped *operand);
302
303                 typedef std::vector<TIntermTyped*> VariableArray;
304
305                 int lookup(VariableArray &list, TIntermTyped *variable);
306                 int lookup(VariableArray &list, TInterfaceBlock *block);
307                 int blockMemberLookup(const TType &type, const TString &name, int registerIndex);
308                 int allocate(VariableArray &list, TIntermTyped *variable);
309                 void free(VariableArray &list, TIntermTyped *variable);
310
311                 void declareUniform(const TType &type, const TString &name, int registerIndex, int blockId = -1, BlockLayoutEncoder* encoder = nullptr);
312                 GLenum glVariableType(const TType &type);
313                 GLenum glVariablePrecision(const TType &type);
314
315                 static int dim(TIntermNode *v);
316                 static int dim2(TIntermNode *m);
317                 static unsigned int loopCount(TIntermLoop *node);
318
319                 Shader *const shaderObject;
320                 sw::Shader *shader;
321                 sw::PixelShader *pixelShader;
322                 sw::VertexShader *vertexShader;
323
324                 VariableArray temporaries;
325                 VariableArray uniforms;
326                 VariableArray varyings;
327                 VariableArray attributes;
328                 VariableArray samplers;
329                 VariableArray fragmentOutputs;
330
331                 struct TypedMemberInfo : public BlockMemberInfo
332                 {
333                         TypedMemberInfo() {}
334                         TypedMemberInfo(const BlockMemberInfo& b, const TType& t) : BlockMemberInfo(b), type(t) {}
335                         TType type;
336                 };
337                 struct ArgumentInfo
338                 {
339                         ArgumentInfo(const BlockMemberInfo& b, const TType& t, int clampedIndex, int bufferIndex) :
340                             typedMemberInfo(b, t), clampedIndex(clampedIndex), bufferIndex(bufferIndex) {}
341                         TypedMemberInfo typedMemberInfo;
342                         int clampedIndex;
343                         int bufferIndex;
344                 };
345                 int getBlockId(TIntermTyped *argument);
346                 ArgumentInfo getArgumentInfo(TIntermTyped *argument, int index);
347
348                 typedef std::map<int, TypedMemberInfo> BlockDefinitionIndexMap;
349                 std::vector<BlockDefinitionIndexMap> blockDefinitions;
350
351                 Scope emitScope;
352                 Scope currentScope;
353
354                 int currentFunction;
355                 std::vector<Function> functionArray;
356
357                 TQualifier outputQualifier;
358
359                 TParseContext &mContext;
360         };
361
362         class LoopUnrollable : public TIntermTraverser
363         {
364         public:
365                 bool traverse(TIntermNode *node);
366
367         private:
368                 bool visitBranch(Visit visit, TIntermBranch *node);
369                 bool visitLoop(Visit visit, TIntermLoop *loop);
370                 bool visitAggregate(Visit visit, TIntermAggregate *node);
371
372                 int loopDepth;
373                 bool loopUnrollable;
374         };
375 }
376
377 #endif   // COMPILER_OUTPUTASM_H_