blob: a3fe633b43a46a2a4de890fce7d9bd3bd12c43a2 [file] [log] [blame]
Jamie Madill6a729792014-07-18 10:33:14 -04001//
2// Copyright (c) 2014 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Jamie Madilla2ad4e82014-07-17 14:16:32 -04006// ShaderVars.cpp:
Jamie Madill6a729792014-07-18 10:33:14 -04007// Methods for GL variable types (varyings, uniforms, etc)
8//
9
Jamie Madille294bb82014-07-17 14:16:26 -040010#include <GLSLANG/ShaderLang.h>
Jamie Madill6a729792014-07-18 10:33:14 -040011
Olli Etuahod57e0db2015-04-24 15:05:08 +030012#include "common/debug.h"
Zhenyao Moed136362014-10-03 13:23:01 -070013
Jamie Madill6a729792014-07-18 10:33:14 -040014namespace sh
15{
16
Jamie Madille9cc4692015-02-19 16:00:13 -050017namespace
18{
19
20InterpolationType GetNonAuxiliaryInterpolationType(InterpolationType interpolation)
21{
22 return (interpolation == INTERPOLATION_CENTROID ? INTERPOLATION_SMOOTH : interpolation);
23}
24
25}
26// The ES 3.0 spec is not clear on this point, but the ES 3.1 spec, and discussion
27// on Khronos.org, clarifies that a smooth/flat mismatch produces a link error,
28// but auxiliary qualifier mismatch (centroid) does not.
29bool InterpolationTypesMatch(InterpolationType a, InterpolationType b)
30{
31 return (GetNonAuxiliaryInterpolationType(a) == GetNonAuxiliaryInterpolationType(b));
32}
33
Jamie Madill6a729792014-07-18 10:33:14 -040034ShaderVariable::ShaderVariable()
35 : type(0),
36 precision(0),
37 arraySize(0),
38 staticUse(false)
39{}
40
41ShaderVariable::ShaderVariable(GLenum typeIn, unsigned int arraySizeIn)
42 : type(typeIn),
43 precision(0),
44 arraySize(arraySizeIn),
45 staticUse(false)
46{}
47
48ShaderVariable::~ShaderVariable()
49{}
50
51ShaderVariable::ShaderVariable(const ShaderVariable &other)
52 : type(other.type),
53 precision(other.precision),
54 name(other.name),
55 mappedName(other.mappedName),
56 arraySize(other.arraySize),
Jamie Madill42bcf322014-08-25 16:20:46 -040057 staticUse(other.staticUse),
58 fields(other.fields),
59 structName(other.structName)
Jamie Madill6a729792014-07-18 10:33:14 -040060{}
61
62ShaderVariable &ShaderVariable::operator=(const ShaderVariable &other)
63{
64 type = other.type;
65 precision = other.precision;
66 name = other.name;
67 mappedName = other.mappedName;
68 arraySize = other.arraySize;
69 staticUse = other.staticUse;
Jamie Madill42bcf322014-08-25 16:20:46 -040070 fields = other.fields;
71 structName = other.structName;
Jamie Madill6a729792014-07-18 10:33:14 -040072 return *this;
73}
74
Zhenyao Moed136362014-10-03 13:23:01 -070075bool ShaderVariable::operator==(const ShaderVariable &other) const
76{
77 if (type != other.type ||
78 precision != other.precision ||
79 name != other.name ||
80 mappedName != other.mappedName ||
81 arraySize != other.arraySize ||
82 staticUse != other.staticUse ||
83 fields.size() != other.fields.size() ||
84 structName != other.structName)
85 {
86 return false;
87 }
88 for (size_t ii = 0; ii < fields.size(); ++ii)
89 {
90 if (fields[ii] != other.fields[ii])
91 return false;
92 }
93 return true;
94}
95
96bool ShaderVariable::findInfoByMappedName(
97 const std::string &mappedFullName,
98 const ShaderVariable **leafVar, std::string *originalFullName) const
99{
100 ASSERT(leafVar && originalFullName);
101 // There are three cases:
102 // 1) the top variable is of struct type;
103 // 2) the top variable is an array;
104 // 3) otherwise.
105 size_t pos = mappedFullName.find_first_of(".[");
Zhenyao Moed136362014-10-03 13:23:01 -0700106
107 if (pos == std::string::npos)
108 {
109 // Case 3.
110 if (mappedFullName != this->mappedName)
111 return false;
112 *originalFullName = this->name;
113 *leafVar = this;
114 return true;
115 }
116 else
117 {
118 std::string topName = mappedFullName.substr(0, pos);
119 if (topName != this->mappedName)
120 return false;
121 std::string originalName = this->name;
122 std::string remaining;
123 if (mappedFullName[pos] == '[')
124 {
125 // Case 2.
126 size_t closePos = mappedFullName.find_first_of(']');
127 if (closePos < pos || closePos == std::string::npos)
128 return false;
129 // Append '[index]'.
130 originalName += mappedFullName.substr(pos, closePos - pos + 1);
131 if (closePos + 1 == mappedFullName.size())
132 {
133 *originalFullName = originalName;
134 *leafVar = this;
135 return true;
136 }
137 else
138 {
139 // In the form of 'a[0].b', so after ']', '.' is expected.
140 if (mappedFullName[closePos + 1] != '.')
141 return false;
142 remaining = mappedFullName.substr(closePos + 2); // Skip "]."
143 }
144 }
145 else
146 {
147 // Case 1.
148 remaining = mappedFullName.substr(pos + 1); // Skip "."
149 }
150 for (size_t ii = 0; ii < this->fields.size(); ++ii)
151 {
152 const ShaderVariable *fieldVar = NULL;
153 std::string originalFieldName;
154 bool found = fields[ii].findInfoByMappedName(
155 remaining, &fieldVar, &originalFieldName);
156 if (found)
157 {
158 *originalFullName = originalName + "." + originalFieldName;
159 *leafVar = fieldVar;
160 return true;
161 }
162 }
163 return false;
164 }
165}
166
167bool ShaderVariable::isSameVariableAtLinkTime(
168 const ShaderVariable &other, bool matchPrecision) const
169{
170 if (type != other.type)
171 return false;
172 if (matchPrecision && precision != other.precision)
173 return false;
174 if (name != other.name)
175 return false;
176 ASSERT(mappedName == other.mappedName);
177 if (arraySize != other.arraySize)
178 return false;
179 if (fields.size() != other.fields.size())
180 return false;
181 for (size_t ii = 0; ii < fields.size(); ++ii)
182 {
183 if (!fields[ii].isSameVariableAtLinkTime(other.fields[ii],
184 matchPrecision))
185 {
186 return false;
187 }
188 }
189 if (structName != other.structName)
190 return false;
191 return true;
192}
193
Jamie Madill6a729792014-07-18 10:33:14 -0400194Uniform::Uniform()
195{}
196
197Uniform::~Uniform()
198{}
199
200Uniform::Uniform(const Uniform &other)
Jamie Madill42bcf322014-08-25 16:20:46 -0400201 : ShaderVariable(other)
Jamie Madill6a729792014-07-18 10:33:14 -0400202{}
203
204Uniform &Uniform::operator=(const Uniform &other)
205{
206 ShaderVariable::operator=(other);
Jamie Madill6a729792014-07-18 10:33:14 -0400207 return *this;
208}
209
Zhenyao Moed136362014-10-03 13:23:01 -0700210bool Uniform::operator==(const Uniform &other) const
211{
212 return ShaderVariable::operator==(other);
213}
214
215bool Uniform::isSameUniformAtLinkTime(const Uniform &other) const
216{
217 return ShaderVariable::isSameVariableAtLinkTime(other, true);
218}
219
Jamie Madill6a729792014-07-18 10:33:14 -0400220Attribute::Attribute()
221 : location(-1)
222{}
223
224Attribute::~Attribute()
225{}
226
227Attribute::Attribute(const Attribute &other)
228 : ShaderVariable(other),
229 location(other.location)
230{}
231
232Attribute &Attribute::operator=(const Attribute &other)
233{
234 ShaderVariable::operator=(other);
235 location = other.location;
236 return *this;
237}
238
Zhenyao Moed136362014-10-03 13:23:01 -0700239bool Attribute::operator==(const Attribute &other) const
240{
241 return (ShaderVariable::operator==(other) &&
242 location == other.location);
243}
244
Jamie Madill6a729792014-07-18 10:33:14 -0400245InterfaceBlockField::InterfaceBlockField()
Jamie Madilla6f267f2014-08-27 11:44:15 -0400246 : isRowMajorLayout(false)
Jamie Madill6a729792014-07-18 10:33:14 -0400247{}
248
249InterfaceBlockField::~InterfaceBlockField()
250{}
251
252InterfaceBlockField::InterfaceBlockField(const InterfaceBlockField &other)
253 : ShaderVariable(other),
Jamie Madilla6f267f2014-08-27 11:44:15 -0400254 isRowMajorLayout(other.isRowMajorLayout)
Jamie Madill6a729792014-07-18 10:33:14 -0400255{}
256
257InterfaceBlockField &InterfaceBlockField::operator=(const InterfaceBlockField &other)
258{
259 ShaderVariable::operator=(other);
Jamie Madilla6f267f2014-08-27 11:44:15 -0400260 isRowMajorLayout = other.isRowMajorLayout;
Jamie Madill6a729792014-07-18 10:33:14 -0400261 return *this;
262}
263
Zhenyao Moed136362014-10-03 13:23:01 -0700264bool InterfaceBlockField::operator==(const InterfaceBlockField &other) const
265{
266 return (ShaderVariable::operator==(other) &&
267 isRowMajorLayout == other.isRowMajorLayout);
268}
269
270bool InterfaceBlockField::isSameInterfaceBlockFieldAtLinkTime(
271 const InterfaceBlockField &other) const
272{
273 return (ShaderVariable::isSameVariableAtLinkTime(other, true) &&
274 isRowMajorLayout == other.isRowMajorLayout);
275}
276
Jamie Madill6a729792014-07-18 10:33:14 -0400277Varying::Varying()
Jamie Madill42bcf322014-08-25 16:20:46 -0400278 : interpolation(INTERPOLATION_SMOOTH),
279 isInvariant(false)
Jamie Madill6a729792014-07-18 10:33:14 -0400280{}
281
282Varying::~Varying()
283{}
284
285Varying::Varying(const Varying &other)
286 : ShaderVariable(other),
287 interpolation(other.interpolation),
Jamie Madill42bcf322014-08-25 16:20:46 -0400288 isInvariant(other.isInvariant)
Jamie Madill6a729792014-07-18 10:33:14 -0400289{}
290
291Varying &Varying::operator=(const Varying &other)
292{
293 ShaderVariable::operator=(other);
294 interpolation = other.interpolation;
Jamie Madill42bcf322014-08-25 16:20:46 -0400295 isInvariant = other.isInvariant;
Jamie Madill6a729792014-07-18 10:33:14 -0400296 return *this;
297}
298
Zhenyao Moed136362014-10-03 13:23:01 -0700299bool Varying::operator==(const Varying &other) const
300{
301 return (ShaderVariable::operator==(other) &&
302 interpolation == other.interpolation &&
303 isInvariant == other.isInvariant);
304}
305
Jamie Madill9e64edc2015-05-07 14:08:06 +0000306bool Varying::isSameVaryingAtLinkTime(const Varying &other) const
Zhenyao Moed136362014-10-03 13:23:01 -0700307{
Olli Etuaho37ad4742015-04-27 13:18:50 +0300308 return isSameVaryingAtLinkTime(other, 100);
309}
310
311bool Varying::isSameVaryingAtLinkTime(const Varying &other, int shaderVersion) const
312{
Zhenyao Moed136362014-10-03 13:23:01 -0700313 return (ShaderVariable::isSameVariableAtLinkTime(other, false) &&
314 interpolation == other.interpolation &&
Olli Etuaho37ad4742015-04-27 13:18:50 +0300315 (shaderVersion >= 300 || isInvariant == other.isInvariant));
Zhenyao Moed136362014-10-03 13:23:01 -0700316}
317
Jamie Madill6a729792014-07-18 10:33:14 -0400318InterfaceBlock::InterfaceBlock()
319 : arraySize(0),
320 layout(BLOCKLAYOUT_PACKED),
321 isRowMajorLayout(false),
322 staticUse(false)
323{}
324
325InterfaceBlock::~InterfaceBlock()
326{}
327
328InterfaceBlock::InterfaceBlock(const InterfaceBlock &other)
329 : name(other.name),
330 mappedName(other.mappedName),
Jamie Madill42bcf322014-08-25 16:20:46 -0400331 instanceName(other.instanceName),
Jamie Madill6a729792014-07-18 10:33:14 -0400332 arraySize(other.arraySize),
333 layout(other.layout),
334 isRowMajorLayout(other.isRowMajorLayout),
335 staticUse(other.staticUse),
336 fields(other.fields)
337{}
338
339InterfaceBlock &InterfaceBlock::operator=(const InterfaceBlock &other)
340{
341 name = other.name;
342 mappedName = other.mappedName;
Jamie Madill42bcf322014-08-25 16:20:46 -0400343 instanceName = other.instanceName;
Jamie Madill6a729792014-07-18 10:33:14 -0400344 arraySize = other.arraySize;
345 layout = other.layout;
346 isRowMajorLayout = other.isRowMajorLayout;
347 staticUse = other.staticUse;
348 fields = other.fields;
349 return *this;
350}
351
352}