Make ES 100 gl_FragData be a mediump, and fix some warnings from g++.
[platform/upstream/glslang.git] / glslang / MachineIndependent / parseConst.cpp
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 // Travarse a tree of constants to create a single folded constant.
37 // It should only be used when the whole tree is known to be constant.
38 //
39
40 #include "ParseHelper.h"
41
42 namespace glslang {
43
44 class TConstTraverser : public TIntermTraverser {
45 public:
46     TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t) : unionArray(cUnion), type(t),
47         constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), 
48         matrixCols(0), matrixRows(0) {  index = 0; tOp = EOpNull;}
49     int index;
50     TConstUnionArray unionArray;
51     TOperator tOp;
52     const TType& type;
53     TOperator constructorType;
54     bool singleConstantParam;
55     bool error;
56     int size; // size of the constructor ( 4 for vec4)
57     bool isMatrix;
58     int matrixCols;
59     int matrixRows;
60 };
61
62 bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
63 {
64     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
65
66     if (! node->isConstructor() && node->getOp() != EOpComma) {
67         oit->error = true;
68
69         return false;  
70     }
71
72     if (node->getSequence().size() == 0) {
73         oit->error = true;
74
75         return false;
76     }
77
78     bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
79     if (flag) {
80         oit->singleConstantParam = true; 
81         oit->constructorType = node->getOp();
82         oit->size = node->getType().getObjectSize();
83
84         if (node->getType().isMatrix()) {
85             oit->isMatrix = true;
86             oit->matrixCols = node->getType().getMatrixCols();
87             oit->matrixRows = node->getType().getMatrixRows();
88         }
89     }       
90
91     for (TIntermSequence::iterator p = node->getSequence().begin(); 
92                                    p != node->getSequence().end(); p++) {
93
94         if (node->getOp() == EOpComma)
95             oit->index = 0;           
96
97         (*p)->traverse(oit);
98     }   
99     if (flag) 
100     {
101         oit->singleConstantParam = false;   
102         oit->constructorType = EOpNull;
103         oit->size = 0;
104         oit->isMatrix = false;
105         oit->matrixCols = 0;
106         oit->matrixRows = 0;
107     }
108
109     return false;
110 }
111
112 void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
113 {
114     TConstTraverser* oit = static_cast<TConstTraverser*>(it);
115     TConstUnionArray leftUnionArray(oit->unionArray);
116     int instanceSize = oit->type.getObjectSize();
117
118     if (oit->index >= instanceSize)
119         return;
120
121     if (!oit->singleConstantParam) {
122         int size = node->getType().getObjectSize();
123     
124         const TConstUnionArray& rightUnionArray = node->getConstArray();
125         for (int i=0; i < size; i++) {
126             if (oit->index >= instanceSize)
127                 return;
128             leftUnionArray[oit->index] = rightUnionArray[i];
129
130             (oit->index)++;
131         }
132     } else {
133         int size, totalSize, matrixRows;
134         bool isMatrix = false;
135         size = oit->size;
136         matrixRows = oit->matrixRows;
137         isMatrix = oit->isMatrix;
138         totalSize = oit->index + size;
139         const TConstUnionArray& rightUnionArray = node->getConstArray();
140         if (! isMatrix) {
141             int count = 0;
142             for (int i = oit->index; i < totalSize; i++) {
143                 if (i >= instanceSize)
144                     return;
145
146                 leftUnionArray[i] = rightUnionArray[count];
147
148                 (oit->index)++;
149                 
150                 if (node->getType().getObjectSize() > 1)
151                     count++;
152             }
153         } else {  // for matrix constructors
154             int count = 0;
155             int index = oit->index;
156             for (int i = index; i < totalSize; i++) {
157                 if (i >= instanceSize)
158                     return;
159                 if (index - i == 0 || (i - index) % (matrixRows + 1) == 0 )
160                     leftUnionArray[i] = rightUnionArray[count];
161                 else 
162                     leftUnionArray[i].setDConst(0.0);
163
164                 (oit->index)++;
165
166                 if (node->getType().getObjectSize() > 1)
167                     count++;                
168             }
169         }
170     }
171 }
172
173 bool TIntermediate::parseConstTree(TSourceLoc line, TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam)
174 {
175     if (root == 0)
176         return false;
177
178     TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
179     
180     it.visitAggregate = ParseAggregate;
181     it.visitConstantUnion = ParseConstantUnion;
182
183     root->traverse(&it);
184     if (it.error)
185         return true;
186     else
187         return false;
188 }
189
190 } // end namespace glslang