xref: /aosp_15_r20/external/angle/src/compiler/translator/ShaderVars.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2014 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 // ShaderVars.cpp:
7*8975f5c5SAndroid Build Coastguard Worker //  Methods for GL variable types (varyings, uniforms, etc)
8*8975f5c5SAndroid Build Coastguard Worker //
9*8975f5c5SAndroid Build Coastguard Worker 
10*8975f5c5SAndroid Build Coastguard Worker #include <GLSLANG/ShaderLang.h>
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker #include "common/debug.h"
13*8975f5c5SAndroid Build Coastguard Worker #include "common/utilities.h"
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker namespace sh
16*8975f5c5SAndroid Build Coastguard Worker {
17*8975f5c5SAndroid Build Coastguard Worker 
18*8975f5c5SAndroid Build Coastguard Worker namespace
19*8975f5c5SAndroid Build Coastguard Worker {
20*8975f5c5SAndroid Build Coastguard Worker 
GetNonAuxiliaryInterpolationType(InterpolationType interpolation)21*8975f5c5SAndroid Build Coastguard Worker InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
22*8975f5c5SAndroid Build Coastguard Worker {
23*8975f5c5SAndroid Build Coastguard Worker     return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
24*8975f5c5SAndroid Build Coastguard Worker }
25*8975f5c5SAndroid Build Coastguard Worker }  // namespace
26*8975f5c5SAndroid Build Coastguard Worker // The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
27*8975f5c5SAndroid Build Coastguard Worker // on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
28*8975f5c5SAndroid Build Coastguard Worker // but auxiliary qualifier mismatch (centroid) does not.
InterpolationTypesMatch(InterpolationType a,InterpolationType b)29*8975f5c5SAndroid Build Coastguard Worker bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
30*8975f5c5SAndroid Build Coastguard Worker {
31*8975f5c5SAndroid Build Coastguard Worker     return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
32*8975f5c5SAndroid Build Coastguard Worker }
33*8975f5c5SAndroid Build Coastguard Worker 
ShaderVariable()34*8975f5c5SAndroid Build Coastguard Worker ShaderVariable::ShaderVariable() : ShaderVariable(GL_NONE) {}
35*8975f5c5SAndroid Build Coastguard Worker 
ShaderVariable(GLenum typeIn)36*8975f5c5SAndroid Build Coastguard Worker ShaderVariable::ShaderVariable(GLenum typeIn)
37*8975f5c5SAndroid Build Coastguard Worker     : type(typeIn),
38*8975f5c5SAndroid Build Coastguard Worker       precision(0),
39*8975f5c5SAndroid Build Coastguard Worker       staticUse(false),
40*8975f5c5SAndroid Build Coastguard Worker       active(false),
41*8975f5c5SAndroid Build Coastguard Worker       isRowMajorLayout(false),
42*8975f5c5SAndroid Build Coastguard Worker       location(-1),
43*8975f5c5SAndroid Build Coastguard Worker       hasImplicitLocation(false),
44*8975f5c5SAndroid Build Coastguard Worker       binding(-1),
45*8975f5c5SAndroid Build Coastguard Worker       imageUnitFormat(GL_NONE),
46*8975f5c5SAndroid Build Coastguard Worker       offset(-1),
47*8975f5c5SAndroid Build Coastguard Worker       rasterOrdered(false),
48*8975f5c5SAndroid Build Coastguard Worker       readonly(false),
49*8975f5c5SAndroid Build Coastguard Worker       writeonly(false),
50*8975f5c5SAndroid Build Coastguard Worker       isFragmentInOut(false),
51*8975f5c5SAndroid Build Coastguard Worker       index(-1),
52*8975f5c5SAndroid Build Coastguard Worker       yuv(false),
53*8975f5c5SAndroid Build Coastguard Worker       interpolation(INTERPOLATION_SMOOTH),
54*8975f5c5SAndroid Build Coastguard Worker       isInvariant(false),
55*8975f5c5SAndroid Build Coastguard Worker       isShaderIOBlock(false),
56*8975f5c5SAndroid Build Coastguard Worker       isPatch(false),
57*8975f5c5SAndroid Build Coastguard Worker       texelFetchStaticUse(false),
58*8975f5c5SAndroid Build Coastguard Worker       id(0),
59*8975f5c5SAndroid Build Coastguard Worker       flattenedOffsetInParentArrays(-1)
60*8975f5c5SAndroid Build Coastguard Worker {}
61*8975f5c5SAndroid Build Coastguard Worker 
ShaderVariable(GLenum typeIn,unsigned int arraySizeIn)62*8975f5c5SAndroid Build Coastguard Worker ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn) : ShaderVariable(typeIn)
63*8975f5c5SAndroid Build Coastguard Worker {
64*8975f5c5SAndroid Build Coastguard Worker     ASSERT(arraySizeIn != 0);
65*8975f5c5SAndroid Build Coastguard Worker     arraySizes.push_back(arraySizeIn);
66*8975f5c5SAndroid Build Coastguard Worker }
67*8975f5c5SAndroid Build Coastguard Worker 
~ShaderVariable()68*8975f5c5SAndroid Build Coastguard Worker ShaderVariable::~ShaderVariable() {}
69*8975f5c5SAndroid Build Coastguard Worker 
ShaderVariable(const ShaderVariable & other)70*8975f5c5SAndroid Build Coastguard Worker ShaderVariable::ShaderVariable(const ShaderVariable &other)
71*8975f5c5SAndroid Build Coastguard Worker     : type(other.type),
72*8975f5c5SAndroid Build Coastguard Worker       precision(other.precision),
73*8975f5c5SAndroid Build Coastguard Worker       name(other.name),
74*8975f5c5SAndroid Build Coastguard Worker       mappedName(other.mappedName),
75*8975f5c5SAndroid Build Coastguard Worker       arraySizes(other.arraySizes),
76*8975f5c5SAndroid Build Coastguard Worker       staticUse(other.staticUse),
77*8975f5c5SAndroid Build Coastguard Worker       active(other.active),
78*8975f5c5SAndroid Build Coastguard Worker       fields(other.fields),
79*8975f5c5SAndroid Build Coastguard Worker       structOrBlockName(other.structOrBlockName),
80*8975f5c5SAndroid Build Coastguard Worker       mappedStructOrBlockName(other.mappedStructOrBlockName),
81*8975f5c5SAndroid Build Coastguard Worker       isRowMajorLayout(other.isRowMajorLayout),
82*8975f5c5SAndroid Build Coastguard Worker       location(other.location),
83*8975f5c5SAndroid Build Coastguard Worker       hasImplicitLocation(other.hasImplicitLocation),
84*8975f5c5SAndroid Build Coastguard Worker       binding(other.binding),
85*8975f5c5SAndroid Build Coastguard Worker       imageUnitFormat(other.imageUnitFormat),
86*8975f5c5SAndroid Build Coastguard Worker       offset(other.offset),
87*8975f5c5SAndroid Build Coastguard Worker       rasterOrdered(other.rasterOrdered),
88*8975f5c5SAndroid Build Coastguard Worker       readonly(other.readonly),
89*8975f5c5SAndroid Build Coastguard Worker       writeonly(other.writeonly),
90*8975f5c5SAndroid Build Coastguard Worker       isFragmentInOut(other.isFragmentInOut),
91*8975f5c5SAndroid Build Coastguard Worker       index(other.index),
92*8975f5c5SAndroid Build Coastguard Worker       yuv(other.yuv),
93*8975f5c5SAndroid Build Coastguard Worker       interpolation(other.interpolation),
94*8975f5c5SAndroid Build Coastguard Worker       isInvariant(other.isInvariant),
95*8975f5c5SAndroid Build Coastguard Worker       isShaderIOBlock(other.isShaderIOBlock),
96*8975f5c5SAndroid Build Coastguard Worker       isPatch(other.isPatch),
97*8975f5c5SAndroid Build Coastguard Worker       texelFetchStaticUse(other.texelFetchStaticUse),
98*8975f5c5SAndroid Build Coastguard Worker       id(other.id),
99*8975f5c5SAndroid Build Coastguard Worker       flattenedOffsetInParentArrays(other.flattenedOffsetInParentArrays)
100*8975f5c5SAndroid Build Coastguard Worker {}
101*8975f5c5SAndroid Build Coastguard Worker 
operator =(const ShaderVariable & other)102*8975f5c5SAndroid Build Coastguard Worker ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
103*8975f5c5SAndroid Build Coastguard Worker {
104*8975f5c5SAndroid Build Coastguard Worker     type                          = other.type;
105*8975f5c5SAndroid Build Coastguard Worker     precision                     = other.precision;
106*8975f5c5SAndroid Build Coastguard Worker     name                          = other.name;
107*8975f5c5SAndroid Build Coastguard Worker     mappedName                    = other.mappedName;
108*8975f5c5SAndroid Build Coastguard Worker     arraySizes                    = other.arraySizes;
109*8975f5c5SAndroid Build Coastguard Worker     staticUse                     = other.staticUse;
110*8975f5c5SAndroid Build Coastguard Worker     active                        = other.active;
111*8975f5c5SAndroid Build Coastguard Worker     fields                        = other.fields;
112*8975f5c5SAndroid Build Coastguard Worker     structOrBlockName             = other.structOrBlockName;
113*8975f5c5SAndroid Build Coastguard Worker     mappedStructOrBlockName       = other.mappedStructOrBlockName;
114*8975f5c5SAndroid Build Coastguard Worker     isRowMajorLayout              = other.isRowMajorLayout;
115*8975f5c5SAndroid Build Coastguard Worker     flattenedOffsetInParentArrays = other.flattenedOffsetInParentArrays;
116*8975f5c5SAndroid Build Coastguard Worker     location                      = other.location;
117*8975f5c5SAndroid Build Coastguard Worker     hasImplicitLocation           = other.hasImplicitLocation;
118*8975f5c5SAndroid Build Coastguard Worker     binding                       = other.binding;
119*8975f5c5SAndroid Build Coastguard Worker     imageUnitFormat               = other.imageUnitFormat;
120*8975f5c5SAndroid Build Coastguard Worker     offset                        = other.offset;
121*8975f5c5SAndroid Build Coastguard Worker     rasterOrdered                 = other.rasterOrdered;
122*8975f5c5SAndroid Build Coastguard Worker     readonly                      = other.readonly;
123*8975f5c5SAndroid Build Coastguard Worker     writeonly                     = other.writeonly;
124*8975f5c5SAndroid Build Coastguard Worker     isFragmentInOut               = other.isFragmentInOut;
125*8975f5c5SAndroid Build Coastguard Worker     index                         = other.index;
126*8975f5c5SAndroid Build Coastguard Worker     yuv                           = other.yuv;
127*8975f5c5SAndroid Build Coastguard Worker     interpolation                 = other.interpolation;
128*8975f5c5SAndroid Build Coastguard Worker     isInvariant                   = other.isInvariant;
129*8975f5c5SAndroid Build Coastguard Worker     isShaderIOBlock               = other.isShaderIOBlock;
130*8975f5c5SAndroid Build Coastguard Worker     isPatch                       = other.isPatch;
131*8975f5c5SAndroid Build Coastguard Worker     texelFetchStaticUse           = other.texelFetchStaticUse;
132*8975f5c5SAndroid Build Coastguard Worker     id                            = other.id;
133*8975f5c5SAndroid Build Coastguard Worker     return *this;
134*8975f5c5SAndroid Build Coastguard Worker }
135*8975f5c5SAndroid Build Coastguard Worker 
operator ==(const ShaderVariable & other) const136*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::operator==(const ShaderVariable &other) const
137*8975f5c5SAndroid Build Coastguard Worker {
138*8975f5c5SAndroid Build Coastguard Worker     if (type != other.type || precision != other.precision || name != other.name ||
139*8975f5c5SAndroid Build Coastguard Worker         mappedName != other.mappedName || arraySizes != other.arraySizes ||
140*8975f5c5SAndroid Build Coastguard Worker         staticUse != other.staticUse || active != other.active ||
141*8975f5c5SAndroid Build Coastguard Worker         fields.size() != other.fields.size() || structOrBlockName != other.structOrBlockName ||
142*8975f5c5SAndroid Build Coastguard Worker         mappedStructOrBlockName != other.mappedStructOrBlockName ||
143*8975f5c5SAndroid Build Coastguard Worker         isRowMajorLayout != other.isRowMajorLayout || location != other.location ||
144*8975f5c5SAndroid Build Coastguard Worker         hasImplicitLocation != other.hasImplicitLocation || binding != other.binding ||
145*8975f5c5SAndroid Build Coastguard Worker         imageUnitFormat != other.imageUnitFormat || offset != other.offset ||
146*8975f5c5SAndroid Build Coastguard Worker         rasterOrdered != other.rasterOrdered || readonly != other.readonly ||
147*8975f5c5SAndroid Build Coastguard Worker         writeonly != other.writeonly || index != other.index || yuv != other.yuv ||
148*8975f5c5SAndroid Build Coastguard Worker         interpolation != other.interpolation || isInvariant != other.isInvariant ||
149*8975f5c5SAndroid Build Coastguard Worker         isShaderIOBlock != other.isShaderIOBlock || isPatch != other.isPatch ||
150*8975f5c5SAndroid Build Coastguard Worker         texelFetchStaticUse != other.texelFetchStaticUse ||
151*8975f5c5SAndroid Build Coastguard Worker         isFragmentInOut != other.isFragmentInOut)
152*8975f5c5SAndroid Build Coastguard Worker     {
153*8975f5c5SAndroid Build Coastguard Worker         return false;
154*8975f5c5SAndroid Build Coastguard Worker     }
155*8975f5c5SAndroid Build Coastguard Worker     for (size_t ii = 0; ii < fields.size(); ++ii)
156*8975f5c5SAndroid Build Coastguard Worker     {
157*8975f5c5SAndroid Build Coastguard Worker         if (fields[ii] != other.fields[ii])
158*8975f5c5SAndroid Build Coastguard Worker             return false;
159*8975f5c5SAndroid Build Coastguard Worker     }
160*8975f5c5SAndroid Build Coastguard Worker     return true;
161*8975f5c5SAndroid Build Coastguard Worker }
162*8975f5c5SAndroid Build Coastguard Worker 
setArraySize(unsigned int size)163*8975f5c5SAndroid Build Coastguard Worker void ShaderVariable::setArraySize(unsigned int size)
164*8975f5c5SAndroid Build Coastguard Worker {
165*8975f5c5SAndroid Build Coastguard Worker     arraySizes.clear();
166*8975f5c5SAndroid Build Coastguard Worker     if (size != 0)
167*8975f5c5SAndroid Build Coastguard Worker     {
168*8975f5c5SAndroid Build Coastguard Worker         arraySizes.push_back(size);
169*8975f5c5SAndroid Build Coastguard Worker     }
170*8975f5c5SAndroid Build Coastguard Worker }
171*8975f5c5SAndroid Build Coastguard Worker 
getInnerArraySizeProduct() const172*8975f5c5SAndroid Build Coastguard Worker unsigned int ShaderVariable::getInnerArraySizeProduct() const
173*8975f5c5SAndroid Build Coastguard Worker {
174*8975f5c5SAndroid Build Coastguard Worker     return gl::InnerArraySizeProduct(arraySizes);
175*8975f5c5SAndroid Build Coastguard Worker }
176*8975f5c5SAndroid Build Coastguard Worker 
getArraySizeProduct() const177*8975f5c5SAndroid Build Coastguard Worker unsigned int ShaderVariable::getArraySizeProduct() const
178*8975f5c5SAndroid Build Coastguard Worker {
179*8975f5c5SAndroid Build Coastguard Worker     return gl::ArraySizeProduct(arraySizes);
180*8975f5c5SAndroid Build Coastguard Worker }
181*8975f5c5SAndroid Build Coastguard Worker 
indexIntoArray(unsigned int arrayIndex)182*8975f5c5SAndroid Build Coastguard Worker void ShaderVariable::indexIntoArray(unsigned int arrayIndex)
183*8975f5c5SAndroid Build Coastguard Worker {
184*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isArray());
185*8975f5c5SAndroid Build Coastguard Worker     flattenedOffsetInParentArrays = arrayIndex + getOutermostArraySize() * parentArrayIndex();
186*8975f5c5SAndroid Build Coastguard Worker     arraySizes.pop_back();
187*8975f5c5SAndroid Build Coastguard Worker }
188*8975f5c5SAndroid Build Coastguard Worker 
getNestedArraySize(unsigned int arrayNestingIndex) const189*8975f5c5SAndroid Build Coastguard Worker unsigned int ShaderVariable::getNestedArraySize(unsigned int arrayNestingIndex) const
190*8975f5c5SAndroid Build Coastguard Worker {
191*8975f5c5SAndroid Build Coastguard Worker     ASSERT(arraySizes.size() > arrayNestingIndex);
192*8975f5c5SAndroid Build Coastguard Worker     unsigned int arraySize = arraySizes[arraySizes.size() - 1u - arrayNestingIndex];
193*8975f5c5SAndroid Build Coastguard Worker 
194*8975f5c5SAndroid Build Coastguard Worker     if (arraySize == 0)
195*8975f5c5SAndroid Build Coastguard Worker     {
196*8975f5c5SAndroid Build Coastguard Worker         // Unsized array, so give it at least 1 entry
197*8975f5c5SAndroid Build Coastguard Worker         arraySize = 1;
198*8975f5c5SAndroid Build Coastguard Worker     }
199*8975f5c5SAndroid Build Coastguard Worker 
200*8975f5c5SAndroid Build Coastguard Worker     return arraySize;
201*8975f5c5SAndroid Build Coastguard Worker }
202*8975f5c5SAndroid Build Coastguard Worker 
getBasicTypeElementCount() const203*8975f5c5SAndroid Build Coastguard Worker unsigned int ShaderVariable::getBasicTypeElementCount() const
204*8975f5c5SAndroid Build Coastguard Worker {
205*8975f5c5SAndroid Build Coastguard Worker     // GLES 3.1 Nov 2016 section 7.3.1.1 page 77 specifies that a separate entry should be generated
206*8975f5c5SAndroid Build Coastguard Worker     // for each array element when dealing with an array of arrays or an array of structs.
207*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!isArrayOfArrays());
208*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!isStruct() || !isArray());
209*8975f5c5SAndroid Build Coastguard Worker 
210*8975f5c5SAndroid Build Coastguard Worker     // GLES 3.1 Nov 2016 page 82.
211*8975f5c5SAndroid Build Coastguard Worker     if (isArray())
212*8975f5c5SAndroid Build Coastguard Worker     {
213*8975f5c5SAndroid Build Coastguard Worker         return getOutermostArraySize();
214*8975f5c5SAndroid Build Coastguard Worker     }
215*8975f5c5SAndroid Build Coastguard Worker     return 1u;
216*8975f5c5SAndroid Build Coastguard Worker }
217*8975f5c5SAndroid Build Coastguard Worker 
getExternalSize() const218*8975f5c5SAndroid Build Coastguard Worker unsigned int ShaderVariable::getExternalSize() const
219*8975f5c5SAndroid Build Coastguard Worker {
220*8975f5c5SAndroid Build Coastguard Worker     unsigned int memorySize = 0;
221*8975f5c5SAndroid Build Coastguard Worker 
222*8975f5c5SAndroid Build Coastguard Worker     if (isStruct())
223*8975f5c5SAndroid Build Coastguard Worker     {
224*8975f5c5SAndroid Build Coastguard Worker         // Have a structure, need to compute the structure size.
225*8975f5c5SAndroid Build Coastguard Worker         for (const auto &field : fields)
226*8975f5c5SAndroid Build Coastguard Worker         {
227*8975f5c5SAndroid Build Coastguard Worker             memorySize += field.getExternalSize();
228*8975f5c5SAndroid Build Coastguard Worker         }
229*8975f5c5SAndroid Build Coastguard Worker     }
230*8975f5c5SAndroid Build Coastguard Worker     else
231*8975f5c5SAndroid Build Coastguard Worker     {
232*8975f5c5SAndroid Build Coastguard Worker         memorySize += gl::VariableExternalSize(type);
233*8975f5c5SAndroid Build Coastguard Worker     }
234*8975f5c5SAndroid Build Coastguard Worker 
235*8975f5c5SAndroid Build Coastguard Worker     // multiply by array size to get total memory size of this variable / struct.
236*8975f5c5SAndroid Build Coastguard Worker     memorySize *= getArraySizeProduct();
237*8975f5c5SAndroid Build Coastguard Worker 
238*8975f5c5SAndroid Build Coastguard Worker     return memorySize;
239*8975f5c5SAndroid Build Coastguard Worker }
240*8975f5c5SAndroid Build Coastguard Worker 
findInfoByMappedName(const std::string & mappedFullName,const ShaderVariable ** leafVar,std::string * originalFullName) const241*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::findInfoByMappedName(const std::string &mappedFullName,
242*8975f5c5SAndroid Build Coastguard Worker                                           const ShaderVariable **leafVar,
243*8975f5c5SAndroid Build Coastguard Worker                                           std::string *originalFullName) const
244*8975f5c5SAndroid Build Coastguard Worker {
245*8975f5c5SAndroid Build Coastguard Worker     ASSERT(leafVar && originalFullName);
246*8975f5c5SAndroid Build Coastguard Worker     // There are three cases:
247*8975f5c5SAndroid Build Coastguard Worker     // 1) the top variable is of struct type;
248*8975f5c5SAndroid Build Coastguard Worker     // 2) the top variable is an array;
249*8975f5c5SAndroid Build Coastguard Worker     // 3) otherwise.
250*8975f5c5SAndroid Build Coastguard Worker     size_t pos = mappedFullName.find_first_of(".[");
251*8975f5c5SAndroid Build Coastguard Worker 
252*8975f5c5SAndroid Build Coastguard Worker     if (pos == std::string::npos)
253*8975f5c5SAndroid Build Coastguard Worker     {
254*8975f5c5SAndroid Build Coastguard Worker         // Case 3.
255*8975f5c5SAndroid Build Coastguard Worker         if (mappedFullName != this->mappedName)
256*8975f5c5SAndroid Build Coastguard Worker             return false;
257*8975f5c5SAndroid Build Coastguard Worker         *originalFullName = this->name;
258*8975f5c5SAndroid Build Coastguard Worker         *leafVar          = this;
259*8975f5c5SAndroid Build Coastguard Worker         return true;
260*8975f5c5SAndroid Build Coastguard Worker     }
261*8975f5c5SAndroid Build Coastguard Worker     else
262*8975f5c5SAndroid Build Coastguard Worker     {
263*8975f5c5SAndroid Build Coastguard Worker         std::string topName = mappedFullName.substr(0, pos);
264*8975f5c5SAndroid Build Coastguard Worker         if (topName != this->mappedName)
265*8975f5c5SAndroid Build Coastguard Worker             return false;
266*8975f5c5SAndroid Build Coastguard Worker         std::string originalName = this->name;
267*8975f5c5SAndroid Build Coastguard Worker         std::string remaining;
268*8975f5c5SAndroid Build Coastguard Worker         if (mappedFullName[pos] == '[')
269*8975f5c5SAndroid Build Coastguard Worker         {
270*8975f5c5SAndroid Build Coastguard Worker             // Case 2.
271*8975f5c5SAndroid Build Coastguard Worker             size_t closePos = mappedFullName.find_first_of(']');
272*8975f5c5SAndroid Build Coastguard Worker             if (closePos < pos || closePos == std::string::npos)
273*8975f5c5SAndroid Build Coastguard Worker                 return false;
274*8975f5c5SAndroid Build Coastguard Worker             // Append '[index]'.
275*8975f5c5SAndroid Build Coastguard Worker             originalName += mappedFullName.substr(pos, closePos - pos + 1);
276*8975f5c5SAndroid Build Coastguard Worker             if (closePos + 1 == mappedFullName.size())
277*8975f5c5SAndroid Build Coastguard Worker             {
278*8975f5c5SAndroid Build Coastguard Worker                 *originalFullName = originalName;
279*8975f5c5SAndroid Build Coastguard Worker                 *leafVar          = this;
280*8975f5c5SAndroid Build Coastguard Worker                 return true;
281*8975f5c5SAndroid Build Coastguard Worker             }
282*8975f5c5SAndroid Build Coastguard Worker             else
283*8975f5c5SAndroid Build Coastguard Worker             {
284*8975f5c5SAndroid Build Coastguard Worker                 // In the form of 'a[0].b', so after ']', '.' is expected.
285*8975f5c5SAndroid Build Coastguard Worker                 if (mappedFullName[closePos + 1] != '.')
286*8975f5c5SAndroid Build Coastguard Worker                     return false;
287*8975f5c5SAndroid Build Coastguard Worker                 remaining = mappedFullName.substr(closePos + 2);  // Skip "]."
288*8975f5c5SAndroid Build Coastguard Worker             }
289*8975f5c5SAndroid Build Coastguard Worker         }
290*8975f5c5SAndroid Build Coastguard Worker         else
291*8975f5c5SAndroid Build Coastguard Worker         {
292*8975f5c5SAndroid Build Coastguard Worker             // Case 1.
293*8975f5c5SAndroid Build Coastguard Worker             remaining = mappedFullName.substr(pos + 1);  // Skip "."
294*8975f5c5SAndroid Build Coastguard Worker         }
295*8975f5c5SAndroid Build Coastguard Worker         for (size_t ii = 0; ii < this->fields.size(); ++ii)
296*8975f5c5SAndroid Build Coastguard Worker         {
297*8975f5c5SAndroid Build Coastguard Worker             const ShaderVariable *fieldVar = nullptr;
298*8975f5c5SAndroid Build Coastguard Worker             std::string originalFieldName;
299*8975f5c5SAndroid Build Coastguard Worker             bool found = fields[ii].findInfoByMappedName(remaining, &fieldVar, &originalFieldName);
300*8975f5c5SAndroid Build Coastguard Worker             if (found)
301*8975f5c5SAndroid Build Coastguard Worker             {
302*8975f5c5SAndroid Build Coastguard Worker                 *originalFullName = originalName + "." + originalFieldName;
303*8975f5c5SAndroid Build Coastguard Worker                 *leafVar          = fieldVar;
304*8975f5c5SAndroid Build Coastguard Worker                 return true;
305*8975f5c5SAndroid Build Coastguard Worker             }
306*8975f5c5SAndroid Build Coastguard Worker         }
307*8975f5c5SAndroid Build Coastguard Worker         return false;
308*8975f5c5SAndroid Build Coastguard Worker     }
309*8975f5c5SAndroid Build Coastguard Worker }
310*8975f5c5SAndroid Build Coastguard Worker 
findField(const std::string & fullName,uint32_t * fieldIndexOut) const311*8975f5c5SAndroid Build Coastguard Worker const sh::ShaderVariable *ShaderVariable::findField(const std::string &fullName,
312*8975f5c5SAndroid Build Coastguard Worker                                                     uint32_t *fieldIndexOut) const
313*8975f5c5SAndroid Build Coastguard Worker {
314*8975f5c5SAndroid Build Coastguard Worker     if (fields.empty())
315*8975f5c5SAndroid Build Coastguard Worker     {
316*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
317*8975f5c5SAndroid Build Coastguard Worker     }
318*8975f5c5SAndroid Build Coastguard Worker     size_t pos = fullName.find_first_of(".");
319*8975f5c5SAndroid Build Coastguard Worker     std::string topName, fieldName;
320*8975f5c5SAndroid Build Coastguard Worker     if (pos == std::string::npos)
321*8975f5c5SAndroid Build Coastguard Worker     {
322*8975f5c5SAndroid Build Coastguard Worker         // If this is a shader I/O block without an instance name, return the field given only the
323*8975f5c5SAndroid Build Coastguard Worker         // field name.
324*8975f5c5SAndroid Build Coastguard Worker         if (!isShaderIOBlock || !name.empty())
325*8975f5c5SAndroid Build Coastguard Worker         {
326*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
327*8975f5c5SAndroid Build Coastguard Worker         }
328*8975f5c5SAndroid Build Coastguard Worker 
329*8975f5c5SAndroid Build Coastguard Worker         fieldName = fullName;
330*8975f5c5SAndroid Build Coastguard Worker     }
331*8975f5c5SAndroid Build Coastguard Worker     else
332*8975f5c5SAndroid Build Coastguard Worker     {
333*8975f5c5SAndroid Build Coastguard Worker         std::string baseName = isShaderIOBlock ? structOrBlockName : name;
334*8975f5c5SAndroid Build Coastguard Worker         topName              = fullName.substr(0, pos);
335*8975f5c5SAndroid Build Coastguard Worker         if (topName != baseName)
336*8975f5c5SAndroid Build Coastguard Worker         {
337*8975f5c5SAndroid Build Coastguard Worker             return nullptr;
338*8975f5c5SAndroid Build Coastguard Worker         }
339*8975f5c5SAndroid Build Coastguard Worker         fieldName = fullName.substr(pos + 1);
340*8975f5c5SAndroid Build Coastguard Worker     }
341*8975f5c5SAndroid Build Coastguard Worker     if (fieldName.empty())
342*8975f5c5SAndroid Build Coastguard Worker     {
343*8975f5c5SAndroid Build Coastguard Worker         return nullptr;
344*8975f5c5SAndroid Build Coastguard Worker     }
345*8975f5c5SAndroid Build Coastguard Worker     for (size_t field = 0; field < fields.size(); ++field)
346*8975f5c5SAndroid Build Coastguard Worker     {
347*8975f5c5SAndroid Build Coastguard Worker         if (fields[field].name == fieldName)
348*8975f5c5SAndroid Build Coastguard Worker         {
349*8975f5c5SAndroid Build Coastguard Worker             *fieldIndexOut = static_cast<GLuint>(field);
350*8975f5c5SAndroid Build Coastguard Worker             return &fields[field];
351*8975f5c5SAndroid Build Coastguard Worker         }
352*8975f5c5SAndroid Build Coastguard Worker     }
353*8975f5c5SAndroid Build Coastguard Worker     return nullptr;
354*8975f5c5SAndroid Build Coastguard Worker }
355*8975f5c5SAndroid Build Coastguard Worker 
isBuiltIn() const356*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isBuiltIn() const
357*8975f5c5SAndroid Build Coastguard Worker {
358*8975f5c5SAndroid Build Coastguard Worker     return gl::IsBuiltInName(name);
359*8975f5c5SAndroid Build Coastguard Worker }
360*8975f5c5SAndroid Build Coastguard Worker 
isEmulatedBuiltIn() const361*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isEmulatedBuiltIn() const
362*8975f5c5SAndroid Build Coastguard Worker {
363*8975f5c5SAndroid Build Coastguard Worker     return isBuiltIn() && name != mappedName;
364*8975f5c5SAndroid Build Coastguard Worker }
365*8975f5c5SAndroid Build Coastguard Worker 
isSameVariableAtLinkTime(const ShaderVariable & other,bool matchPrecision,bool matchName) const366*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameVariableAtLinkTime(const ShaderVariable &other,
367*8975f5c5SAndroid Build Coastguard Worker                                               bool matchPrecision,
368*8975f5c5SAndroid Build Coastguard Worker                                               bool matchName) const
369*8975f5c5SAndroid Build Coastguard Worker {
370*8975f5c5SAndroid Build Coastguard Worker     if (type != other.type)
371*8975f5c5SAndroid Build Coastguard Worker         return false;
372*8975f5c5SAndroid Build Coastguard Worker     if (matchPrecision && precision != other.precision)
373*8975f5c5SAndroid Build Coastguard Worker         return false;
374*8975f5c5SAndroid Build Coastguard Worker     if (matchName && name != other.name)
375*8975f5c5SAndroid Build Coastguard Worker         return false;
376*8975f5c5SAndroid Build Coastguard Worker     ASSERT(!matchName || mappedName == other.mappedName);
377*8975f5c5SAndroid Build Coastguard Worker     if (arraySizes != other.arraySizes)
378*8975f5c5SAndroid Build Coastguard Worker         return false;
379*8975f5c5SAndroid Build Coastguard Worker     if (isRowMajorLayout != other.isRowMajorLayout)
380*8975f5c5SAndroid Build Coastguard Worker         return false;
381*8975f5c5SAndroid Build Coastguard Worker     if (fields.size() != other.fields.size())
382*8975f5c5SAndroid Build Coastguard Worker         return false;
383*8975f5c5SAndroid Build Coastguard Worker 
384*8975f5c5SAndroid Build Coastguard Worker     // [OpenGL ES 3.1 SPEC Chapter 7.4.1]
385*8975f5c5SAndroid Build Coastguard Worker     // Variables declared as structures are considered to match in type if and only if structure
386*8975f5c5SAndroid Build Coastguard Worker     // members match in name, type, qualification, and declaration order.
387*8975f5c5SAndroid Build Coastguard Worker     for (size_t ii = 0; ii < fields.size(); ++ii)
388*8975f5c5SAndroid Build Coastguard Worker     {
389*8975f5c5SAndroid Build Coastguard Worker         if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii], matchPrecision, true))
390*8975f5c5SAndroid Build Coastguard Worker         {
391*8975f5c5SAndroid Build Coastguard Worker             return false;
392*8975f5c5SAndroid Build Coastguard Worker         }
393*8975f5c5SAndroid Build Coastguard Worker     }
394*8975f5c5SAndroid Build Coastguard Worker     if (structOrBlockName != other.structOrBlockName ||
395*8975f5c5SAndroid Build Coastguard Worker         mappedStructOrBlockName != other.mappedStructOrBlockName)
396*8975f5c5SAndroid Build Coastguard Worker         return false;
397*8975f5c5SAndroid Build Coastguard Worker     return true;
398*8975f5c5SAndroid Build Coastguard Worker }
399*8975f5c5SAndroid Build Coastguard Worker 
updateEffectiveLocation(const sh::ShaderVariable & parent)400*8975f5c5SAndroid Build Coastguard Worker void ShaderVariable::updateEffectiveLocation(const sh::ShaderVariable &parent)
401*8975f5c5SAndroid Build Coastguard Worker {
402*8975f5c5SAndroid Build Coastguard Worker     if ((location < 0 || hasImplicitLocation) && !parent.hasImplicitLocation)
403*8975f5c5SAndroid Build Coastguard Worker     {
404*8975f5c5SAndroid Build Coastguard Worker         location = parent.location;
405*8975f5c5SAndroid Build Coastguard Worker     }
406*8975f5c5SAndroid Build Coastguard Worker }
407*8975f5c5SAndroid Build Coastguard Worker 
resetEffectiveLocation()408*8975f5c5SAndroid Build Coastguard Worker void ShaderVariable::resetEffectiveLocation()
409*8975f5c5SAndroid Build Coastguard Worker {
410*8975f5c5SAndroid Build Coastguard Worker     if (hasImplicitLocation)
411*8975f5c5SAndroid Build Coastguard Worker     {
412*8975f5c5SAndroid Build Coastguard Worker         location = -1;
413*8975f5c5SAndroid Build Coastguard Worker     }
414*8975f5c5SAndroid Build Coastguard Worker }
415*8975f5c5SAndroid Build Coastguard Worker 
isSameUniformAtLinkTime(const ShaderVariable & other) const416*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameUniformAtLinkTime(const ShaderVariable &other) const
417*8975f5c5SAndroid Build Coastguard Worker {
418*8975f5c5SAndroid Build Coastguard Worker     // Enforce a consistent match.
419*8975f5c5SAndroid Build Coastguard Worker     // https://cvs.khronos.org/bugzilla/show_bug.cgi?id=16261
420*8975f5c5SAndroid Build Coastguard Worker     if (binding != -1 && other.binding != -1 && binding != other.binding)
421*8975f5c5SAndroid Build Coastguard Worker     {
422*8975f5c5SAndroid Build Coastguard Worker         return false;
423*8975f5c5SAndroid Build Coastguard Worker     }
424*8975f5c5SAndroid Build Coastguard Worker     if (imageUnitFormat != other.imageUnitFormat)
425*8975f5c5SAndroid Build Coastguard Worker     {
426*8975f5c5SAndroid Build Coastguard Worker         return false;
427*8975f5c5SAndroid Build Coastguard Worker     }
428*8975f5c5SAndroid Build Coastguard Worker     if (location != -1 && other.location != -1 && location != other.location)
429*8975f5c5SAndroid Build Coastguard Worker     {
430*8975f5c5SAndroid Build Coastguard Worker         return false;
431*8975f5c5SAndroid Build Coastguard Worker     }
432*8975f5c5SAndroid Build Coastguard Worker     if (offset != other.offset)
433*8975f5c5SAndroid Build Coastguard Worker     {
434*8975f5c5SAndroid Build Coastguard Worker         return false;
435*8975f5c5SAndroid Build Coastguard Worker     }
436*8975f5c5SAndroid Build Coastguard Worker     if (rasterOrdered != other.rasterOrdered)
437*8975f5c5SAndroid Build Coastguard Worker     {
438*8975f5c5SAndroid Build Coastguard Worker         return false;
439*8975f5c5SAndroid Build Coastguard Worker     }
440*8975f5c5SAndroid Build Coastguard Worker     if (readonly != other.readonly || writeonly != other.writeonly)
441*8975f5c5SAndroid Build Coastguard Worker     {
442*8975f5c5SAndroid Build Coastguard Worker         return false;
443*8975f5c5SAndroid Build Coastguard Worker     }
444*8975f5c5SAndroid Build Coastguard Worker     return ShaderVariable::isSameVariableAtLinkTime(other, true, true);
445*8975f5c5SAndroid Build Coastguard Worker }
446*8975f5c5SAndroid Build Coastguard Worker 
isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable & other) const447*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameInterfaceBlockFieldAtLinkTime(const ShaderVariable &other) const
448*8975f5c5SAndroid Build Coastguard Worker {
449*8975f5c5SAndroid Build Coastguard Worker     return (ShaderVariable::isSameVariableAtLinkTime(other, true, true));
450*8975f5c5SAndroid Build Coastguard Worker }
451*8975f5c5SAndroid Build Coastguard Worker 
isSameVaryingAtLinkTime(const ShaderVariable & other) const452*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other) const
453*8975f5c5SAndroid Build Coastguard Worker {
454*8975f5c5SAndroid Build Coastguard Worker     return isSameVaryingAtLinkTime(other, 100);
455*8975f5c5SAndroid Build Coastguard Worker }
456*8975f5c5SAndroid Build Coastguard Worker 
isSameVaryingAtLinkTime(const ShaderVariable & other,int shaderVersion) const457*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameVaryingAtLinkTime(const ShaderVariable &other, int shaderVersion) const
458*8975f5c5SAndroid Build Coastguard Worker {
459*8975f5c5SAndroid Build Coastguard Worker     return ShaderVariable::isSameVariableAtLinkTime(other, false, false) &&
460*8975f5c5SAndroid Build Coastguard Worker            InterpolationTypesMatch(interpolation, other.interpolation) &&
461*8975f5c5SAndroid Build Coastguard Worker            (shaderVersion >= 300 || isInvariant == other.isInvariant) &&
462*8975f5c5SAndroid Build Coastguard Worker            (isPatch == other.isPatch) && location == other.location &&
463*8975f5c5SAndroid Build Coastguard Worker            (isSameNameAtLinkTime(other) || (shaderVersion >= 310 && location >= 0));
464*8975f5c5SAndroid Build Coastguard Worker }
465*8975f5c5SAndroid Build Coastguard Worker 
isSameNameAtLinkTime(const ShaderVariable & other) const466*8975f5c5SAndroid Build Coastguard Worker bool ShaderVariable::isSameNameAtLinkTime(const ShaderVariable &other) const
467*8975f5c5SAndroid Build Coastguard Worker {
468*8975f5c5SAndroid Build Coastguard Worker     if (isShaderIOBlock != other.isShaderIOBlock)
469*8975f5c5SAndroid Build Coastguard Worker     {
470*8975f5c5SAndroid Build Coastguard Worker         return false;
471*8975f5c5SAndroid Build Coastguard Worker     }
472*8975f5c5SAndroid Build Coastguard Worker 
473*8975f5c5SAndroid Build Coastguard Worker     if (isShaderIOBlock)
474*8975f5c5SAndroid Build Coastguard Worker     {
475*8975f5c5SAndroid Build Coastguard Worker         // Shader I/O blocks match by block name.
476*8975f5c5SAndroid Build Coastguard Worker         return structOrBlockName == other.structOrBlockName;
477*8975f5c5SAndroid Build Coastguard Worker     }
478*8975f5c5SAndroid Build Coastguard Worker 
479*8975f5c5SAndroid Build Coastguard Worker     // Otherwise match by name.
480*8975f5c5SAndroid Build Coastguard Worker     return name == other.name;
481*8975f5c5SAndroid Build Coastguard Worker }
482*8975f5c5SAndroid Build Coastguard Worker 
InterfaceBlock()483*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock::InterfaceBlock()
484*8975f5c5SAndroid Build Coastguard Worker     : arraySize(0),
485*8975f5c5SAndroid Build Coastguard Worker       layout(BLOCKLAYOUT_PACKED),
486*8975f5c5SAndroid Build Coastguard Worker       isRowMajorLayout(false),
487*8975f5c5SAndroid Build Coastguard Worker       binding(-1),
488*8975f5c5SAndroid Build Coastguard Worker       staticUse(false),
489*8975f5c5SAndroid Build Coastguard Worker       active(false),
490*8975f5c5SAndroid Build Coastguard Worker       isReadOnly(false),
491*8975f5c5SAndroid Build Coastguard Worker       blockType(BlockType::kBlockUniform),
492*8975f5c5SAndroid Build Coastguard Worker       id(0)
493*8975f5c5SAndroid Build Coastguard Worker {}
494*8975f5c5SAndroid Build Coastguard Worker 
~InterfaceBlock()495*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock::~InterfaceBlock() {}
496*8975f5c5SAndroid Build Coastguard Worker 
InterfaceBlock(const InterfaceBlock & other)497*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
498*8975f5c5SAndroid Build Coastguard Worker     : name(other.name),
499*8975f5c5SAndroid Build Coastguard Worker       mappedName(other.mappedName),
500*8975f5c5SAndroid Build Coastguard Worker       instanceName(other.instanceName),
501*8975f5c5SAndroid Build Coastguard Worker       arraySize(other.arraySize),
502*8975f5c5SAndroid Build Coastguard Worker       layout(other.layout),
503*8975f5c5SAndroid Build Coastguard Worker       isRowMajorLayout(other.isRowMajorLayout),
504*8975f5c5SAndroid Build Coastguard Worker       binding(other.binding),
505*8975f5c5SAndroid Build Coastguard Worker       staticUse(other.staticUse),
506*8975f5c5SAndroid Build Coastguard Worker       active(other.active),
507*8975f5c5SAndroid Build Coastguard Worker       isReadOnly(other.isReadOnly),
508*8975f5c5SAndroid Build Coastguard Worker       blockType(other.blockType),
509*8975f5c5SAndroid Build Coastguard Worker       fields(other.fields),
510*8975f5c5SAndroid Build Coastguard Worker       id(other.id)
511*8975f5c5SAndroid Build Coastguard Worker {}
512*8975f5c5SAndroid Build Coastguard Worker 
operator =(const InterfaceBlock & other)513*8975f5c5SAndroid Build Coastguard Worker InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
514*8975f5c5SAndroid Build Coastguard Worker {
515*8975f5c5SAndroid Build Coastguard Worker     name             = other.name;
516*8975f5c5SAndroid Build Coastguard Worker     mappedName       = other.mappedName;
517*8975f5c5SAndroid Build Coastguard Worker     instanceName     = other.instanceName;
518*8975f5c5SAndroid Build Coastguard Worker     arraySize        = other.arraySize;
519*8975f5c5SAndroid Build Coastguard Worker     layout           = other.layout;
520*8975f5c5SAndroid Build Coastguard Worker     isRowMajorLayout = other.isRowMajorLayout;
521*8975f5c5SAndroid Build Coastguard Worker     binding          = other.binding;
522*8975f5c5SAndroid Build Coastguard Worker     staticUse        = other.staticUse;
523*8975f5c5SAndroid Build Coastguard Worker     active           = other.active;
524*8975f5c5SAndroid Build Coastguard Worker     isReadOnly       = other.isReadOnly;
525*8975f5c5SAndroid Build Coastguard Worker     blockType        = other.blockType;
526*8975f5c5SAndroid Build Coastguard Worker     id               = other.id;
527*8975f5c5SAndroid Build Coastguard Worker     fields           = other.fields;
528*8975f5c5SAndroid Build Coastguard Worker     return *this;
529*8975f5c5SAndroid Build Coastguard Worker }
530*8975f5c5SAndroid Build Coastguard Worker 
fieldPrefix() const531*8975f5c5SAndroid Build Coastguard Worker std::string InterfaceBlock::fieldPrefix() const
532*8975f5c5SAndroid Build Coastguard Worker {
533*8975f5c5SAndroid Build Coastguard Worker     return instanceName.empty() ? "" : name;
534*8975f5c5SAndroid Build Coastguard Worker }
535*8975f5c5SAndroid Build Coastguard Worker 
fieldMappedPrefix() const536*8975f5c5SAndroid Build Coastguard Worker std::string InterfaceBlock::fieldMappedPrefix() const
537*8975f5c5SAndroid Build Coastguard Worker {
538*8975f5c5SAndroid Build Coastguard Worker     return instanceName.empty() ? "" : mappedName;
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker 
isSameInterfaceBlockAtLinkTime(const InterfaceBlock & other) const541*8975f5c5SAndroid Build Coastguard Worker bool InterfaceBlock::isSameInterfaceBlockAtLinkTime(const InterfaceBlock &other) const
542*8975f5c5SAndroid Build Coastguard Worker {
543*8975f5c5SAndroid Build Coastguard Worker     if (name != other.name || mappedName != other.mappedName || arraySize != other.arraySize ||
544*8975f5c5SAndroid Build Coastguard Worker         layout != other.layout || isRowMajorLayout != other.isRowMajorLayout ||
545*8975f5c5SAndroid Build Coastguard Worker         binding != other.binding || blockType != other.blockType ||
546*8975f5c5SAndroid Build Coastguard Worker         fields.size() != other.fields.size())
547*8975f5c5SAndroid Build Coastguard Worker     {
548*8975f5c5SAndroid Build Coastguard Worker         return false;
549*8975f5c5SAndroid Build Coastguard Worker     }
550*8975f5c5SAndroid Build Coastguard Worker 
551*8975f5c5SAndroid Build Coastguard Worker     for (size_t fieldIndex = 0; fieldIndex < fields.size(); ++fieldIndex)
552*8975f5c5SAndroid Build Coastguard Worker     {
553*8975f5c5SAndroid Build Coastguard Worker         if (!fields[fieldIndex].isSameInterfaceBlockFieldAtLinkTime(other.fields[fieldIndex]))
554*8975f5c5SAndroid Build Coastguard Worker         {
555*8975f5c5SAndroid Build Coastguard Worker             return false;
556*8975f5c5SAndroid Build Coastguard Worker         }
557*8975f5c5SAndroid Build Coastguard Worker     }
558*8975f5c5SAndroid Build Coastguard Worker 
559*8975f5c5SAndroid Build Coastguard Worker     return true;
560*8975f5c5SAndroid Build Coastguard Worker }
561*8975f5c5SAndroid Build Coastguard Worker 
isBuiltIn() const562*8975f5c5SAndroid Build Coastguard Worker bool InterfaceBlock::isBuiltIn() const
563*8975f5c5SAndroid Build Coastguard Worker {
564*8975f5c5SAndroid Build Coastguard Worker     return gl::IsBuiltInName(name);
565*8975f5c5SAndroid Build Coastguard Worker }
566*8975f5c5SAndroid Build Coastguard Worker 
fill(int fillValue)567*8975f5c5SAndroid Build Coastguard Worker void WorkGroupSize::fill(int fillValue)
568*8975f5c5SAndroid Build Coastguard Worker {
569*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[0] = fillValue;
570*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[1] = fillValue;
571*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[2] = fillValue;
572*8975f5c5SAndroid Build Coastguard Worker }
573*8975f5c5SAndroid Build Coastguard Worker 
setLocalSize(int localSizeX,int localSizeY,int localSizeZ)574*8975f5c5SAndroid Build Coastguard Worker void WorkGroupSize::setLocalSize(int localSizeX, int localSizeY, int localSizeZ)
575*8975f5c5SAndroid Build Coastguard Worker {
576*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[0] = localSizeX;
577*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[1] = localSizeY;
578*8975f5c5SAndroid Build Coastguard Worker     localSizeQualifiers[2] = localSizeZ;
579*8975f5c5SAndroid Build Coastguard Worker }
580*8975f5c5SAndroid Build Coastguard Worker 
581*8975f5c5SAndroid Build Coastguard Worker // check that if one of them is less than 1, then all of them are.
582*8975f5c5SAndroid Build Coastguard Worker // Or if one is positive, then all of them are positive.
isLocalSizeValid() const583*8975f5c5SAndroid Build Coastguard Worker bool WorkGroupSize::isLocalSizeValid() const
584*8975f5c5SAndroid Build Coastguard Worker {
585*8975f5c5SAndroid Build Coastguard Worker     return (
586*8975f5c5SAndroid Build Coastguard Worker         (localSizeQualifiers[0] < 1 && localSizeQualifiers[1] < 1 && localSizeQualifiers[2] < 1) ||
587*8975f5c5SAndroid Build Coastguard Worker         (localSizeQualifiers[0] > 0 && localSizeQualifiers[1] > 0 && localSizeQualifiers[2] > 0));
588*8975f5c5SAndroid Build Coastguard Worker }
589*8975f5c5SAndroid Build Coastguard Worker 
isAnyValueSet() const590*8975f5c5SAndroid Build Coastguard Worker bool WorkGroupSize::isAnyValueSet() const
591*8975f5c5SAndroid Build Coastguard Worker {
592*8975f5c5SAndroid Build Coastguard Worker     return localSizeQualifiers[0] > 0 || localSizeQualifiers[1] > 0 || localSizeQualifiers[2] > 0;
593*8975f5c5SAndroid Build Coastguard Worker }
594*8975f5c5SAndroid Build Coastguard Worker 
isDeclared() const595*8975f5c5SAndroid Build Coastguard Worker bool WorkGroupSize::isDeclared() const
596*8975f5c5SAndroid Build Coastguard Worker {
597*8975f5c5SAndroid Build Coastguard Worker     bool localSizeDeclared = localSizeQualifiers[0] > 0;
598*8975f5c5SAndroid Build Coastguard Worker     ASSERT(isLocalSizeValid());
599*8975f5c5SAndroid Build Coastguard Worker     return localSizeDeclared;
600*8975f5c5SAndroid Build Coastguard Worker }
601*8975f5c5SAndroid Build Coastguard Worker 
isWorkGroupSizeMatching(const WorkGroupSize & right) const602*8975f5c5SAndroid Build Coastguard Worker bool WorkGroupSize::isWorkGroupSizeMatching(const WorkGroupSize &right) const
603*8975f5c5SAndroid Build Coastguard Worker {
604*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0u; i < size(); ++i)
605*8975f5c5SAndroid Build Coastguard Worker     {
606*8975f5c5SAndroid Build Coastguard Worker         bool result = (localSizeQualifiers[i] == right.localSizeQualifiers[i] ||
607*8975f5c5SAndroid Build Coastguard Worker                        (localSizeQualifiers[i] == 1 && right.localSizeQualifiers[i] == -1) ||
608*8975f5c5SAndroid Build Coastguard Worker                        (localSizeQualifiers[i] == -1 && right.localSizeQualifiers[i] == 1));
609*8975f5c5SAndroid Build Coastguard Worker         if (!result)
610*8975f5c5SAndroid Build Coastguard Worker         {
611*8975f5c5SAndroid Build Coastguard Worker             return false;
612*8975f5c5SAndroid Build Coastguard Worker         }
613*8975f5c5SAndroid Build Coastguard Worker     }
614*8975f5c5SAndroid Build Coastguard Worker     return true;
615*8975f5c5SAndroid Build Coastguard Worker }
616*8975f5c5SAndroid Build Coastguard Worker 
operator [](size_t index)617*8975f5c5SAndroid Build Coastguard Worker int &WorkGroupSize::operator[](size_t index)
618*8975f5c5SAndroid Build Coastguard Worker {
619*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index < size());
620*8975f5c5SAndroid Build Coastguard Worker     return localSizeQualifiers[index];
621*8975f5c5SAndroid Build Coastguard Worker }
622*8975f5c5SAndroid Build Coastguard Worker 
operator [](size_t index) const623*8975f5c5SAndroid Build Coastguard Worker int WorkGroupSize::operator[](size_t index) const
624*8975f5c5SAndroid Build Coastguard Worker {
625*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index < size());
626*8975f5c5SAndroid Build Coastguard Worker     return localSizeQualifiers[index];
627*8975f5c5SAndroid Build Coastguard Worker }
628*8975f5c5SAndroid Build Coastguard Worker 
size() const629*8975f5c5SAndroid Build Coastguard Worker size_t WorkGroupSize::size() const
630*8975f5c5SAndroid Build Coastguard Worker {
631*8975f5c5SAndroid Build Coastguard Worker     return 3u;
632*8975f5c5SAndroid Build Coastguard Worker }
633*8975f5c5SAndroid Build Coastguard Worker 
634*8975f5c5SAndroid Build Coastguard Worker }  // namespace sh
635