1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Check whether variables fit within packing limits according to the packing rules from the GLSL ES
7*8975f5c5SAndroid Build Coastguard Worker // 1.00.17 spec, Appendix A, section 7.
8*8975f5c5SAndroid Build Coastguard Worker
9*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
10*8975f5c5SAndroid Build Coastguard Worker
11*8975f5c5SAndroid Build Coastguard Worker #include "angle_gl.h"
12*8975f5c5SAndroid Build Coastguard Worker
13*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
14*8975f5c5SAndroid Build Coastguard Worker #include "compiler/translator/VariablePacker.h"
15*8975f5c5SAndroid Build Coastguard Worker
16*8975f5c5SAndroid Build Coastguard Worker namespace sh
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker
19*8975f5c5SAndroid Build Coastguard Worker namespace
20*8975f5c5SAndroid Build Coastguard Worker {
21*8975f5c5SAndroid Build Coastguard Worker
22*8975f5c5SAndroid Build Coastguard Worker // Expand the variable so that struct variables are split into their individual fields.
23*8975f5c5SAndroid Build Coastguard Worker // Will not set the mappedName or staticUse fields on the expanded variables.
24*8975f5c5SAndroid Build Coastguard Worker void ExpandVariable(const ShaderVariable &variable,
25*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
26*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *expanded);
27*8975f5c5SAndroid Build Coastguard Worker
ExpandStructVariable(const ShaderVariable & variable,const std::string & name,std::vector<ShaderVariable> * expanded)28*8975f5c5SAndroid Build Coastguard Worker void ExpandStructVariable(const ShaderVariable &variable,
29*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
30*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *expanded)
31*8975f5c5SAndroid Build Coastguard Worker {
32*8975f5c5SAndroid Build Coastguard Worker ASSERT(variable.isStruct());
33*8975f5c5SAndroid Build Coastguard Worker
34*8975f5c5SAndroid Build Coastguard Worker const std::vector<ShaderVariable> &fields = variable.fields;
35*8975f5c5SAndroid Build Coastguard Worker
36*8975f5c5SAndroid Build Coastguard Worker for (size_t fieldIndex = 0; fieldIndex < fields.size(); fieldIndex++)
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker const ShaderVariable &field = fields[fieldIndex];
39*8975f5c5SAndroid Build Coastguard Worker ExpandVariable(field, name + "." + field.name, expanded);
40*8975f5c5SAndroid Build Coastguard Worker }
41*8975f5c5SAndroid Build Coastguard Worker }
42*8975f5c5SAndroid Build Coastguard Worker
ExpandStructArrayVariable(const ShaderVariable & variable,unsigned int arrayNestingIndex,const std::string & name,std::vector<ShaderVariable> * expanded)43*8975f5c5SAndroid Build Coastguard Worker void ExpandStructArrayVariable(const ShaderVariable &variable,
44*8975f5c5SAndroid Build Coastguard Worker unsigned int arrayNestingIndex,
45*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
46*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *expanded)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker // Nested arrays are processed starting from outermost (arrayNestingIndex 0u) and ending at the
49*8975f5c5SAndroid Build Coastguard Worker // innermost.
50*8975f5c5SAndroid Build Coastguard Worker const unsigned int currentArraySize = variable.getNestedArraySize(arrayNestingIndex);
51*8975f5c5SAndroid Build Coastguard Worker for (unsigned int arrayElement = 0u; arrayElement < currentArraySize; ++arrayElement)
52*8975f5c5SAndroid Build Coastguard Worker {
53*8975f5c5SAndroid Build Coastguard Worker const std::string elementName = name + ArrayString(arrayElement);
54*8975f5c5SAndroid Build Coastguard Worker if (arrayNestingIndex + 1u < variable.arraySizes.size())
55*8975f5c5SAndroid Build Coastguard Worker {
56*8975f5c5SAndroid Build Coastguard Worker ExpandStructArrayVariable(variable, arrayNestingIndex + 1u, elementName, expanded);
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker else
59*8975f5c5SAndroid Build Coastguard Worker {
60*8975f5c5SAndroid Build Coastguard Worker ExpandStructVariable(variable, elementName, expanded);
61*8975f5c5SAndroid Build Coastguard Worker }
62*8975f5c5SAndroid Build Coastguard Worker }
63*8975f5c5SAndroid Build Coastguard Worker }
64*8975f5c5SAndroid Build Coastguard Worker
ExpandVariable(const ShaderVariable & variable,const std::string & name,std::vector<ShaderVariable> * expanded)65*8975f5c5SAndroid Build Coastguard Worker void ExpandVariable(const ShaderVariable &variable,
66*8975f5c5SAndroid Build Coastguard Worker const std::string &name,
67*8975f5c5SAndroid Build Coastguard Worker std::vector<ShaderVariable> *expanded)
68*8975f5c5SAndroid Build Coastguard Worker {
69*8975f5c5SAndroid Build Coastguard Worker if (variable.isStruct())
70*8975f5c5SAndroid Build Coastguard Worker {
71*8975f5c5SAndroid Build Coastguard Worker if (variable.isArray())
72*8975f5c5SAndroid Build Coastguard Worker {
73*8975f5c5SAndroid Build Coastguard Worker ExpandStructArrayVariable(variable, 0u, name, expanded);
74*8975f5c5SAndroid Build Coastguard Worker }
75*8975f5c5SAndroid Build Coastguard Worker else
76*8975f5c5SAndroid Build Coastguard Worker {
77*8975f5c5SAndroid Build Coastguard Worker ExpandStructVariable(variable, name, expanded);
78*8975f5c5SAndroid Build Coastguard Worker }
79*8975f5c5SAndroid Build Coastguard Worker }
80*8975f5c5SAndroid Build Coastguard Worker else
81*8975f5c5SAndroid Build Coastguard Worker {
82*8975f5c5SAndroid Build Coastguard Worker ShaderVariable expandedVar = variable;
83*8975f5c5SAndroid Build Coastguard Worker expandedVar.name = name;
84*8975f5c5SAndroid Build Coastguard Worker
85*8975f5c5SAndroid Build Coastguard Worker expanded->push_back(expandedVar);
86*8975f5c5SAndroid Build Coastguard Worker }
87*8975f5c5SAndroid Build Coastguard Worker }
88*8975f5c5SAndroid Build Coastguard Worker
GetVariablePackingRows(const ShaderVariable & variable)89*8975f5c5SAndroid Build Coastguard Worker int GetVariablePackingRows(const ShaderVariable &variable)
90*8975f5c5SAndroid Build Coastguard Worker {
91*8975f5c5SAndroid Build Coastguard Worker return GetTypePackingRows(variable.type) * variable.getArraySizeProduct();
92*8975f5c5SAndroid Build Coastguard Worker }
93*8975f5c5SAndroid Build Coastguard Worker
94*8975f5c5SAndroid Build Coastguard Worker class VariablePacker
95*8975f5c5SAndroid Build Coastguard Worker {
96*8975f5c5SAndroid Build Coastguard Worker public:
97*8975f5c5SAndroid Build Coastguard Worker bool checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,
98*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *variables);
99*8975f5c5SAndroid Build Coastguard Worker
100*8975f5c5SAndroid Build Coastguard Worker private:
101*8975f5c5SAndroid Build Coastguard Worker static const int kNumColumns = 4;
102*8975f5c5SAndroid Build Coastguard Worker static const unsigned kColumnMask = (1 << kNumColumns) - 1;
103*8975f5c5SAndroid Build Coastguard Worker
104*8975f5c5SAndroid Build Coastguard Worker unsigned makeColumnFlags(int column, int numComponentsPerRow);
105*8975f5c5SAndroid Build Coastguard Worker void fillColumns(int topRow, int numRows, int column, int numComponentsPerRow);
106*8975f5c5SAndroid Build Coastguard Worker bool searchColumn(int column, int numRows, int *destRow, int *destSize);
107*8975f5c5SAndroid Build Coastguard Worker
108*8975f5c5SAndroid Build Coastguard Worker int topNonFullRow_;
109*8975f5c5SAndroid Build Coastguard Worker int bottomNonFullRow_;
110*8975f5c5SAndroid Build Coastguard Worker int maxRows_;
111*8975f5c5SAndroid Build Coastguard Worker std::vector<unsigned> rows_;
112*8975f5c5SAndroid Build Coastguard Worker };
113*8975f5c5SAndroid Build Coastguard Worker
114*8975f5c5SAndroid Build Coastguard Worker struct TVariableInfoComparer
115*8975f5c5SAndroid Build Coastguard Worker {
operator ()sh::__anone7e802c40111::TVariableInfoComparer116*8975f5c5SAndroid Build Coastguard Worker bool operator()(const sh::ShaderVariable &lhs, const sh::ShaderVariable &rhs) const
117*8975f5c5SAndroid Build Coastguard Worker {
118*8975f5c5SAndroid Build Coastguard Worker int lhsSortOrder = gl::VariableSortOrder(lhs.type);
119*8975f5c5SAndroid Build Coastguard Worker int rhsSortOrder = gl::VariableSortOrder(rhs.type);
120*8975f5c5SAndroid Build Coastguard Worker if (lhsSortOrder != rhsSortOrder)
121*8975f5c5SAndroid Build Coastguard Worker {
122*8975f5c5SAndroid Build Coastguard Worker return lhsSortOrder < rhsSortOrder;
123*8975f5c5SAndroid Build Coastguard Worker }
124*8975f5c5SAndroid Build Coastguard Worker // Sort by largest first.
125*8975f5c5SAndroid Build Coastguard Worker return lhs.getArraySizeProduct() > rhs.getArraySizeProduct();
126*8975f5c5SAndroid Build Coastguard Worker }
127*8975f5c5SAndroid Build Coastguard Worker };
128*8975f5c5SAndroid Build Coastguard Worker
makeColumnFlags(int column,int numComponentsPerRow)129*8975f5c5SAndroid Build Coastguard Worker unsigned VariablePacker::makeColumnFlags(int column, int numComponentsPerRow)
130*8975f5c5SAndroid Build Coastguard Worker {
131*8975f5c5SAndroid Build Coastguard Worker return ((kColumnMask << (kNumColumns - numComponentsPerRow)) & kColumnMask) >> column;
132*8975f5c5SAndroid Build Coastguard Worker }
133*8975f5c5SAndroid Build Coastguard Worker
fillColumns(int topRow,int numRows,int column,int numComponentsPerRow)134*8975f5c5SAndroid Build Coastguard Worker void VariablePacker::fillColumns(int topRow, int numRows, int column, int numComponentsPerRow)
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker unsigned columnFlags = makeColumnFlags(column, numComponentsPerRow);
137*8975f5c5SAndroid Build Coastguard Worker for (int r = 0; r < numRows; ++r)
138*8975f5c5SAndroid Build Coastguard Worker {
139*8975f5c5SAndroid Build Coastguard Worker int row = topRow + r;
140*8975f5c5SAndroid Build Coastguard Worker ASSERT((rows_[row] & columnFlags) == 0);
141*8975f5c5SAndroid Build Coastguard Worker rows_[row] |= columnFlags;
142*8975f5c5SAndroid Build Coastguard Worker }
143*8975f5c5SAndroid Build Coastguard Worker }
144*8975f5c5SAndroid Build Coastguard Worker
searchColumn(int column,int numRows,int * destRow,int * destSize)145*8975f5c5SAndroid Build Coastguard Worker bool VariablePacker::searchColumn(int column, int numRows, int *destRow, int *destSize)
146*8975f5c5SAndroid Build Coastguard Worker {
147*8975f5c5SAndroid Build Coastguard Worker ASSERT(destRow);
148*8975f5c5SAndroid Build Coastguard Worker
149*8975f5c5SAndroid Build Coastguard Worker for (; topNonFullRow_ < maxRows_ && rows_[topNonFullRow_] == kColumnMask; ++topNonFullRow_)
150*8975f5c5SAndroid Build Coastguard Worker {
151*8975f5c5SAndroid Build Coastguard Worker }
152*8975f5c5SAndroid Build Coastguard Worker
153*8975f5c5SAndroid Build Coastguard Worker for (; bottomNonFullRow_ >= 0 && rows_[bottomNonFullRow_] == kColumnMask; --bottomNonFullRow_)
154*8975f5c5SAndroid Build Coastguard Worker {
155*8975f5c5SAndroid Build Coastguard Worker }
156*8975f5c5SAndroid Build Coastguard Worker
157*8975f5c5SAndroid Build Coastguard Worker if (bottomNonFullRow_ - topNonFullRow_ + 1 < numRows)
158*8975f5c5SAndroid Build Coastguard Worker {
159*8975f5c5SAndroid Build Coastguard Worker return false;
160*8975f5c5SAndroid Build Coastguard Worker }
161*8975f5c5SAndroid Build Coastguard Worker
162*8975f5c5SAndroid Build Coastguard Worker unsigned columnFlags = makeColumnFlags(column, 1);
163*8975f5c5SAndroid Build Coastguard Worker int topGoodRow = 0;
164*8975f5c5SAndroid Build Coastguard Worker int smallestGoodTop = -1;
165*8975f5c5SAndroid Build Coastguard Worker int smallestGoodSize = maxRows_ + 1;
166*8975f5c5SAndroid Build Coastguard Worker int bottomRow = bottomNonFullRow_ + 1;
167*8975f5c5SAndroid Build Coastguard Worker bool found = false;
168*8975f5c5SAndroid Build Coastguard Worker for (int row = topNonFullRow_; row <= bottomRow; ++row)
169*8975f5c5SAndroid Build Coastguard Worker {
170*8975f5c5SAndroid Build Coastguard Worker bool rowEmpty = row < bottomRow ? ((rows_[row] & columnFlags) == 0) : false;
171*8975f5c5SAndroid Build Coastguard Worker if (rowEmpty)
172*8975f5c5SAndroid Build Coastguard Worker {
173*8975f5c5SAndroid Build Coastguard Worker if (!found)
174*8975f5c5SAndroid Build Coastguard Worker {
175*8975f5c5SAndroid Build Coastguard Worker topGoodRow = row;
176*8975f5c5SAndroid Build Coastguard Worker found = true;
177*8975f5c5SAndroid Build Coastguard Worker }
178*8975f5c5SAndroid Build Coastguard Worker }
179*8975f5c5SAndroid Build Coastguard Worker else
180*8975f5c5SAndroid Build Coastguard Worker {
181*8975f5c5SAndroid Build Coastguard Worker if (found)
182*8975f5c5SAndroid Build Coastguard Worker {
183*8975f5c5SAndroid Build Coastguard Worker int size = row - topGoodRow;
184*8975f5c5SAndroid Build Coastguard Worker if (size >= numRows && size < smallestGoodSize)
185*8975f5c5SAndroid Build Coastguard Worker {
186*8975f5c5SAndroid Build Coastguard Worker smallestGoodSize = size;
187*8975f5c5SAndroid Build Coastguard Worker smallestGoodTop = topGoodRow;
188*8975f5c5SAndroid Build Coastguard Worker }
189*8975f5c5SAndroid Build Coastguard Worker }
190*8975f5c5SAndroid Build Coastguard Worker found = false;
191*8975f5c5SAndroid Build Coastguard Worker }
192*8975f5c5SAndroid Build Coastguard Worker }
193*8975f5c5SAndroid Build Coastguard Worker if (smallestGoodTop < 0)
194*8975f5c5SAndroid Build Coastguard Worker {
195*8975f5c5SAndroid Build Coastguard Worker return false;
196*8975f5c5SAndroid Build Coastguard Worker }
197*8975f5c5SAndroid Build Coastguard Worker
198*8975f5c5SAndroid Build Coastguard Worker *destRow = smallestGoodTop;
199*8975f5c5SAndroid Build Coastguard Worker if (destSize)
200*8975f5c5SAndroid Build Coastguard Worker {
201*8975f5c5SAndroid Build Coastguard Worker *destSize = smallestGoodSize;
202*8975f5c5SAndroid Build Coastguard Worker }
203*8975f5c5SAndroid Build Coastguard Worker return true;
204*8975f5c5SAndroid Build Coastguard Worker }
205*8975f5c5SAndroid Build Coastguard Worker
checkExpandedVariablesWithinPackingLimits(unsigned int maxVectors,std::vector<sh::ShaderVariable> * variables)206*8975f5c5SAndroid Build Coastguard Worker bool VariablePacker::checkExpandedVariablesWithinPackingLimits(
207*8975f5c5SAndroid Build Coastguard Worker unsigned int maxVectors,
208*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> *variables)
209*8975f5c5SAndroid Build Coastguard Worker {
210*8975f5c5SAndroid Build Coastguard Worker ASSERT(maxVectors > 0);
211*8975f5c5SAndroid Build Coastguard Worker maxRows_ = maxVectors;
212*8975f5c5SAndroid Build Coastguard Worker topNonFullRow_ = 0;
213*8975f5c5SAndroid Build Coastguard Worker bottomNonFullRow_ = maxRows_ - 1;
214*8975f5c5SAndroid Build Coastguard Worker
215*8975f5c5SAndroid Build Coastguard Worker // Check whether each variable fits in the available vectors.
216*8975f5c5SAndroid Build Coastguard Worker for (const sh::ShaderVariable &variable : *variables)
217*8975f5c5SAndroid Build Coastguard Worker {
218*8975f5c5SAndroid Build Coastguard Worker // Structs should have been expanded before reaching here.
219*8975f5c5SAndroid Build Coastguard Worker ASSERT(!variable.isStruct());
220*8975f5c5SAndroid Build Coastguard Worker if (variable.getArraySizeProduct() > maxVectors / GetTypePackingRows(variable.type))
221*8975f5c5SAndroid Build Coastguard Worker {
222*8975f5c5SAndroid Build Coastguard Worker return false;
223*8975f5c5SAndroid Build Coastguard Worker }
224*8975f5c5SAndroid Build Coastguard Worker }
225*8975f5c5SAndroid Build Coastguard Worker
226*8975f5c5SAndroid Build Coastguard Worker // As per GLSL 1.017 Appendix A, Section 7 variables are packed in specific
227*8975f5c5SAndroid Build Coastguard Worker // order by type, then by size of array, largest first.
228*8975f5c5SAndroid Build Coastguard Worker std::sort(variables->begin(), variables->end(), TVariableInfoComparer());
229*8975f5c5SAndroid Build Coastguard Worker rows_.clear();
230*8975f5c5SAndroid Build Coastguard Worker rows_.resize(maxVectors, 0);
231*8975f5c5SAndroid Build Coastguard Worker
232*8975f5c5SAndroid Build Coastguard Worker // Packs the 4 column variables.
233*8975f5c5SAndroid Build Coastguard Worker size_t ii = 0;
234*8975f5c5SAndroid Build Coastguard Worker for (; ii < variables->size(); ++ii)
235*8975f5c5SAndroid Build Coastguard Worker {
236*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable &variable = (*variables)[ii];
237*8975f5c5SAndroid Build Coastguard Worker if (GetTypePackingComponentsPerRow(variable.type) != 4)
238*8975f5c5SAndroid Build Coastguard Worker {
239*8975f5c5SAndroid Build Coastguard Worker break;
240*8975f5c5SAndroid Build Coastguard Worker }
241*8975f5c5SAndroid Build Coastguard Worker topNonFullRow_ += GetVariablePackingRows(variable);
242*8975f5c5SAndroid Build Coastguard Worker if (topNonFullRow_ > maxRows_)
243*8975f5c5SAndroid Build Coastguard Worker {
244*8975f5c5SAndroid Build Coastguard Worker return false;
245*8975f5c5SAndroid Build Coastguard Worker }
246*8975f5c5SAndroid Build Coastguard Worker }
247*8975f5c5SAndroid Build Coastguard Worker
248*8975f5c5SAndroid Build Coastguard Worker // Packs the 3 column variables.
249*8975f5c5SAndroid Build Coastguard Worker int num3ColumnRows = 0;
250*8975f5c5SAndroid Build Coastguard Worker for (; ii < variables->size(); ++ii)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable &variable = (*variables)[ii];
253*8975f5c5SAndroid Build Coastguard Worker if (GetTypePackingComponentsPerRow(variable.type) != 3)
254*8975f5c5SAndroid Build Coastguard Worker {
255*8975f5c5SAndroid Build Coastguard Worker break;
256*8975f5c5SAndroid Build Coastguard Worker }
257*8975f5c5SAndroid Build Coastguard Worker
258*8975f5c5SAndroid Build Coastguard Worker num3ColumnRows += GetVariablePackingRows(variable);
259*8975f5c5SAndroid Build Coastguard Worker if (topNonFullRow_ + num3ColumnRows > maxRows_)
260*8975f5c5SAndroid Build Coastguard Worker {
261*8975f5c5SAndroid Build Coastguard Worker return false;
262*8975f5c5SAndroid Build Coastguard Worker }
263*8975f5c5SAndroid Build Coastguard Worker }
264*8975f5c5SAndroid Build Coastguard Worker
265*8975f5c5SAndroid Build Coastguard Worker fillColumns(topNonFullRow_, num3ColumnRows, 0, 3);
266*8975f5c5SAndroid Build Coastguard Worker
267*8975f5c5SAndroid Build Coastguard Worker // Packs the 2 column variables.
268*8975f5c5SAndroid Build Coastguard Worker int top2ColumnRow = topNonFullRow_ + num3ColumnRows;
269*8975f5c5SAndroid Build Coastguard Worker int twoColumnRowsAvailable = maxRows_ - top2ColumnRow;
270*8975f5c5SAndroid Build Coastguard Worker int rowsAvailableInColumns01 = twoColumnRowsAvailable;
271*8975f5c5SAndroid Build Coastguard Worker int rowsAvailableInColumns23 = twoColumnRowsAvailable;
272*8975f5c5SAndroid Build Coastguard Worker for (; ii < variables->size(); ++ii)
273*8975f5c5SAndroid Build Coastguard Worker {
274*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable &variable = (*variables)[ii];
275*8975f5c5SAndroid Build Coastguard Worker if (GetTypePackingComponentsPerRow(variable.type) != 2)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker break;
278*8975f5c5SAndroid Build Coastguard Worker }
279*8975f5c5SAndroid Build Coastguard Worker int numRows = GetVariablePackingRows(variable);
280*8975f5c5SAndroid Build Coastguard Worker if (numRows <= rowsAvailableInColumns01)
281*8975f5c5SAndroid Build Coastguard Worker {
282*8975f5c5SAndroid Build Coastguard Worker rowsAvailableInColumns01 -= numRows;
283*8975f5c5SAndroid Build Coastguard Worker }
284*8975f5c5SAndroid Build Coastguard Worker else if (numRows <= rowsAvailableInColumns23)
285*8975f5c5SAndroid Build Coastguard Worker {
286*8975f5c5SAndroid Build Coastguard Worker rowsAvailableInColumns23 -= numRows;
287*8975f5c5SAndroid Build Coastguard Worker }
288*8975f5c5SAndroid Build Coastguard Worker else
289*8975f5c5SAndroid Build Coastguard Worker {
290*8975f5c5SAndroid Build Coastguard Worker return false;
291*8975f5c5SAndroid Build Coastguard Worker }
292*8975f5c5SAndroid Build Coastguard Worker }
293*8975f5c5SAndroid Build Coastguard Worker
294*8975f5c5SAndroid Build Coastguard Worker int numRowsUsedInColumns01 = twoColumnRowsAvailable - rowsAvailableInColumns01;
295*8975f5c5SAndroid Build Coastguard Worker int numRowsUsedInColumns23 = twoColumnRowsAvailable - rowsAvailableInColumns23;
296*8975f5c5SAndroid Build Coastguard Worker fillColumns(top2ColumnRow, numRowsUsedInColumns01, 0, 2);
297*8975f5c5SAndroid Build Coastguard Worker fillColumns(maxRows_ - numRowsUsedInColumns23, numRowsUsedInColumns23, 2, 2);
298*8975f5c5SAndroid Build Coastguard Worker
299*8975f5c5SAndroid Build Coastguard Worker // Packs the 1 column variables.
300*8975f5c5SAndroid Build Coastguard Worker for (; ii < variables->size(); ++ii)
301*8975f5c5SAndroid Build Coastguard Worker {
302*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable &variable = (*variables)[ii];
303*8975f5c5SAndroid Build Coastguard Worker ASSERT(1 == GetTypePackingComponentsPerRow(variable.type));
304*8975f5c5SAndroid Build Coastguard Worker int numRows = GetVariablePackingRows(variable);
305*8975f5c5SAndroid Build Coastguard Worker int smallestColumn = -1;
306*8975f5c5SAndroid Build Coastguard Worker int smallestSize = maxRows_ + 1;
307*8975f5c5SAndroid Build Coastguard Worker int topRow = -1;
308*8975f5c5SAndroid Build Coastguard Worker for (int column = 0; column < kNumColumns; ++column)
309*8975f5c5SAndroid Build Coastguard Worker {
310*8975f5c5SAndroid Build Coastguard Worker int row = 0;
311*8975f5c5SAndroid Build Coastguard Worker int size = 0;
312*8975f5c5SAndroid Build Coastguard Worker if (searchColumn(column, numRows, &row, &size))
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker if (size < smallestSize)
315*8975f5c5SAndroid Build Coastguard Worker {
316*8975f5c5SAndroid Build Coastguard Worker smallestSize = size;
317*8975f5c5SAndroid Build Coastguard Worker smallestColumn = column;
318*8975f5c5SAndroid Build Coastguard Worker topRow = row;
319*8975f5c5SAndroid Build Coastguard Worker }
320*8975f5c5SAndroid Build Coastguard Worker }
321*8975f5c5SAndroid Build Coastguard Worker }
322*8975f5c5SAndroid Build Coastguard Worker
323*8975f5c5SAndroid Build Coastguard Worker if (smallestColumn < 0)
324*8975f5c5SAndroid Build Coastguard Worker {
325*8975f5c5SAndroid Build Coastguard Worker return false;
326*8975f5c5SAndroid Build Coastguard Worker }
327*8975f5c5SAndroid Build Coastguard Worker
328*8975f5c5SAndroid Build Coastguard Worker fillColumns(topRow, numRows, smallestColumn, 1);
329*8975f5c5SAndroid Build Coastguard Worker }
330*8975f5c5SAndroid Build Coastguard Worker
331*8975f5c5SAndroid Build Coastguard Worker ASSERT(variables->size() == ii);
332*8975f5c5SAndroid Build Coastguard Worker
333*8975f5c5SAndroid Build Coastguard Worker return true;
334*8975f5c5SAndroid Build Coastguard Worker }
335*8975f5c5SAndroid Build Coastguard Worker
336*8975f5c5SAndroid Build Coastguard Worker } // anonymous namespace
337*8975f5c5SAndroid Build Coastguard Worker
GetTypePackingComponentsPerRow(sh::GLenum type)338*8975f5c5SAndroid Build Coastguard Worker int GetTypePackingComponentsPerRow(sh::GLenum type)
339*8975f5c5SAndroid Build Coastguard Worker {
340*8975f5c5SAndroid Build Coastguard Worker switch (type)
341*8975f5c5SAndroid Build Coastguard Worker {
342*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4:
343*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2:
344*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2x4:
345*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3x4:
346*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4x2:
347*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4x3:
348*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_VEC4:
349*8975f5c5SAndroid Build Coastguard Worker case GL_INT_VEC4:
350*8975f5c5SAndroid Build Coastguard Worker case GL_BOOL_VEC4:
351*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_VEC4:
352*8975f5c5SAndroid Build Coastguard Worker return 4;
353*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3:
354*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2x3:
355*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3x2:
356*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_VEC3:
357*8975f5c5SAndroid Build Coastguard Worker case GL_INT_VEC3:
358*8975f5c5SAndroid Build Coastguard Worker case GL_BOOL_VEC3:
359*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_VEC3:
360*8975f5c5SAndroid Build Coastguard Worker return 3;
361*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_VEC2:
362*8975f5c5SAndroid Build Coastguard Worker case GL_INT_VEC2:
363*8975f5c5SAndroid Build Coastguard Worker case GL_BOOL_VEC2:
364*8975f5c5SAndroid Build Coastguard Worker case GL_UNSIGNED_INT_VEC2:
365*8975f5c5SAndroid Build Coastguard Worker return 2;
366*8975f5c5SAndroid Build Coastguard Worker default:
367*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::VariableComponentCount(type) == 1);
368*8975f5c5SAndroid Build Coastguard Worker return 1;
369*8975f5c5SAndroid Build Coastguard Worker }
370*8975f5c5SAndroid Build Coastguard Worker }
371*8975f5c5SAndroid Build Coastguard Worker
GetTypePackingRows(sh::GLenum type)372*8975f5c5SAndroid Build Coastguard Worker int GetTypePackingRows(sh::GLenum type)
373*8975f5c5SAndroid Build Coastguard Worker {
374*8975f5c5SAndroid Build Coastguard Worker switch (type)
375*8975f5c5SAndroid Build Coastguard Worker {
376*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4:
377*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2x4:
378*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3x4:
379*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4x3:
380*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT4x2:
381*8975f5c5SAndroid Build Coastguard Worker return 4;
382*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3:
383*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2x3:
384*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT3x2:
385*8975f5c5SAndroid Build Coastguard Worker return 3;
386*8975f5c5SAndroid Build Coastguard Worker case GL_FLOAT_MAT2:
387*8975f5c5SAndroid Build Coastguard Worker return 2;
388*8975f5c5SAndroid Build Coastguard Worker default:
389*8975f5c5SAndroid Build Coastguard Worker ASSERT(gl::VariableRowCount(type) == 1);
390*8975f5c5SAndroid Build Coastguard Worker return 1;
391*8975f5c5SAndroid Build Coastguard Worker }
392*8975f5c5SAndroid Build Coastguard Worker }
393*8975f5c5SAndroid Build Coastguard Worker
CheckVariablesInPackingLimits(unsigned int maxVectors,const std::vector<ShaderVariable> & variables)394*8975f5c5SAndroid Build Coastguard Worker bool CheckVariablesInPackingLimits(unsigned int maxVectors,
395*8975f5c5SAndroid Build Coastguard Worker const std::vector<ShaderVariable> &variables)
396*8975f5c5SAndroid Build Coastguard Worker {
397*8975f5c5SAndroid Build Coastguard Worker VariablePacker packer;
398*8975f5c5SAndroid Build Coastguard Worker std::vector<sh::ShaderVariable> expandedVariables;
399*8975f5c5SAndroid Build Coastguard Worker for (const ShaderVariable &variable : variables)
400*8975f5c5SAndroid Build Coastguard Worker {
401*8975f5c5SAndroid Build Coastguard Worker ExpandVariable(variable, variable.name, &expandedVariables);
402*8975f5c5SAndroid Build Coastguard Worker }
403*8975f5c5SAndroid Build Coastguard Worker return packer.checkExpandedVariablesWithinPackingLimits(maxVectors, &expandedVariables);
404*8975f5c5SAndroid Build Coastguard Worker }
405*8975f5c5SAndroid Build Coastguard Worker
406*8975f5c5SAndroid Build Coastguard Worker bool CheckVariablesInPackingLimits(unsigned int maxVectors,
407*8975f5c5SAndroid Build Coastguard Worker const std::vector<ShaderVariable> &variables);
408*8975f5c5SAndroid Build Coastguard Worker
409*8975f5c5SAndroid Build Coastguard Worker } // namespace sh
410