updated some printfs, added comment about sched_yield
[mesa.git] / src / mesa / shader / slang / Include / intermediate.h
1 //
2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 //All rights reserved.
4 //
5 //Redistribution and use in source and binary forms, with or without
6 //modification, are permitted provided that the following conditions
7 //are met:
8 //
9 // Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
16 //
17 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
20 //
21 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //POSSIBILITY OF SUCH DAMAGE.
33 //
34
35 //
36 // Definition of the in-memory high-level intermediate representation
37 // of shaders. This is a tree that parser creates.
38 //
39 // Nodes in the tree are defined as a hierarchy of classes derived from
40 // TIntermNode. Each is a node in a tree. There is no preset branching factor;
41 // each node can have it's own type of list of children.
42 //
43
44 #ifndef __INTERMEDIATE_H
45 #define __INTERMEDIATE_H
46
47 #include "../Include/Common.h"
48 #include "../Include/Types.h"
49 #include "../Include/ConstantUnion.h"
50
51 //
52 // Operators used by the high-level (parse tree) representation.
53 //
54 enum TOperator {
55 EOpNull, // if in a node, should only mean a node is still being built
56 EOpSequence, // denotes a list of statements, or parameters, etc.
57 EOpFunctionCall,
58 EOpFunction, // For function definition
59 EOpParameters, // an aggregate listing the parameters to a function
60
61 //
62 // Unary operators
63 //
64
65 EOpNegative,
66 EOpLogicalNot,
67 EOpVectorLogicalNot,
68 EOpBitwiseNot,
69
70 EOpPostIncrement,
71 EOpPostDecrement,
72 EOpPreIncrement,
73 EOpPreDecrement,
74
75 EOpConvIntToBool,
76 EOpConvFloatToBool,
77 EOpConvBoolToFloat,
78 EOpConvIntToFloat,
79 EOpConvFloatToInt,
80 EOpConvBoolToInt,
81
82 //
83 // binary operations
84 //
85
86 EOpAdd,
87 EOpSub,
88 EOpMul,
89 EOpDiv,
90 EOpMod,
91 EOpRightShift,
92 EOpLeftShift,
93 EOpAnd,
94 EOpInclusiveOr,
95 EOpExclusiveOr,
96 EOpEqual,
97 EOpNotEqual,
98 EOpVectorEqual,
99 EOpVectorNotEqual,
100 EOpLessThan,
101 EOpGreaterThan,
102 EOpLessThanEqual,
103 EOpGreaterThanEqual,
104 EOpComma,
105
106 EOpVectorTimesScalar,
107 EOpVectorTimesMatrix,
108 EOpMatrixTimesVector,
109 EOpMatrixTimesScalar,
110
111 EOpLogicalOr,
112 EOpLogicalXor,
113 EOpLogicalAnd,
114
115 EOpIndexDirect,
116 EOpIndexIndirect,
117 EOpIndexDirectStruct,
118
119 EOpVectorSwizzle,
120
121 //
122 // Built-in functions potentially mapped to operators
123 //
124
125 EOpRadians,
126 EOpDegrees,
127 EOpSin,
128 EOpCos,
129 EOpTan,
130 EOpAsin,
131 EOpAcos,
132 EOpAtan,
133
134 EOpPow,
135 EOpExp,
136 EOpLog,
137 EOpExp2,
138 EOpLog2,
139 EOpSqrt,
140 EOpInverseSqrt,
141
142 EOpAbs,
143 EOpSign,
144 EOpFloor,
145 EOpCeil,
146 EOpFract,
147 EOpMin,
148 EOpMax,
149 EOpClamp,
150 EOpMix,
151 EOpStep,
152 EOpSmoothStep,
153
154 EOpLength,
155 EOpDistance,
156 EOpDot,
157 EOpCross,
158 EOpNormalize,
159 EOpFaceForward,
160 EOpReflect,
161 EOpRefract,
162
163 EOpDPdx, // Fragment only
164 EOpDPdy, // Fragment only
165 EOpFwidth, // Fragment only
166
167 EOpMatrixTimesMatrix,
168
169 EOpAny,
170 EOpAll,
171
172 EOpItof, // pack/unpack only
173 EOpFtoi, // pack/unpack only
174 EOpSkipPixels, // pack/unpack only
175 EOpReadInput, // unpack only
176 EOpWritePixel, // unpack only
177 EOpBitmapLsb, // unpack only
178 EOpBitmapMsb, // unpack only
179 EOpWriteOutput, // pack only
180 EOpReadPixel, // pack only
181
182 //
183 // Branch
184 //
185
186 EOpKill, // Fragment only
187 EOpReturn,
188 EOpBreak,
189 EOpContinue,
190
191 //
192 // Constructors
193 //
194
195 EOpConstructInt,
196 EOpConstructBool,
197 EOpConstructFloat,
198 EOpConstructVec2,
199 EOpConstructVec3,
200 EOpConstructVec4,
201 EOpConstructBVec2,
202 EOpConstructBVec3,
203 EOpConstructBVec4,
204 EOpConstructIVec2,
205 EOpConstructIVec3,
206 EOpConstructIVec4,
207 EOpConstructMat2,
208 EOpConstructMat3,
209 EOpConstructMat4,
210 EOpConstructStruct,
211
212 //
213 // moves
214 //
215
216 EOpAssign,
217 EOpAddAssign,
218 EOpSubAssign,
219 EOpMulAssign,
220 EOpVectorTimesMatrixAssign,
221 EOpVectorTimesScalarAssign,
222 EOpMatrixTimesScalarAssign,
223 EOpMatrixTimesMatrixAssign,
224 EOpDivAssign,
225 EOpModAssign,
226 EOpAndAssign,
227 EOpInclusiveOrAssign,
228 EOpExclusiveOrAssign,
229 EOpLeftShiftAssign,
230 EOpRightShiftAssign
231 };
232
233 class TIntermTraverser;
234 class TIntermAggregate;
235 class TIntermBinary;
236 class TIntermConstantUnion;
237 class TIntermSelection;
238 class TIntermTyped;
239 class TIntermSymbol;
240 class TInfoSink;
241
242 //
243 // Base class for the tree nodes
244 //
245 class TIntermNode {
246 public:
247 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
248
249 TIntermNode() : line(0) {}
250 virtual TSourceLoc getLine() const { return line; }
251 virtual void setLine(TSourceLoc l) { line = l; }
252 virtual void traverse(TIntermTraverser*) = 0;
253 virtual TIntermTyped* getAsTyped() { return 0; }
254 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
255 virtual TIntermAggregate* getAsAggregate() { return 0; }
256 virtual TIntermBinary* getAsBinaryNode() { return 0; }
257 virtual TIntermSelection* getAsSelectionNode() { return 0; }
258 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
259 virtual ~TIntermNode() { }
260 protected:
261 TSourceLoc line;
262 };
263
264 //
265 // This is just to help yacc.
266 //
267 struct TIntermNodePair {
268 TIntermNode* node1;
269 TIntermNode* node2;
270 };
271
272 class TIntermSymbol;
273 class TIntermBinary;
274
275 //
276 // Intermediate class for nodes that have a type.
277 //
278 class TIntermTyped : public TIntermNode {
279 public:
280 TIntermTyped(const TType& t) : type(t) { }
281 virtual TIntermTyped* getAsTyped() { return this; }
282 virtual void setType(const TType& t) { type = t; }
283 virtual TType getType() const { return type; }
284 virtual TType* getTypePointer() { return &type; }
285
286 virtual TBasicType getBasicType() const { return type.getBasicType(); }
287 virtual TQualifier getQualifier() const { return type.getQualifier(); }
288 virtual int getNominalSize() const { return type.getNominalSize(); }
289 virtual int getSize() const { return type.getInstanceSize(); }
290 virtual bool isMatrix() const { return type.isMatrix(); }
291 virtual bool isArray() const { return type.isArray(); }
292 virtual bool isVector() const { return type.isVector(); }
293 const char* getBasicString() const { return type.getBasicString(); }
294 const char* getQualifierString() const { return type.getQualifierString(); }
295 TString getCompleteString() const { return type.getCompleteString(); }
296
297 protected:
298 TType type;
299 };
300
301 //
302 // Handle for, do-while, and while loops.
303 //
304 class TIntermLoop : public TIntermNode {
305 public:
306 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
307 body(aBody),
308 test(aTest),
309 terminal(aTerminal),
310 first(testFirst) { }
311 virtual void traverse(TIntermTraverser*);
312 TIntermNode* getBody() { return body; }
313 TIntermTyped* getTest() { return test; }
314 TIntermTyped* getTerminal() { return terminal; }
315 bool testFirst() { return first; }
316 protected:
317 TIntermNode* body; // code to loop over
318 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
319 TIntermTyped* terminal; // exists for for-loops
320 bool first; // true for while and for, not for do-while
321 };
322
323 //
324 // Handle break, continue, return, and kill.
325 //
326 class TIntermBranch : public TIntermNode {
327 public:
328 TIntermBranch(TOperator op, TIntermTyped* e) :
329 flowOp(op),
330 expression(e) { }
331 virtual void traverse(TIntermTraverser*);
332 TOperator getFlowOp() { return flowOp; }
333 TIntermTyped* getExpression() { return expression; }
334 protected:
335 TOperator flowOp;
336 TIntermTyped* expression; // non-zero except for "return exp;" statements
337 };
338
339 //
340 // Nodes that correspond to symbols or constants in the source code.
341 //
342 class TIntermSymbol : public TIntermTyped {
343 public:
344 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
345 // per process globalpoolallocator, then it causes increased memory usage per compile
346 // it is essential to use "symbol = sym" to assign to symbol
347 TIntermSymbol(int i, const TString& sym, const TType& t) :
348 TIntermTyped(t), id(i) { symbol = sym;}
349 virtual int getId() const { return id; }
350 virtual const TString& getSymbol() const { return symbol; }
351 virtual void traverse(TIntermTraverser*);
352 virtual TIntermSymbol* getAsSymbolNode() { return this; }
353 protected:
354 int id;
355 TString symbol;
356 };
357
358 class TIntermConstantUnion : public TIntermTyped {
359 public:
360 TIntermConstantUnion(constUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
361 constUnion* getUnionArrayPointer() const { return unionArrayPointer; }
362 void setUnionArrayPointer(constUnion *c) { unionArrayPointer = c; }
363 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
364 virtual void traverse(TIntermTraverser* );
365 virtual TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&, bool);
366 protected:
367 constUnion *unionArrayPointer;
368 };
369
370 //
371 // Intermediate class for node types that hold operators.
372 //
373 class TIntermOperator : public TIntermTyped {
374 public:
375 TOperator getOp() { return op; }
376 bool modifiesState() const;
377 bool isConstructor() const;
378 virtual bool promote(TInfoSink&) { return true; }
379 protected:
380 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat)), op(o) {}
381 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
382 TOperator op;
383 };
384
385 //
386 // Nodes for all the basic binary math operators.
387 //
388 class TIntermBinary : public TIntermOperator {
389 public:
390 TIntermBinary(TOperator o) : TIntermOperator(o) {}
391 virtual void traverse(TIntermTraverser*);
392 virtual void setLeft(TIntermTyped* n) { left = n; }
393 virtual void setRight(TIntermTyped* n) { right = n; }
394 virtual TIntermTyped* getLeft() const { return left; }
395 virtual TIntermTyped* getRight() const { return right; }
396 virtual TIntermBinary* getAsBinaryNode() { return this; }
397 virtual bool promote(TInfoSink&);
398 protected:
399 TIntermTyped* left;
400 TIntermTyped* right;
401 };
402
403 //
404 // Nodes for unary math operators.
405 //
406 class TIntermUnary : public TIntermOperator {
407 public:
408 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
409 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
410 virtual void traverse(TIntermTraverser*);
411 virtual void setOperand(TIntermTyped* o) { operand = o; }
412 virtual TIntermTyped* getOperand() { return operand; }
413 virtual bool promote(TInfoSink&);
414 protected:
415 TIntermTyped* operand;
416 };
417
418 typedef TVector<TIntermNode*> TIntermSequence;
419 typedef TVector<int> TQualifierList;
420 //
421 // Nodes that operate on an arbitrary sized set of children.
422 //
423 class TIntermAggregate : public TIntermOperator {
424 public:
425 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
426 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
427 ~TIntermAggregate() { delete pragmaTable; }
428 virtual TIntermAggregate* getAsAggregate() { return this; }
429 virtual void setOperator(TOperator o) { op = o; }
430 virtual TIntermSequence& getSequence() { return sequence; }
431 virtual void setName(const TString& n) { name = n; }
432 virtual const TString& getName() const { return name; }
433 virtual void traverse(TIntermTraverser*);
434 virtual void setUserDefined() { userDefined = true; }
435 virtual bool isUserDefined() { return userDefined; }
436 virtual TQualifierList& getQualifier() { return qualifier; }
437 void setOptimize(bool o) { optimize = o; }
438 void setDebug(bool d) { debug = d; }
439 bool getOptimize() { return optimize; }
440 bool getDebug() { return debug; }
441 void addToPragmaTable(const TPragmaTable& pTable);
442 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
443 protected:
444 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
445 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
446 TIntermSequence sequence;
447 TQualifierList qualifier;
448 TString name;
449 bool userDefined; // used for user defined function names
450 bool optimize;
451 bool debug;
452 TPragmaTable *pragmaTable;
453 };
454
455 //
456 // For if tests. Simplified since there is no switch statement.
457 //
458 class TIntermSelection : public TIntermTyped {
459 public:
460 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
461 TIntermTyped(TType(EbtVoid)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
462 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
463 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
464 virtual void traverse(TIntermTraverser*);
465 virtual TIntermNode* getCondition() const { return condition; }
466 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
467 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
468 virtual TIntermSelection* getAsSelectionNode() { return this; }
469 protected:
470 TIntermTyped* condition;
471 TIntermNode* trueBlock;
472 TIntermNode* falseBlock;
473 };
474
475 //
476 // For traversing the tree. User should derive from this,
477 // put their traversal specific data in it, and then pass
478 // it to a Traverse method.
479 //
480 // When using this, just fill in the methods for nodes you want visited.
481 // Return false from a pre-visit to skip visiting that node's subtree.
482 //
483 class TIntermTraverser {
484 public:
485 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
486
487 TIntermTraverser() :
488 visitSymbol(0),
489 visitConstantUnion(0),
490 visitBinary(0),
491 visitUnary(0),
492 visitSelection(0),
493 visitAggregate(0),
494 visitLoop(0),
495 visitBranch(0),
496 depth(0),
497 preVisit(true),
498 postVisit(false),
499 rightToLeft(false) {}
500
501 void (*visitSymbol)(TIntermSymbol*, TIntermTraverser*);
502 void (*visitConstantUnion)(TIntermConstantUnion*, TIntermTraverser*);
503 bool (*visitBinary)(bool preVisit, TIntermBinary*, TIntermTraverser*);
504 bool (*visitUnary)(bool preVisit, TIntermUnary*, TIntermTraverser*);
505 bool (*visitSelection)(bool preVisit, TIntermSelection*, TIntermTraverser*);
506 bool (*visitAggregate)(bool preVisit, TIntermAggregate*, TIntermTraverser*);
507 bool (*visitLoop)(bool preVisit, TIntermLoop*, TIntermTraverser*);
508 bool (*visitBranch)(bool preVisit, TIntermBranch*, TIntermTraverser*);
509
510 int depth;
511 bool preVisit;
512 bool postVisit;
513 bool rightToLeft;
514 };
515
516 #endif // __INTERMEDIATE_H