1 //
2 // Copyright 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 //
6 // TypeTracking_test.cpp:
7 // Test for tracking types resulting from math operations, including their
8 // precision.
9 //
10
11 #include "GLSLANG/ShaderLang.h"
12 #include "angle_gl.h"
13 #include "compiler/translator/TranslatorESSL.h"
14 #include "gtest/gtest.h"
15
16 using namespace sh;
17
18 class TypeTrackingTest : public testing::Test
19 {
20 public:
TypeTrackingTest()21 TypeTrackingTest() {}
22
23 protected:
SetUp()24 void SetUp() override
25 {
26 ShBuiltInResources resources;
27 InitBuiltInResources(&resources);
28 resources.FragmentPrecisionHigh = 1;
29
30 mTranslator = new TranslatorESSL(GL_FRAGMENT_SHADER, SH_GLES3_1_SPEC);
31 ASSERT_TRUE(mTranslator->Init(resources));
32 }
33
TearDown()34 void TearDown() override { delete mTranslator; }
35
compile(const std::string & shaderString)36 void compile(const std::string &shaderString)
37 {
38 const char *shaderStrings[] = {shaderString.c_str()};
39 bool compilationSuccess = mTranslator->compile(shaderStrings, 1, SH_INTERMEDIATE_TREE);
40 TInfoSink &infoSink = mTranslator->getInfoSink();
41 mInfoLog = RemoveSymbolIdsFromInfoLog(infoSink.info.c_str());
42 if (!compilationSuccess)
43 FAIL() << "Shader compilation failed " << mInfoLog;
44 }
45
foundErrorInIntermediateTree() const46 bool foundErrorInIntermediateTree() const { return foundInIntermediateTree("ERROR:"); }
47
foundInIntermediateTree(const char * stringToFind) const48 bool foundInIntermediateTree(const char *stringToFind) const
49 {
50 return mInfoLog.find(stringToFind) != std::string::npos;
51 }
52
53 private:
54 // Remove symbol ids from info log - the tests don't care about them.
RemoveSymbolIdsFromInfoLog(const char * infoLog)55 static std::string RemoveSymbolIdsFromInfoLog(const char *infoLog)
56 {
57 std::string filteredLog(infoLog);
58 size_t idPrefixPos = 0u;
59 do
60 {
61 idPrefixPos = filteredLog.find(" (symbol id");
62 if (idPrefixPos != std::string::npos)
63 {
64 size_t idSuffixPos = filteredLog.find(")", idPrefixPos);
65 filteredLog.erase(idPrefixPos, idSuffixPos - idPrefixPos + 1u);
66 }
67 } while (idPrefixPos != std::string::npos);
68 return filteredLog;
69 }
70
71 TranslatorESSL *mTranslator;
72 std::string mInfoLog;
73 };
74
TEST_F(TypeTrackingTest,FunctionPrototype)75 TEST_F(TypeTrackingTest, FunctionPrototype)
76 {
77 const std::string &shaderString =
78 "precision mediump float;\n"
79 "float fun(float a);\n"
80 "uniform float f;\n"
81 "void main() {\n"
82 " float ff = fun(f);\n"
83 " gl_FragColor = vec4(ff);\n"
84 "}\n"
85 "float fun(float a) {\n"
86 " return a * 2.0;\n"
87 "}\n";
88 compile(shaderString);
89 ASSERT_FALSE(foundErrorInIntermediateTree());
90 ASSERT_TRUE(foundInIntermediateTree("Function Prototype: fun"));
91 }
92
TEST_F(TypeTrackingTest,BuiltInFunctionResultPrecision)93 TEST_F(TypeTrackingTest, BuiltInFunctionResultPrecision)
94 {
95 const std::string &shaderString =
96 "precision mediump float;\n"
97 "uniform float f;\n"
98 "void main() {\n"
99 " float ff = sin(f);\n"
100 " gl_FragColor = vec4(ff);\n"
101 "}\n";
102 compile(shaderString);
103 ASSERT_FALSE(foundErrorInIntermediateTree());
104 ASSERT_TRUE(foundInIntermediateTree("sin (mediump float)"));
105 }
106
TEST_F(TypeTrackingTest,BinaryMathResultPrecision)107 TEST_F(TypeTrackingTest, BinaryMathResultPrecision)
108 {
109 const std::string &shaderString =
110 "precision mediump float;\n"
111 "uniform float f;\n"
112 "void main() {\n"
113 " float ff = f * 0.5;\n"
114 " gl_FragColor = vec4(ff);\n"
115 "}\n";
116 compile(shaderString);
117 ASSERT_FALSE(foundErrorInIntermediateTree());
118 ASSERT_TRUE(foundInIntermediateTree("multiply (mediump float)"));
119 }
120
TEST_F(TypeTrackingTest,BuiltInVecFunctionResultTypeAndPrecision)121 TEST_F(TypeTrackingTest, BuiltInVecFunctionResultTypeAndPrecision)
122 {
123 const std::string &shaderString =
124 "precision mediump float;\n"
125 "uniform vec2 a;\n"
126 "void main() {\n"
127 " float b = length(a);\n"
128 " float c = dot(a, vec2(0.5));\n"
129 " float d = distance(vec2(0.5), a);\n"
130 " gl_FragColor = vec4(b, c, d, 1.0);\n"
131 "}\n";
132 compile(shaderString);
133 ASSERT_FALSE(foundErrorInIntermediateTree());
134 ASSERT_TRUE(foundInIntermediateTree("length (mediump float)"));
135 ASSERT_TRUE(foundInIntermediateTree("dot product (mediump float)"));
136 ASSERT_TRUE(foundInIntermediateTree("distance (mediump float)"));
137 }
138
TEST_F(TypeTrackingTest,BuiltInMatFunctionResultTypeAndPrecision)139 TEST_F(TypeTrackingTest, BuiltInMatFunctionResultTypeAndPrecision)
140 {
141 const std::string &shaderString =
142 "#version 300 es\n"
143 "precision mediump float;\n"
144 "out vec4 my_FragColor;\n"
145 "uniform mat4 m;\n"
146 "void main() {\n"
147 " mat3x2 tmp32 = mat3x2(m);\n"
148 " mat2x3 tmp23 = mat2x3(m);\n"
149 " mat4x2 tmp42 = mat4x2(m);\n"
150 " mat2x4 tmp24 = mat2x4(m);\n"
151 " mat4x3 tmp43 = mat4x3(m);\n"
152 " mat3x4 tmp34 = mat3x4(m);\n"
153 " my_FragColor = vec4(tmp32[2][1] * tmp23[1][2], tmp42[3][1] * tmp24[1][3], tmp43[3][2] "
154 "* tmp34[2][3], 1.0);\n"
155 "}\n";
156 compile(shaderString);
157 ASSERT_FALSE(foundErrorInIntermediateTree());
158 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 2X3 matrix of float)"));
159 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 3X2 matrix of float)"));
160 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 2X4 matrix of float)"));
161 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 4X2 matrix of float)"));
162 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 3X4 matrix of float)"));
163 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 4X3 matrix of float)"));
164 }
165
TEST_F(TypeTrackingTest,BuiltInFunctionChoosesHigherPrecision)166 TEST_F(TypeTrackingTest, BuiltInFunctionChoosesHigherPrecision)
167 {
168 const std::string &shaderString =
169 "precision lowp float;\n"
170 "uniform mediump vec2 a;\n"
171 "uniform lowp vec2 b;\n"
172 "void main() {\n"
173 " float c = dot(a, b);\n"
174 " float d = distance(b, a);\n"
175 " gl_FragColor = vec4(c, d, 0.0, 1.0);\n"
176 "}\n";
177 compile(shaderString);
178 ASSERT_FALSE(foundErrorInIntermediateTree());
179 ASSERT_TRUE(foundInIntermediateTree("dot product (mediump float)"));
180 ASSERT_TRUE(foundInIntermediateTree("distance (mediump float)"));
181 }
182
TEST_F(TypeTrackingTest,BuiltInBoolFunctionResultType)183 TEST_F(TypeTrackingTest, BuiltInBoolFunctionResultType)
184 {
185 const std::string &shaderString =
186 "uniform bvec4 bees;\n"
187 "void main() {\n"
188 " bool b = any(bees);\n"
189 " bool c = all(bees);\n"
190 " bvec4 d = not(bees);\n"
191 " gl_FragColor = vec4(b ? 1.0 : 0.0, c ? 1.0 : 0.0, d.x ? 1.0 : 0.0, 1.0);\n"
192 "}\n";
193 compile(shaderString);
194 ASSERT_FALSE(foundErrorInIntermediateTree());
195 ASSERT_TRUE(foundInIntermediateTree("any (bool)"));
196 ASSERT_TRUE(foundInIntermediateTree("all (bool)"));
197 ASSERT_TRUE(foundInIntermediateTree("component-wise not (4-component vector of bool)"));
198 }
199
TEST_F(TypeTrackingTest,BuiltInVecToBoolFunctionResultType)200 TEST_F(TypeTrackingTest, BuiltInVecToBoolFunctionResultType)
201 {
202 const std::string &shaderString =
203 "precision mediump float;\n"
204 "uniform vec2 apples;\n"
205 "uniform vec2 oranges;\n"
206 "uniform ivec2 foo;\n"
207 "uniform ivec2 bar;\n"
208 "void main() {\n"
209 " bvec2 a = lessThan(apples, oranges);\n"
210 " bvec2 b = greaterThan(foo, bar);\n"
211 " gl_FragColor = vec4(any(a) ? 1.0 : 0.0, any(b) ? 1.0 : 0.0, 0.0, 1.0);\n"
212 "}\n";
213 compile(shaderString);
214 ASSERT_FALSE(foundErrorInIntermediateTree());
215 ASSERT_TRUE(foundInIntermediateTree("component-wise less than (2-component vector of bool)"));
216 ASSERT_TRUE(
217 foundInIntermediateTree("component-wise greater than (2-component vector of bool)"));
218 }
219
TEST_F(TypeTrackingTest,Texture2DResultTypeAndPrecision)220 TEST_F(TypeTrackingTest, Texture2DResultTypeAndPrecision)
221 {
222 // ESSL spec section 4.5.3: sampler2D and samplerCube are lowp by default
223 // ESSL spec section 8: For the texture functions, the precision of the return type matches the
224 // precision of the sampler type.
225 const std::string &shaderString =
226 "precision mediump float;\n"
227 "uniform sampler2D s;\n"
228 "uniform vec2 a;\n"
229 "void main() {\n"
230 " vec4 c = texture2D(s, a);\n"
231 " gl_FragColor = c;\n"
232 "}\n";
233 compile(shaderString);
234 ASSERT_FALSE(foundErrorInIntermediateTree());
235 ASSERT_TRUE(foundInIntermediateTree("texture2D (lowp 4-component vector of float)"));
236 }
237
TEST_F(TypeTrackingTest,TextureCubeResultTypeAndPrecision)238 TEST_F(TypeTrackingTest, TextureCubeResultTypeAndPrecision)
239 {
240 // ESSL spec section 4.5.3: sampler2D and samplerCube are lowp by default
241 // ESSL spec section 8: For the texture functions, the precision of the return type matches the
242 // precision of the sampler type.
243 const std::string &shaderString =
244 "precision mediump float;\n"
245 "uniform samplerCube sc;\n"
246 "uniform vec3 a;\n"
247 "void main() {\n"
248 " vec4 c = textureCube(sc, a);\n"
249 " gl_FragColor = c;\n"
250 "}\n";
251 compile(shaderString);
252 ASSERT_FALSE(foundErrorInIntermediateTree());
253 ASSERT_TRUE(foundInIntermediateTree("textureCube (lowp 4-component vector of float)"));
254 }
255
TEST_F(TypeTrackingTest,TextureSizeResultTypeAndPrecision)256 TEST_F(TypeTrackingTest, TextureSizeResultTypeAndPrecision)
257 {
258 // ESSL 3.0 spec section 8: textureSize has predefined precision highp
259 const std::string &shaderString =
260 "#version 300 es\n"
261 "precision mediump float;\n"
262 "out vec4 my_FragColor;\n"
263 "uniform sampler2D s;\n"
264 "void main() {\n"
265 " ivec2 size = textureSize(s, 0);\n"
266 " if (size.x > 100) {\n"
267 " my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
268 " } else {\n"
269 " my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
270 " }\n"
271 "}\n";
272 compile(shaderString);
273 ASSERT_FALSE(foundErrorInIntermediateTree());
274 ASSERT_TRUE(foundInIntermediateTree("textureSize (highp 2-component vector of int)"));
275 }
276
TEST_F(TypeTrackingTest,BuiltInConstructorResultTypeAndPrecision)277 TEST_F(TypeTrackingTest, BuiltInConstructorResultTypeAndPrecision)
278 {
279 const std::string &shaderString =
280 "precision mediump float;\n"
281 "uniform float u1;\n"
282 "uniform float u2;\n"
283 "uniform float u3;\n"
284 "uniform float u4;\n"
285 "void main() {\n"
286 " vec4 a = vec4(u1, u2, u3, u4);\n"
287 " gl_FragColor = a;\n"
288 "}\n";
289 compile(shaderString);
290 ASSERT_FALSE(foundErrorInIntermediateTree());
291 ASSERT_TRUE(foundInIntermediateTree("Construct (mediump 4-component vector of float)"));
292 }
293
TEST_F(TypeTrackingTest,StructConstructorResultNoPrecision)294 TEST_F(TypeTrackingTest, StructConstructorResultNoPrecision)
295 {
296 const std::string &shaderString =
297 "precision mediump float;\n"
298 "uniform vec4 u1;\n"
299 "uniform vec4 u2;\n"
300 "struct S { highp vec4 a; highp vec4 b; };\n"
301 "void main() {\n"
302 " S s = S(u1, u2);\n"
303 " gl_FragColor = s.a;\n"
304 "}\n";
305 compile(shaderString);
306 ASSERT_FALSE(foundErrorInIntermediateTree());
307 ASSERT_TRUE(foundInIntermediateTree("Construct (structure)"));
308 }
309
TEST_F(TypeTrackingTest,PackResultTypeAndPrecision)310 TEST_F(TypeTrackingTest, PackResultTypeAndPrecision)
311 {
312 // ESSL 3.0 spec section 8.4: pack functions have predefined precision highp
313 const std::string &shaderString =
314 "#version 300 es\n"
315 "precision mediump float;\n"
316 "precision mediump int;\n"
317 "uniform vec2 uv;\n"
318 "out vec4 my_FragColor;\n"
319 "void main() {\n"
320 " uint u0 = packSnorm2x16(uv);\n"
321 " uint u1 = packUnorm2x16(uv);\n"
322 " uint u2 = packHalf2x16(uv);\n"
323 " if (u0 + u1 + u2 > 100u) {\n"
324 " my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
325 " } else {\n"
326 " my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
327 " }\n"
328 "}\n";
329 compile(shaderString);
330 ASSERT_FALSE(foundErrorInIntermediateTree());
331 ASSERT_TRUE(foundInIntermediateTree("packSnorm2x16 (highp uint)"));
332 ASSERT_TRUE(foundInIntermediateTree("packUnorm2x16 (highp uint)"));
333 ASSERT_TRUE(foundInIntermediateTree("packHalf2x16 (highp uint)"));
334 }
335
TEST_F(TypeTrackingTest,UnpackNormResultTypeAndPrecision)336 TEST_F(TypeTrackingTest, UnpackNormResultTypeAndPrecision)
337 {
338 // ESSL 3.0 spec section 8.4: unpack(S/U)norm2x16 has predefined precision highp
339 const std::string &shaderString =
340 "#version 300 es\n"
341 "precision mediump float;\n"
342 "precision mediump int;\n"
343 "uniform uint uu;\n"
344 "out vec4 my_FragColor;\n"
345 "void main() {\n"
346 " vec2 v0 = unpackSnorm2x16(uu);\n"
347 " vec2 v1 = unpackUnorm2x16(uu);\n"
348 " if (v0.x * v1.x > 1.0) {\n"
349 " my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
350 " } else {\n"
351 " my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
352 " }\n"
353 "}\n";
354 compile(shaderString);
355 ASSERT_FALSE(foundErrorInIntermediateTree());
356 ASSERT_TRUE(foundInIntermediateTree("unpackSnorm2x16 (highp 2-component vector of float)"));
357 ASSERT_TRUE(foundInIntermediateTree("unpackUnorm2x16 (highp 2-component vector of float)"));
358 }
359
TEST_F(TypeTrackingTest,UnpackHalfResultTypeAndPrecision)360 TEST_F(TypeTrackingTest, UnpackHalfResultTypeAndPrecision)
361 {
362 // ESSL 3.0 spec section 8.4: unpackHalf2x16 has predefined precision mediump
363 const std::string &shaderString =
364 "#version 300 es\n"
365 "precision highp float;\n"
366 "precision highp int;\n"
367 "uniform uint uu;\n"
368 "out vec4 my_FragColor;\n"
369 "void main() {\n"
370 " vec2 v = unpackHalf2x16(uu);\n"
371 " if (v.x > 1.0) {\n"
372 " my_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
373 " } else {\n"
374 " my_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
375 " }\n"
376 "}\n";
377 compile(shaderString);
378 ASSERT_FALSE(foundErrorInIntermediateTree());
379 ASSERT_TRUE(foundInIntermediateTree("unpackHalf2x16 (mediump 2-component vector of float)"));
380 }
381
TEST_F(TypeTrackingTest,BuiltInAbsSignFunctionFloatResultTypeAndPrecision)382 TEST_F(TypeTrackingTest, BuiltInAbsSignFunctionFloatResultTypeAndPrecision)
383 {
384 const std::string &shaderString =
385 "precision mediump float;\n"
386 "uniform float fval1;\n"
387 "void main() {\n"
388 " float fval2 = abs(fval1);\n"
389 " float fval3 = sign(fval1);\n"
390 " gl_FragColor = vec4(fval1, fval2, fval3, 1.0); \n"
391 "}\n";
392 compile(shaderString);
393 ASSERT_FALSE(foundErrorInIntermediateTree());
394 ASSERT_TRUE(foundInIntermediateTree("abs (mediump float)"));
395 ASSERT_TRUE(foundInIntermediateTree("sign (mediump float)"));
396 }
397
TEST_F(TypeTrackingTest,BuiltInAbsSignFunctionIntResultTypeAndPrecision)398 TEST_F(TypeTrackingTest, BuiltInAbsSignFunctionIntResultTypeAndPrecision)
399 {
400 const std::string &shaderString =
401 "#version 300 es\n"
402 "precision mediump float;\n"
403 "precision mediump int;\n"
404 "uniform int ival1;\n"
405 "out vec4 my_FragColor;\n"
406 "void main() {\n"
407 " int ival2 = abs(ival1);\n"
408 " int ival3 = sign(ival1);\n"
409 " my_FragColor = vec4(ival2, ival3, 0, 1); \n"
410 "}\n";
411 compile(shaderString);
412 ASSERT_FALSE(foundErrorInIntermediateTree());
413 ASSERT_TRUE(foundInIntermediateTree("abs (mediump int)"));
414 ASSERT_TRUE(foundInIntermediateTree("sign (mediump int)"));
415 }
416
TEST_F(TypeTrackingTest,BuiltInFloatBitsToIntResultTypeAndPrecision)417 TEST_F(TypeTrackingTest, BuiltInFloatBitsToIntResultTypeAndPrecision)
418 {
419 // ESSL 3.00 section 8.3: floatBitsTo(U)int returns a highp value.
420 const std::string &shaderString =
421 "#version 300 es\n"
422 "precision mediump float;\n"
423 "precision mediump int;\n"
424 "uniform float f;\n"
425 "out vec4 my_FragColor;\n"
426 "void main() {\n"
427 " int i = floatBitsToInt(f);\n"
428 " uint u = floatBitsToUint(f);\n"
429 " my_FragColor = vec4(i, int(u), 0, 1); \n"
430 "}\n";
431 compile(shaderString);
432 ASSERT_FALSE(foundErrorInIntermediateTree());
433 ASSERT_TRUE(foundInIntermediateTree("floatBitsToInt (highp int)"));
434 ASSERT_TRUE(foundInIntermediateTree("floatBitsToUint (highp uint)"));
435 }
436
TEST_F(TypeTrackingTest,BuiltInIntBitsToFloatResultTypeAndPrecision)437 TEST_F(TypeTrackingTest, BuiltInIntBitsToFloatResultTypeAndPrecision)
438 {
439 // ESSL 3.00 section 8.3: (u)intBitsToFloat returns a highp value.
440 const std::string &shaderString =
441 "#version 300 es\n"
442 "precision mediump float;\n"
443 "precision mediump int;\n"
444 "uniform int i;\n"
445 "uniform uint u;\n"
446 "out vec4 my_FragColor;\n"
447 "void main() {\n"
448 " float f1 = intBitsToFloat(i);\n"
449 " float f2 = uintBitsToFloat(u);\n"
450 " my_FragColor = vec4(f1, f2, 0.0, 1.0); \n"
451 "}\n";
452 compile(shaderString);
453 ASSERT_FALSE(foundErrorInIntermediateTree());
454 ASSERT_TRUE(foundInIntermediateTree("intBitsToFloat (highp float)"));
455 ASSERT_TRUE(foundInIntermediateTree("uintBitsToFloat (highp float)"));
456 }
457
458 // Test that bitfieldExtract returns a precision consistent with its "value" parameter.
TEST_F(TypeTrackingTest,BuiltInBitfieldExtractResultTypeAndPrecision)459 TEST_F(TypeTrackingTest, BuiltInBitfieldExtractResultTypeAndPrecision)
460 {
461 const std::string &shaderString =
462 "#version 310 es\n"
463 "precision mediump float;\n"
464 "uniform mediump int i;\n"
465 "uniform highp uint u;\n"
466 "uniform lowp int offset;\n"
467 "uniform highp int bits;\n"
468 "out vec4 my_FragColor;\n"
469 "void main() {\n"
470 " lowp int i2 = bitfieldExtract(i, offset, bits);\n"
471 " lowp uint u2 = bitfieldExtract(u, offset, bits);\n"
472 " my_FragColor = vec4(i2, u2, 0.0, 1.0); \n"
473 "}\n";
474 compile(shaderString);
475 ASSERT_FALSE(foundErrorInIntermediateTree());
476 ASSERT_TRUE(foundInIntermediateTree("bitfieldExtract (mediump int)"));
477 ASSERT_TRUE(foundInIntermediateTree("bitfieldExtract (highp uint)"));
478 }
479
480 // Test that signed bitfieldInsert returns a precision consistent with its "base/insert" parameters.
TEST_F(TypeTrackingTest,BuiltInBitfieldInsertResultTypeAndPrecision)481 TEST_F(TypeTrackingTest, BuiltInBitfieldInsertResultTypeAndPrecision)
482 {
483 const std::string &shaderString =
484 "#version 310 es\n"
485 "precision mediump float;\n"
486 "uniform lowp int iBase;\n"
487 "uniform mediump int iInsert;\n"
488 "uniform highp uint uBase;\n"
489 "uniform mediump uint uInsert;\n"
490 "uniform highp int offset;\n"
491 "uniform highp int bits;\n"
492 "out vec4 my_FragColor;\n"
493 "void main() {\n"
494 " lowp int i = bitfieldInsert(iBase, iInsert, offset, bits);\n"
495 " lowp uint u = bitfieldInsert(uBase, uInsert, offset, bits);\n"
496 " my_FragColor = vec4(i, u, 0.0, 1.0); \n"
497 "}\n";
498 compile(shaderString);
499 ASSERT_FALSE(foundErrorInIntermediateTree());
500 ASSERT_TRUE(foundInIntermediateTree("bitfieldInsert (mediump int)"));
501 ASSERT_TRUE(foundInIntermediateTree("bitfieldInsert (highp uint)"));
502 }
503
504 // Test that signed bitfieldInsert returns a precision consistent with its "base/insert" parameters.
505 // Another variation on parameter precisions.
TEST_F(TypeTrackingTest,BuiltInBitfieldInsertResultTypeAndPrecision2)506 TEST_F(TypeTrackingTest, BuiltInBitfieldInsertResultTypeAndPrecision2)
507 {
508 const std::string &shaderString =
509 "#version 310 es\n"
510 "precision mediump float;\n"
511 "uniform highp int iBase;\n"
512 "uniform mediump int iInsert;\n"
513 "uniform lowp uint uBase;\n"
514 "uniform mediump uint uInsert;\n"
515 "uniform lowp int offset;\n"
516 "uniform lowp int bits;\n"
517 "out vec4 my_FragColor;\n"
518 "void main() {\n"
519 " lowp int i = bitfieldInsert(iBase, iInsert, offset, bits);\n"
520 " lowp uint u = bitfieldInsert(uBase, uInsert, offset, bits);\n"
521 " my_FragColor = vec4(i, u, 0.0, 1.0); \n"
522 "}\n";
523 compile(shaderString);
524 ASSERT_FALSE(foundErrorInIntermediateTree());
525 ASSERT_TRUE(foundInIntermediateTree("bitfieldInsert (highp int)"));
526 ASSERT_TRUE(foundInIntermediateTree("bitfieldInsert (mediump uint)"));
527 }
528
529 // Test that bitfieldReverse always results in highp precision.
TEST_F(TypeTrackingTest,BuiltInBitfieldReversePrecision)530 TEST_F(TypeTrackingTest, BuiltInBitfieldReversePrecision)
531 {
532 const std::string &shaderString =
533 "#version 310 es\n"
534 "precision mediump float;\n"
535 "uniform lowp uint u;\n"
536 "uniform mediump int i;\n"
537 "out vec4 my_FragColor;\n"
538 "void main() {\n"
539 " lowp uint u2 = bitfieldReverse(u);\n"
540 " lowp int i2 = bitfieldReverse(i);\n"
541 " my_FragColor = vec4(u2, i2, 0.0, 1.0); \n"
542 "}\n";
543 compile(shaderString);
544 ASSERT_FALSE(foundErrorInIntermediateTree());
545 ASSERT_TRUE(foundInIntermediateTree("bitfieldReverse (highp uint)"));
546 ASSERT_TRUE(foundInIntermediateTree("bitfieldReverse (highp int)"));
547 }
548
549 // Test that bitCount always results in lowp precision integer.
TEST_F(TypeTrackingTest,BuiltInBitCountTypeAndPrecision)550 TEST_F(TypeTrackingTest, BuiltInBitCountTypeAndPrecision)
551 {
552 const std::string &shaderString =
553 "#version 310 es\n"
554 "precision mediump float;\n"
555 "uniform highp uint u;\n"
556 "uniform mediump int i;\n"
557 "out vec4 my_FragColor;\n"
558 "void main() {\n"
559 " highp int count1 = bitCount(u);\n"
560 " highp int count2 = bitCount(i);\n"
561 " my_FragColor = vec4(count1, count2, 0.0, 1.0); \n"
562 "}\n";
563 compile(shaderString);
564 ASSERT_FALSE(foundErrorInIntermediateTree());
565 ASSERT_TRUE(foundInIntermediateTree("bitCount (lowp int)"));
566 ASSERT_FALSE(foundInIntermediateTree("bitCount (lowp uint)"));
567 }
568
569 // Test that findLSB always results in a lowp precision integer.
TEST_F(TypeTrackingTest,BuiltInFindLSBTypeAndPrecision)570 TEST_F(TypeTrackingTest, BuiltInFindLSBTypeAndPrecision)
571 {
572 const std::string &shaderString =
573 "#version 310 es\n"
574 "precision mediump float;\n"
575 "uniform highp uint u;\n"
576 "uniform mediump int i;\n"
577 "out vec4 my_FragColor;\n"
578 "void main() {\n"
579 " highp int index1 = findLSB(u);\n"
580 " highp int index2 = findLSB(i);\n"
581 " my_FragColor = vec4(index1, index2, 0.0, 1.0); \n"
582 "}\n";
583 compile(shaderString);
584 ASSERT_FALSE(foundErrorInIntermediateTree());
585 ASSERT_TRUE(foundInIntermediateTree("findLSB (lowp int)"));
586 ASSERT_FALSE(foundInIntermediateTree("findLSB (lowp uint)"));
587 }
588
589 // Test that findMSB always results in a lowp precision integer.
TEST_F(TypeTrackingTest,BuiltInFindMSBTypeAndPrecision)590 TEST_F(TypeTrackingTest, BuiltInFindMSBTypeAndPrecision)
591 {
592 const std::string &shaderString =
593 "#version 310 es\n"
594 "precision mediump float;\n"
595 "uniform highp uint u;\n"
596 "uniform mediump int i;\n"
597 "out vec4 my_FragColor;\n"
598 "void main() {\n"
599 " highp int index1 = findMSB(u);\n"
600 " highp int index2 = findMSB(i);\n"
601 " my_FragColor = vec4(index1, index2, 0.0, 1.0); \n"
602 "}\n";
603 compile(shaderString);
604 ASSERT_FALSE(foundErrorInIntermediateTree());
605 ASSERT_TRUE(foundInIntermediateTree("findMSB (lowp int)"));
606 ASSERT_FALSE(foundInIntermediateTree("findMSB (lowp uint)"));
607 }
608
609 // Test that uaddCarry always results in highp precision.
TEST_F(TypeTrackingTest,BuiltInUaddCarryPrecision)610 TEST_F(TypeTrackingTest, BuiltInUaddCarryPrecision)
611 {
612 const std::string &shaderString =
613 "#version 310 es\n"
614 "precision mediump float;\n"
615 "uniform mediump uvec2 x;\n"
616 "uniform mediump uvec2 y;\n"
617 "out vec4 my_FragColor;\n"
618 "void main() {\n"
619 " lowp uvec2 carry;\n"
620 " mediump uvec2 result = uaddCarry(x, y, carry);\n"
621 " my_FragColor = vec4(result.x, carry.y, 0.0, 1.0); \n"
622 "}\n";
623 compile(shaderString);
624 ASSERT_FALSE(foundErrorInIntermediateTree());
625 ASSERT_TRUE(foundInIntermediateTree("uaddCarry (highp 2-component vector of uint)"));
626 }
627
628 // Test that usubBorrow always results in highp precision.
TEST_F(TypeTrackingTest,BuiltInUsubBorrowPrecision)629 TEST_F(TypeTrackingTest, BuiltInUsubBorrowPrecision)
630 {
631 const std::string &shaderString =
632 "#version 310 es\n"
633 "precision mediump float;\n"
634 "uniform mediump uvec2 x;\n"
635 "uniform mediump uvec2 y;\n"
636 "out vec4 my_FragColor;\n"
637 "void main() {\n"
638 " lowp uvec2 borrow;\n"
639 " mediump uvec2 result = usubBorrow(x, y, borrow);\n"
640 " my_FragColor = vec4(result.x, borrow.y, 0.0, 1.0); \n"
641 "}\n";
642 compile(shaderString);
643 ASSERT_FALSE(foundErrorInIntermediateTree());
644 ASSERT_TRUE(foundInIntermediateTree("usubBorrow (highp 2-component vector of uint)"));
645 }
646