Coverage Report

Created: 2025-06-13 06:48

/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