/src/shaderc/third_party/glslang/glslang/MachineIndependent/parseConst.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | // Traverse 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) |
47 | 319k | : unionArray(cUnion), type(t), |
48 | 319k | constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false), |
49 | 319k | matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; } |
50 | | |
51 | | virtual void visitConstantUnion(TIntermConstantUnion* node); |
52 | | virtual bool visitAggregate(TVisit, TIntermAggregate* node); |
53 | | |
54 | | int index; |
55 | | TConstUnionArray unionArray; |
56 | | TOperator tOp; |
57 | | const TType& type; |
58 | | TOperator constructorType; |
59 | | bool singleConstantParam; |
60 | | bool error; |
61 | | int size; // size of the constructor ( 4 for vec4) |
62 | | bool isMatrix; |
63 | | int matrixCols; |
64 | | int matrixRows; |
65 | | |
66 | | protected: |
67 | | TConstTraverser(TConstTraverser&); |
68 | | TConstTraverser& operator=(TConstTraverser&); |
69 | | }; |
70 | | |
71 | | bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) |
72 | 319k | { |
73 | 319k | if (! node->isConstructor() && node->getOp() != EOpComma) { |
74 | 0 | error = true; |
75 | |
|
76 | 0 | return false; |
77 | 0 | } |
78 | | |
79 | 319k | bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion(); |
80 | 319k | if (flag) { |
81 | 96.5k | singleConstantParam = true; |
82 | 96.5k | constructorType = node->getOp(); |
83 | 96.5k | size = node->getType().computeNumComponents(); |
84 | | |
85 | 96.5k | if (node->getType().isMatrix()) { |
86 | 945 | isMatrix = true; |
87 | 945 | matrixCols = node->getType().getMatrixCols(); |
88 | 945 | matrixRows = node->getType().getMatrixRows(); |
89 | 945 | } |
90 | 96.5k | } |
91 | | |
92 | 319k | for (TIntermSequence::iterator p = node->getSequence().begin(); |
93 | 1.08M | p != node->getSequence().end(); p++) { |
94 | | |
95 | 766k | if (node->getOp() == EOpComma) |
96 | 0 | index = 0; |
97 | | |
98 | 766k | (*p)->traverse(this); |
99 | 766k | } |
100 | 319k | if (flag) |
101 | 96.5k | { |
102 | 96.5k | singleConstantParam = false; |
103 | 96.5k | constructorType = EOpNull; |
104 | 96.5k | size = 0; |
105 | 96.5k | isMatrix = false; |
106 | 96.5k | matrixCols = 0; |
107 | 96.5k | matrixRows = 0; |
108 | 96.5k | } |
109 | | |
110 | 319k | return false; |
111 | 319k | } |
112 | | |
113 | | void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node) |
114 | 766k | { |
115 | 766k | TConstUnionArray leftUnionArray(unionArray); |
116 | 766k | int instanceSize = type.computeNumComponents(); |
117 | | |
118 | 766k | if (index >= instanceSize) |
119 | 6 | return; |
120 | | |
121 | 766k | if (! singleConstantParam) { |
122 | 670k | int rightUnionSize = node->getType().computeNumComponents(); |
123 | | |
124 | 670k | const TConstUnionArray& rightUnionArray = node->getConstArray(); |
125 | 1.40M | for (int i = 0; i < rightUnionSize; i++) { |
126 | 731k | if (index >= instanceSize) |
127 | 33 | return; |
128 | 731k | leftUnionArray[index] = rightUnionArray[i]; |
129 | | |
130 | 731k | index++; |
131 | 731k | } |
132 | 670k | } else { |
133 | 96.5k | int endIndex = index + size; |
134 | 96.5k | const TConstUnionArray& rightUnionArray = node->getConstArray(); |
135 | 96.5k | if (! isMatrix) { |
136 | 95.6k | int count = 0; |
137 | 95.6k | int nodeComps = node->getType().computeNumComponents(); |
138 | 389k | for (int i = index; i < endIndex; i++) { |
139 | 293k | if (i >= instanceSize) |
140 | 0 | return; |
141 | | |
142 | 293k | leftUnionArray[i] = rightUnionArray[count]; |
143 | | |
144 | 293k | (index)++; |
145 | | |
146 | 293k | if (nodeComps > 1) |
147 | 1.33k | count++; |
148 | 293k | } |
149 | 95.6k | } else { |
150 | | // constructing a matrix, but from what? |
151 | 945 | if (node->isMatrix()) { |
152 | | // Matrix from a matrix; this has the outer matrix, node is the argument matrix. |
153 | | // Traverse the outer, potentially bigger matrix, fill in missing pieces with the |
154 | | // identity matrix. |
155 | 1.22k | for (int c = 0; c < matrixCols; ++c) { |
156 | 3.49k | for (int r = 0; r < matrixRows; ++r) { |
157 | 2.59k | int targetOffset = index + c * matrixRows + r; |
158 | 2.59k | if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) { |
159 | 1.76k | int srcOffset = c * node->getType().getMatrixRows() + r; |
160 | 1.76k | leftUnionArray[targetOffset] = rightUnionArray[srcOffset]; |
161 | 1.76k | } else if (r == c) |
162 | 166 | leftUnionArray[targetOffset].setDConst(1.0); |
163 | 664 | else |
164 | 664 | leftUnionArray[targetOffset].setDConst(0.0); |
165 | 2.59k | } |
166 | 900 | } |
167 | 619 | } else { |
168 | | // matrix from vector or scalar |
169 | 619 | int nodeComps = node->getType().computeNumComponents(); |
170 | 619 | if (nodeComps == 1) { |
171 | 1.96k | for (int c = 0; c < matrixCols; ++c) { |
172 | 7.02k | for (int r = 0; r < matrixRows; ++r) { |
173 | 5.53k | if (r == c) |
174 | 1.48k | leftUnionArray[index] = rightUnionArray[0]; |
175 | 4.05k | else |
176 | 4.05k | leftUnionArray[index].setDConst(0.0); |
177 | 5.53k | index++; |
178 | 5.53k | } |
179 | 1.49k | } |
180 | 478 | } else { |
181 | 141 | int count = 0; |
182 | 705 | for (int i = index; i < endIndex; i++) { |
183 | 564 | if (i >= instanceSize) |
184 | 0 | return; |
185 | | |
186 | | // construct the matrix in column-major order, from |
187 | | // the components provided, in order |
188 | 564 | leftUnionArray[i] = rightUnionArray[count]; |
189 | | |
190 | 564 | index++; |
191 | 564 | count++; |
192 | 564 | } |
193 | 141 | } |
194 | 619 | } |
195 | 945 | } |
196 | 96.5k | } |
197 | 766k | } |
198 | | |
199 | | bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArray, TOperator constructorType, const TType& t, bool singleConstantParam) |
200 | 319k | { |
201 | 319k | if (root == nullptr) |
202 | 0 | return false; |
203 | | |
204 | 319k | TConstTraverser it(unionArray, singleConstantParam, constructorType, t); |
205 | | |
206 | 319k | root->traverse(&it); |
207 | 319k | if (it.error) |
208 | 0 | return true; |
209 | 319k | else |
210 | 319k | return false; |
211 | 319k | } |
212 | | |
213 | | } // end namespace glslang |