2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
5 //Redistribution and use in source and binary forms, with or without
6 //modification, are permitted provided that the following conditions
9 // Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
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.
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.
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.
36 // Definition of the in-memory high-level intermediate representation
37 // of shaders. This is a tree that parser creates.
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.
44 #ifndef __INTERMEDIATE_H
45 #define __INTERMEDIATE_H
47 #include "../Include/Common.h"
48 #include "../Include/Types.h"
49 #include "../Include/ConstantUnion.h"
52 // Operators used by the high-level (parse tree) representation.
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.
58 EOpFunction
, // For function definition
59 EOpParameters
, // an aggregate listing the parameters to a function
106 EOpVectorTimesScalar
,
107 EOpVectorTimesMatrix
,
108 EOpMatrixTimesVector
,
109 EOpMatrixTimesScalar
,
117 EOpIndexDirectStruct
,
122 // Built-in functions potentially mapped to operators
163 EOpDPdx
, // Fragment only
164 EOpDPdy
, // Fragment only
165 EOpFwidth
, // Fragment only
167 EOpMatrixTimesMatrix
,
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
186 EOpKill
, // Fragment only
220 EOpVectorTimesMatrixAssign
,
221 EOpVectorTimesScalarAssign
,
222 EOpMatrixTimesScalarAssign
,
223 EOpMatrixTimesMatrixAssign
,
227 EOpInclusiveOrAssign
,
228 EOpExclusiveOrAssign
,
233 class TIntermTraverser
;
234 class TIntermAggregate
;
236 class TIntermConstantUnion
;
237 class TIntermSelection
;
243 // Base class for the tree nodes
247 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator
)
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() { }
265 // This is just to help yacc.
267 struct TIntermNodePair
{
276 // Intermediate class for nodes that have a type.
278 class TIntermTyped
: public TIntermNode
{
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
; }
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(); }
302 // Handle for, do-while, and while loops.
304 class TIntermLoop
: public TIntermNode
{
306 TIntermLoop(TIntermNode
* aBody
, TIntermTyped
* aTest
, TIntermTyped
* aTerminal
, bool 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
; }
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
324 // Handle break, continue, return, and kill.
326 class TIntermBranch
: public TIntermNode
{
328 TIntermBranch(TOperator op
, TIntermTyped
* e
) :
331 virtual void traverse(TIntermTraverser
*);
332 TOperator
getFlowOp() { return flowOp
; }
333 TIntermTyped
* getExpression() { return expression
; }
336 TIntermTyped
* expression
; // non-zero except for "return exp;" statements
340 // Nodes that correspond to symbols or constants in the source code.
342 class TIntermSymbol
: public TIntermTyped
{
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; }
358 class TIntermConstantUnion
: public TIntermTyped
{
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);
367 constUnion
*unionArrayPointer
;
371 // Intermediate class for node types that hold operators.
373 class TIntermOperator
: public TIntermTyped
{
375 TOperator
getOp() { return op
; }
376 bool modifiesState() const;
377 bool isConstructor() const;
378 virtual bool promote(TInfoSink
&) { return true; }
380 TIntermOperator(TOperator o
) : TIntermTyped(TType(EbtFloat
)), op(o
) {}
381 TIntermOperator(TOperator o
, TType
& t
) : TIntermTyped(t
), op(o
) {}
386 // Nodes for all the basic binary math operators.
388 class TIntermBinary
: public TIntermOperator
{
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
&);
404 // Nodes for unary math operators.
406 class TIntermUnary
: public TIntermOperator
{
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
&);
415 TIntermTyped
* operand
;
418 typedef TVector
<TIntermNode
*> TIntermSequence
;
419 typedef TVector
<int> TQualifierList
;
421 // Nodes that operate on an arbitrary sized set of children.
423 class TIntermAggregate
: public TIntermOperator
{
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
; }
444 TIntermAggregate(const TIntermAggregate
&); // disallow copy constructor
445 TIntermAggregate
& operator=(const TIntermAggregate
&); // disallow assignment operator
446 TIntermSequence sequence
;
447 TQualifierList qualifier
;
449 bool userDefined
; // used for user defined function names
452 TPragmaTable
*pragmaTable
;
456 // For if tests. Simplified since there is no switch statement.
458 class TIntermSelection
: public TIntermTyped
{
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; }
470 TIntermTyped
* condition
;
471 TIntermNode
* trueBlock
;
472 TIntermNode
* falseBlock
;
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.
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.
483 class TIntermTraverser
{
485 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator
)
489 visitConstantUnion(0),
499 rightToLeft(false) {}
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
*);
516 #endif // __INTERMEDIATE_H