blob: da7f590c098146224fd0939eeb7fff1ce615f266 [file] [log] [blame]
Jamie Madill55def582015-05-04 11:24:57 -04001//
2// Copyright 2015 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
Jamie Madill96509e42014-05-29 14:33:27 -04007#include "ANGLETest.h"
8
Jamie Madill55def582015-05-04 11:24:57 -04009#include "libANGLE/Context.h"
10#include "libANGLE/Program.h"
11
Austin Kinross18b931d2014-09-29 12:58:31 -070012// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
Geoff Lang0d3683c2014-10-23 11:08:16 -040013ANGLE_TYPED_TEST_CASE(GLSLTest, ES2_D3D9, ES2_D3D11);
Austin Kinross18b931d2014-09-29 12:58:31 -070014
15template<typename T>
Jamie Madill2bf8b372014-06-16 17:18:51 -040016class GLSLTest : public ANGLETest
Jamie Madill96509e42014-05-29 14:33:27 -040017{
18protected:
Geoff Lang0d3683c2014-10-23 11:08:16 -040019 GLSLTest() : ANGLETest(T::GetGlesMajorVersion(), T::GetPlatform())
Jamie Madill96509e42014-05-29 14:33:27 -040020 {
21 setWindowWidth(128);
22 setWindowHeight(128);
23 setConfigRedBits(8);
24 setConfigGreenBits(8);
25 setConfigBlueBits(8);
26 setConfigAlphaBits(8);
27 }
Jamie Madillbfa91f42014-06-05 15:45:18 -040028
29 virtual void SetUp()
30 {
31 ANGLETest::SetUp();
32
Jamie Madill2bf8b372014-06-16 17:18:51 -040033 mSimpleVSSource = SHADER_SOURCE
Jamie Madillbfa91f42014-06-05 15:45:18 -040034 (
35 attribute vec4 inputAttribute;
36 void main()
37 {
38 gl_Position = inputAttribute;
39 }
40 );
41 }
42
Austin Kinrossaf875522014-08-25 21:06:07 -070043 std::string GenerateVaryingType(GLint vectorSize)
44 {
45 char varyingType[10];
46
47 if (vectorSize == 1)
48 {
49 sprintf(varyingType, "float");
50 }
51 else
52 {
53 sprintf(varyingType, "vec%d", vectorSize);
54 }
55
56 return std::string(varyingType);
57 }
58
59 std::string GenerateVectorVaryingDeclaration(GLint vectorSize, GLint arraySize, GLint id)
60 {
61 char buff[100];
62
63 if (arraySize == 1)
64 {
65 sprintf(buff, "varying %s v%d;\n", GenerateVaryingType(vectorSize).c_str(), id);
66 }
67 else
68 {
69 sprintf(buff, "varying %s v%d[%d];\n", GenerateVaryingType(vectorSize).c_str(), id, arraySize);
70 }
71
72 return std::string(buff);
73 }
74
75 std::string GenerateVectorVaryingSettingCode(GLint vectorSize, GLint arraySize, GLint id)
76 {
77 std::string returnString;
78 char buff[100];
79
80 if (arraySize == 1)
81 {
82 sprintf(buff, "\t v%d = %s(1.0);\n", id, GenerateVaryingType(vectorSize).c_str());
83 returnString += buff;
84 }
85 else
86 {
87 for (int i = 0; i < arraySize; i++)
88 {
89 sprintf(buff, "\t v%d[%d] = %s(1.0);\n", id, i, GenerateVaryingType(vectorSize).c_str());
90 returnString += buff;
91 }
92 }
93
94 return returnString;
95 }
96
97 std::string GenerateVectorVaryingUseCode(GLint arraySize, GLint id)
98 {
99 if (arraySize == 1)
100 {
101 char buff[100];
102 sprintf(buff, "v%d + ", id);
103 return std::string(buff);
104 }
105 else
106 {
107 std::string returnString;
108 for (int i = 0; i < arraySize; i++)
109 {
110 char buff[100];
111 sprintf(buff, "v%d[%d] + ", id, i);
112 returnString += buff;
113 }
114 return returnString;
115 }
116 }
117
Austin Kinross8b695ee2015-03-12 13:12:20 -0700118 void GenerateGLSLWithVaryings(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
119 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize,
120 std::string* fragmentShader, std::string* vertexShader)
Austin Kinrossaf875522014-08-25 21:06:07 -0700121 {
122 // Generate a string declaring the varyings, to share between the fragment shader and the vertex shader.
123 std::string varyingDeclaration;
124
125 unsigned int varyingCount = 0;
126
127 for (GLint i = 0; i < floatCount; i++)
128 {
129 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 1, varyingCount);
130 varyingCount += 1;
131 }
132
133 for (GLint i = 0; i < floatArrayCount; i++)
134 {
135 varyingDeclaration += GenerateVectorVaryingDeclaration(1, 2, varyingCount);
136 varyingCount += 1;
137 }
138
139 for (GLint i = 0; i < vec2Count; i++)
140 {
141 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 1, varyingCount);
142 varyingCount += 1;
143 }
144
145 for (GLint i = 0; i < vec2ArrayCount; i++)
146 {
147 varyingDeclaration += GenerateVectorVaryingDeclaration(2, 2, varyingCount);
148 varyingCount += 1;
149 }
150
151 for (GLint i = 0; i < vec3Count; i++)
152 {
153 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 1, varyingCount);
154 varyingCount += 1;
155 }
156
157 for (GLint i = 0; i < vec3ArrayCount; i++)
158 {
159 varyingDeclaration += GenerateVectorVaryingDeclaration(3, 2, varyingCount);
160 varyingCount += 1;
161 }
162
Austin Kinross8b695ee2015-03-12 13:12:20 -0700163 for (GLint i = 0; i < vec4Count; i++)
164 {
165 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 1, varyingCount);
166 varyingCount += 1;
167 }
168
169 for (GLint i = 0; i < vec4ArrayCount; i++)
170 {
171 varyingDeclaration += GenerateVectorVaryingDeclaration(4, 2, varyingCount);
172 varyingCount += 1;
173 }
174
Austin Kinrossaf875522014-08-25 21:06:07 -0700175 // Generate the vertex shader
176 vertexShader->clear();
177 vertexShader->append(varyingDeclaration);
178 vertexShader->append("\nvoid main()\n{\n");
179
180 unsigned int currentVSVarying = 0;
181
182 for (GLint i = 0; i < floatCount; i++)
183 {
184 vertexShader->append(GenerateVectorVaryingSettingCode(1, 1, currentVSVarying));
185 currentVSVarying += 1;
186 }
187
188 for (GLint i = 0; i < floatArrayCount; i++)
189 {
190 vertexShader->append(GenerateVectorVaryingSettingCode(1, 2, currentVSVarying));
191 currentVSVarying += 1;
192 }
193
194 for (GLint i = 0; i < vec2Count; i++)
195 {
196 vertexShader->append(GenerateVectorVaryingSettingCode(2, 1, currentVSVarying));
197 currentVSVarying += 1;
198 }
199
200 for (GLint i = 0; i < vec2ArrayCount; i++)
201 {
202 vertexShader->append(GenerateVectorVaryingSettingCode(2, 2, currentVSVarying));
203 currentVSVarying += 1;
204 }
205
206 for (GLint i = 0; i < vec3Count; i++)
207 {
208 vertexShader->append(GenerateVectorVaryingSettingCode(3, 1, currentVSVarying));
209 currentVSVarying += 1;
210 }
211
212 for (GLint i = 0; i < vec3ArrayCount; i++)
213 {
214 vertexShader->append(GenerateVectorVaryingSettingCode(3, 2, currentVSVarying));
215 currentVSVarying += 1;
216 }
217
Austin Kinross8b695ee2015-03-12 13:12:20 -0700218 for (GLint i = 0; i < vec4Count; i++)
219 {
220 vertexShader->append(GenerateVectorVaryingSettingCode(4, 1, currentVSVarying));
221 currentVSVarying += 1;
222 }
223
224 for (GLint i = 0; i < vec4ArrayCount; i++)
225 {
226 vertexShader->append(GenerateVectorVaryingSettingCode(4, 2, currentVSVarying));
227 currentVSVarying += 1;
228 }
229
230 if (usePointSize)
231 {
232 vertexShader->append("gl_PointSize = 1.0;\n");
233 }
234
Austin Kinrossaf875522014-08-25 21:06:07 -0700235 vertexShader->append("}\n");
236
237 // Generate the fragment shader
238 fragmentShader->clear();
239 fragmentShader->append("precision highp float;\n");
240 fragmentShader->append(varyingDeclaration);
241 fragmentShader->append("\nvoid main() \n{ \n\tvec4 retColor = vec4(0,0,0,0);\n");
242
243 unsigned int currentFSVarying = 0;
244
245 // Make use of the float varyings
246 fragmentShader->append("\tretColor += vec4(");
247
248 for (GLint i = 0; i < floatCount; i++)
249 {
250 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
251 currentFSVarying += 1;
252 }
253
254 for (GLint i = 0; i < floatArrayCount; i++)
255 {
256 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
257 currentFSVarying += 1;
258 }
259
260 fragmentShader->append("0.0, 0.0, 0.0, 0.0);\n");
261
262 // Make use of the vec2 varyings
263 fragmentShader->append("\tretColor += vec4(");
264
265 for (GLint i = 0; i < vec2Count; i++)
266 {
267 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
268 currentFSVarying += 1;
269 }
270
271 for (GLint i = 0; i < vec2ArrayCount; i++)
272 {
273 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
274 currentFSVarying += 1;
275 }
276
277 fragmentShader->append("vec2(0.0, 0.0), 0.0, 0.0);\n");
278
279 // Make use of the vec3 varyings
280 fragmentShader->append("\tretColor += vec4(");
281
282 for (GLint i = 0; i < vec3Count; i++)
283 {
284 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
285 currentFSVarying += 1;
286 }
287
288 for (GLint i = 0; i < vec3ArrayCount; i++)
289 {
290 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
291 currentFSVarying += 1;
292 }
293
294 fragmentShader->append("vec3(0.0, 0.0, 0.0), 0.0);\n");
Austin Kinross8b695ee2015-03-12 13:12:20 -0700295
296 // Make use of the vec4 varyings
297 fragmentShader->append("\tretColor += ");
298
299 for (GLint i = 0; i < vec4Count; i++)
300 {
301 fragmentShader->append(GenerateVectorVaryingUseCode(1, currentFSVarying));
302 currentFSVarying += 1;
303 }
304
305 for (GLint i = 0; i < vec4ArrayCount; i++)
306 {
307 fragmentShader->append(GenerateVectorVaryingUseCode(2, currentFSVarying));
308 currentFSVarying += 1;
309 }
310
311 fragmentShader->append("vec4(0.0, 0.0, 0.0, 0.0);\n");
312
313 // Set gl_FragColor, and use special variables if requested
314 fragmentShader->append("\tgl_FragColor = retColor");
315
316 if (useFragCoord)
317 {
318 fragmentShader->append(" + gl_FragCoord");
319 }
320
321 if (usePointCoord)
322 {
323 fragmentShader->append(" + vec4(gl_PointCoord, 0.0, 0.0)");
324 }
325
326 fragmentShader->append(";\n}");
327 }
328
329 void VaryingTestBase(GLint floatCount, GLint floatArrayCount, GLint vec2Count, GLint vec2ArrayCount, GLint vec3Count, GLint vec3ArrayCount,
330 GLint vec4Count, GLint vec4ArrayCount, bool useFragCoord, bool usePointCoord, bool usePointSize, bool expectSuccess)
331 {
332 std::string fragmentShaderSource;
333 std::string vertexShaderSource;
334
335 GenerateGLSLWithVaryings(floatCount, floatArrayCount, vec2Count, vec2ArrayCount, vec3Count, vec3ArrayCount,
336 vec4Count, vec4ArrayCount, useFragCoord, usePointCoord, usePointSize,
337 &fragmentShaderSource, &vertexShaderSource);
338
339 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
340
341 if (expectSuccess)
342 {
343 EXPECT_NE(0u, program);
344 }
345 else
346 {
347 EXPECT_EQ(0u, program);
348 }
Austin Kinrossaf875522014-08-25 21:06:07 -0700349 }
350
Jamie Madill2bf8b372014-06-16 17:18:51 -0400351 std::string mSimpleVSSource;
Austin Kinross8b695ee2015-03-12 13:12:20 -0700352 T fixtureType;
Jamie Madill96509e42014-05-29 14:33:27 -0400353};
354
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +0000355// Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
356ANGLE_TYPED_TEST_CASE(GLSLTest_ES3, ES3_D3D11);
357
358template<typename T>
359class GLSLTest_ES3 : public GLSLTest<T>
360{
361};
362
Austin Kinross18b931d2014-09-29 12:58:31 -0700363TYPED_TEST(GLSLTest, NamelessScopedStructs)
Jamie Madill96509e42014-05-29 14:33:27 -0400364{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400365 const std::string fragmentShaderSource = SHADER_SOURCE
Jamie Madill96509e42014-05-29 14:33:27 -0400366 (
Jamie Madillbfa91f42014-06-05 15:45:18 -0400367 precision mediump float;
368
Jamie Madill96509e42014-05-29 14:33:27 -0400369 void main()
370 {
Jamie Madillbfa91f42014-06-05 15:45:18 -0400371 struct
372 {
373 float q;
374 } b;
375
376 gl_FragColor = vec4(1, 0, 0, 1);
377 gl_FragColor.a += b.q;
Jamie Madill96509e42014-05-29 14:33:27 -0400378 }
379 );
380
Jamie Madill5599c8f2014-08-26 13:16:39 -0400381 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400382 EXPECT_NE(0u, program);
383}
Austin Kinross18b931d2014-09-29 12:58:31 -0700384
385TYPED_TEST(GLSLTest, ScopedStructsOrderBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400386{
387 const std::string fragmentShaderSource = SHADER_SOURCE
388 (
389 precision mediump float;
390
391 struct T
392 {
393 float f;
394 };
395
396 void main()
397 {
398 T a;
399
400 struct T
401 {
402 float q;
403 };
404
405 T b;
406
407 gl_FragColor = vec4(1, 0, 0, 1);
408 gl_FragColor.a += a.f;
409 gl_FragColor.a += b.q;
410 }
411 );
412
Jamie Madill5599c8f2014-08-26 13:16:39 -0400413 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madillbfa91f42014-06-05 15:45:18 -0400414 EXPECT_NE(0u, program);
415}
416
Austin Kinross18b931d2014-09-29 12:58:31 -0700417TYPED_TEST(GLSLTest, ScopedStructsBug)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400418{
Jamie Madill96509e42014-05-29 14:33:27 -0400419 const std::string fragmentShaderSource = SHADER_SOURCE
420 (
421 precision mediump float;
422
423 struct T_0
424 {
425 float f;
426 };
427
428 void main()
429 {
430 gl_FragColor = vec4(1, 0, 0, 1);
431
432 struct T
433 {
434 vec2 v;
435 };
436
437 T_0 a;
438 T b;
439
440 gl_FragColor.a += a.f;
441 gl_FragColor.a += b.v.x;
442 }
443 );
444
Jamie Madill5599c8f2014-08-26 13:16:39 -0400445 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
Jamie Madill2bf8b372014-06-16 17:18:51 -0400446 EXPECT_NE(0u, program);
447}
448
Austin Kinross18b931d2014-09-29 12:58:31 -0700449TYPED_TEST(GLSLTest, DxPositionBug)
Jamie Madill2bf8b372014-06-16 17:18:51 -0400450{
451 const std::string &vertexShaderSource = SHADER_SOURCE
452 (
453 attribute vec4 inputAttribute;
454 varying float dx_Position;
455 void main()
456 {
457 gl_Position = vec4(inputAttribute);
458 dx_Position = 0.0;
459 }
460 );
461
462 const std::string &fragmentShaderSource = SHADER_SOURCE
463 (
464 precision mediump float;
465
466 varying float dx_Position;
467
468 void main()
469 {
470 gl_FragColor = vec4(dx_Position, 0, 0, 1);
471 }
472 );
473
Jamie Madill5599c8f2014-08-26 13:16:39 -0400474 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill96509e42014-05-29 14:33:27 -0400475 EXPECT_NE(0u, program);
476}
Jamie Madill4836d222014-07-24 06:55:51 -0400477
Austin Kinross18b931d2014-09-29 12:58:31 -0700478TYPED_TEST(GLSLTest, ElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400479{
480 const std::string &vertexShaderSource =
481 "attribute vec4 a_position;\n"
482 "varying float v;\n"
483 "void main() {\n"
484 " gl_Position = a_position;\n"
485 " v = 1.0;\n"
486 " if (a_position.x <= 0.5) {\n"
487 " v = 0.0;\n"
488 " } else if (a_position.x >= 0.5) {\n"
489 " v = 2.0;\n"
490 " }\n"
491 "}\n";
492
493 const std::string &fragmentShaderSource =
494 "precision highp float;\n"
495 "varying float v;\n"
496 "void main() {\n"
497 " vec4 color = vec4(1.0, 0.0, 0.0, 1.0);\n"
498 " if (v >= 1.0) color = vec4(0.0, 1.0, 0.0, 1.0);\n"
499 " if (v >= 2.0) color = vec4(0.0, 0.0, 1.0, 1.0);\n"
500 " gl_FragColor = color;\n"
501 "}\n";
502
Jamie Madill5599c8f2014-08-26 13:16:39 -0400503 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400504 ASSERT_NE(0u, program);
505
506 drawQuad(program, "a_position", 0.5f);
507 swapBuffers();
508
509 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
510 EXPECT_PIXEL_EQ(getWindowWidth()-1, 0, 0, 255, 0, 255);
511}
512
Austin Kinross18b931d2014-09-29 12:58:31 -0700513TYPED_TEST(GLSLTest, TwoElseIfRewriting)
Jamie Madill4836d222014-07-24 06:55:51 -0400514{
515 const std::string &vertexShaderSource =
516 "attribute vec4 a_position;\n"
517 "varying float v;\n"
518 "void main() {\n"
519 " gl_Position = a_position;\n"
Jamie Madill778d5272014-08-04 13:13:25 -0400520 " if (a_position.x == 0.0) {\n"
Jamie Madill4836d222014-07-24 06:55:51 -0400521 " v = 1.0;\n"
522 " } else if (a_position.x > 0.5) {\n"
523 " v = 0.0;\n"
524 " } else if (a_position.x > 0.75) {\n"
525 " v = 0.5;\n"
526 " }\n"
527 "}\n";
528
529 const std::string &fragmentShaderSource =
530 "precision highp float;\n"
531 "varying float v;\n"
532 "void main() {\n"
533 " gl_FragColor = vec4(v, 0.0, 0.0, 1.0);\n"
534 "}\n";
535
Jamie Madill5599c8f2014-08-26 13:16:39 -0400536 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill4836d222014-07-24 06:55:51 -0400537 EXPECT_NE(0u, program);
538}
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400539
Austin Kinross18b931d2014-09-29 12:58:31 -0700540TYPED_TEST(GLSLTest, InvariantVaryingOut)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400541{
542 const std::string fragmentShaderSource = SHADER_SOURCE
543 (
544 precision mediump float;
545 varying float v_varying;
546 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
547 );
548
549 const std::string vertexShaderSource = SHADER_SOURCE
550 (
551 attribute vec4 a_position;
552 invariant varying float v_varying;
553 void main() { v_varying = a_position.x; gl_Position = a_position; }
554 );
555
Jamie Madill5599c8f2014-08-26 13:16:39 -0400556 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400557 EXPECT_NE(0u, program);
558}
559
Austin Kinross18b931d2014-09-29 12:58:31 -0700560TYPED_TEST(GLSLTest, FrontFacingAndVarying)
Jamie Madille6256f82014-09-17 10:31:15 -0400561{
Austin Kinross8b695ee2015-03-12 13:12:20 -0700562 EGLPlatformParameters platform = fixtureType.GetPlatform();
563
564 // Disable this test on D3D11 feature level 9_3, since gl_FrontFacing isn't supported.
565 if (platform.renderer == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE)
566 {
567 if (platform.majorVersion == 9 && platform.minorVersion == 3)
568 {
569 return;
570 }
571 }
572
Jamie Madille6256f82014-09-17 10:31:15 -0400573 const std::string vertexShaderSource = SHADER_SOURCE
574 (
575 attribute vec4 a_position;
576 varying float v_varying;
577 void main()
578 {
579 v_varying = a_position.x;
580 gl_Position = a_position;
581 }
582 );
583
584 const std::string fragmentShaderSource = SHADER_SOURCE
585 (
586 precision mediump float;
587 varying float v_varying;
588 void main()
589 {
590 vec4 c;
591
592 if (gl_FrontFacing)
593 {
594 c = vec4(v_varying, 0, 0, 1.0);
595 }
596 else
597 {
598 c = vec4(0, v_varying, 0, 1.0);
599 }
600 gl_FragColor = c;
601 }
602 );
603
604 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
605 EXPECT_NE(0u, program);
606}
607
Austin Kinross18b931d2014-09-29 12:58:31 -0700608TYPED_TEST(GLSLTest, InvariantVaryingIn)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400609{
610 const std::string fragmentShaderSource = SHADER_SOURCE
611 (
612 precision mediump float;
613 invariant varying float v_varying;
614 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
615 );
616
617 const std::string vertexShaderSource = SHADER_SOURCE
618 (
619 attribute vec4 a_position;
620 varying float v_varying;
621 void main() { v_varying = a_position.x; gl_Position = a_position; }
622 );
623
Jamie Madill5599c8f2014-08-26 13:16:39 -0400624 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400625 EXPECT_NE(0u, program);
626}
627
Austin Kinross18b931d2014-09-29 12:58:31 -0700628TYPED_TEST(GLSLTest, InvariantVaryingBoth)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400629{
630 const std::string fragmentShaderSource = SHADER_SOURCE
631 (
632 precision mediump float;
633 invariant varying float v_varying;
634 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
635 );
636
637 const std::string vertexShaderSource = SHADER_SOURCE
638 (
639 attribute vec4 a_position;
640 invariant varying float v_varying;
641 void main() { v_varying = a_position.x; gl_Position = a_position; }
642 );
643
Jamie Madill5599c8f2014-08-26 13:16:39 -0400644 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400645 EXPECT_NE(0u, program);
646}
647
Austin Kinross18b931d2014-09-29 12:58:31 -0700648TYPED_TEST(GLSLTest, InvariantGLPosition)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400649{
650 const std::string fragmentShaderSource = SHADER_SOURCE
651 (
652 precision mediump float;
653 varying float v_varying;
654 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
655 );
656
657 const std::string vertexShaderSource = SHADER_SOURCE
658 (
659 attribute vec4 a_position;
660 invariant gl_Position;
661 varying float v_varying;
662 void main() { v_varying = a_position.x; gl_Position = a_position; }
663 );
664
Jamie Madill5599c8f2014-08-26 13:16:39 -0400665 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400666 EXPECT_NE(0u, program);
667}
668
Austin Kinross18b931d2014-09-29 12:58:31 -0700669TYPED_TEST(GLSLTest, InvariantAll)
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400670{
671 const std::string fragmentShaderSource = SHADER_SOURCE
672 (
673 precision mediump float;
674 varying float v_varying;
675 void main() { gl_FragColor = vec4(v_varying, 0, 0, 1.0); }
676 );
677
678 const std::string vertexShaderSource =
679 "#pragma STDGL invariant(all)\n"
680 "attribute vec4 a_position;\n"
681 "varying float v_varying;\n"
682 "void main() { v_varying = a_position.x; gl_Position = a_position; }\n";
683
Jamie Madill5599c8f2014-08-26 13:16:39 -0400684 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
Jamie Madill1c28e1f2014-08-04 11:37:54 -0400685 EXPECT_NE(0u, program);
686}
Austin Kinrossaf875522014-08-25 21:06:07 -0700687
Austin Kinross8b695ee2015-03-12 13:12:20 -0700688TYPED_TEST(GLSLTest, MaxVaryingVec4)
689{
690 GLint maxVaryings = 0;
691 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
692
693 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, false, false, true);
694}
695
696TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusTwoSpecialVariables)
697{
698 GLint maxVaryings = 0;
699 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
700
701 // Generate shader code that uses gl_FragCoord and gl_PointCoord, two special fragment shader variables.
702 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, false, true);
703}
704
705TYPED_TEST(GLSLTest, MaxMinusTwoVaryingVec4PlusThreeSpecialVariables)
706{
707 GLint maxVaryings = 0;
708 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
709
710 // Generate shader code that uses gl_FragCoord, gl_PointCoord and gl_PointSize.
711 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings - 2, 0, true, true, true, true);
712}
713
714TYPED_TEST(GLSLTest, MaxVaryingVec4PlusFragCoord)
715{
716 GLint maxVaryings = 0;
717 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
718
719 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
720 // This test should fail, since we are really using (maxVaryings + 1) varyings.
721 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, true, false, false, false);
722}
723
724TYPED_TEST(GLSLTest, MaxVaryingVec4PlusPointCoord)
725{
726 GLint maxVaryings = 0;
727 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
728
729 // Generate shader code that uses gl_FragCoord, a special fragment shader variables.
730 // This test should fail, since we are really using (maxVaryings + 1) varyings.
731 VaryingTestBase(0, 0, 0, 0, 0, 0, maxVaryings, 0, false, true, false, false);
732}
733
Austin Kinross18b931d2014-09-29 12:58:31 -0700734TYPED_TEST(GLSLTest, MaxVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700735{
736 GLint maxVaryings = 0;
737 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
738
Austin Kinross8b695ee2015-03-12 13:12:20 -0700739 VaryingTestBase(0, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700740}
741
Austin Kinross18b931d2014-09-29 12:58:31 -0700742TYPED_TEST(GLSLTest, MaxVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700743{
744 GLint maxVaryings = 0;
745 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
746
Austin Kinross8b695ee2015-03-12 13:12:20 -0700747 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700748}
749
Jamie Madillbee59e02014-10-02 10:44:18 -0400750// Disabled because of a failure in D3D9
751TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3AndOneFloat)
Austin Kinrossaf875522014-08-25 21:06:07 -0700752{
753 GLint maxVaryings = 0;
754 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
755
Austin Kinross8b695ee2015-03-12 13:12:20 -0700756 VaryingTestBase(1, 0, 0, 0, maxVaryings, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700757}
758
Jamie Madillbee59e02014-10-02 10:44:18 -0400759// Disabled because of a failure in D3D9
760TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec3ArrayAndOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700761{
762 GLint maxVaryings = 0;
763 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
764
Austin Kinross8b695ee2015-03-12 13:12:20 -0700765 VaryingTestBase(0, 1, 0, 0, 0, maxVaryings / 2, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700766}
767
Jamie Madillbee59e02014-10-02 10:44:18 -0400768// Disabled because of a failure in D3D9
769TYPED_TEST(GLSLTest, DISABLED_TwiceMaxVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700770{
771 GLint maxVaryings = 0;
772 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
773
Austin Kinross8b695ee2015-03-12 13:12:20 -0700774 VaryingTestBase(0, 0, 2 * maxVaryings, 0, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700775}
776
Jamie Madillbee59e02014-10-02 10:44:18 -0400777// Disabled because of a failure in D3D9
778TYPED_TEST(GLSLTest, DISABLED_MaxVaryingVec2Arrays)
Austin Kinrossaf875522014-08-25 21:06:07 -0700779{
780 GLint maxVaryings = 0;
781 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
782
Austin Kinross8b695ee2015-03-12 13:12:20 -0700783 VaryingTestBase(0, 0, 0, maxVaryings, 0, 0, 0, 0, false, false, false, true);
Austin Kinrossaf875522014-08-25 21:06:07 -0700784}
785
Austin Kinross18b931d2014-09-29 12:58:31 -0700786TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3)
Austin Kinrossaf875522014-08-25 21:06:07 -0700787{
788 GLint maxVaryings = 0;
789 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
790
Austin Kinross8b695ee2015-03-12 13:12:20 -0700791 VaryingTestBase(0, 0, 0, 0, maxVaryings + 1, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700792}
793
Austin Kinross18b931d2014-09-29 12:58:31 -0700794TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec3Array)
Austin Kinrossaf875522014-08-25 21:06:07 -0700795{
796 GLint maxVaryings = 0;
797 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
798
Austin Kinross8b695ee2015-03-12 13:12:20 -0700799 VaryingTestBase(0, 0, 0, 0, 0, maxVaryings / 2 + 1, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700800}
801
Austin Kinross18b931d2014-09-29 12:58:31 -0700802TYPED_TEST(GLSLTest, MaxVaryingVec3AndOneVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700803{
804 GLint maxVaryings = 0;
805 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
806
Austin Kinross8b695ee2015-03-12 13:12:20 -0700807 VaryingTestBase(0, 0, 1, 0, maxVaryings, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700808}
809
Austin Kinross18b931d2014-09-29 12:58:31 -0700810TYPED_TEST(GLSLTest, MaxPlusOneVaryingVec2)
Austin Kinrossaf875522014-08-25 21:06:07 -0700811{
812 GLint maxVaryings = 0;
813 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
814
Austin Kinross8b695ee2015-03-12 13:12:20 -0700815 VaryingTestBase(0, 0, 2 * maxVaryings + 1, 0, 0, 0, 0, 0, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700816}
817
Austin Kinross18b931d2014-09-29 12:58:31 -0700818TYPED_TEST(GLSLTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
Austin Kinrossaf875522014-08-25 21:06:07 -0700819{
820 GLint maxVaryings = 0;
821 glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVaryings);
822
Austin Kinross8b695ee2015-03-12 13:12:20 -0700823 VaryingTestBase(0, maxVaryings / 2 + 1, 0, 0, 0, 0, 0, maxVaryings / 2, false, false, false, false);
Austin Kinrossaf875522014-08-25 21:06:07 -0700824}
Geoff Langf60fab62014-11-24 11:21:20 -0500825
826// Verify shader source with a fixed length that is less than the null-terminated length will compile.
827TYPED_TEST(GLSLTest, FixedShaderLength)
828{
829 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
830
831 const std::string appendGarbage = "abcasdfasdfasdfasdfasdf";
832 const std::string source = "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" + appendGarbage;
833 const char *sourceArray[1] = { source.c_str() };
834 GLint lengths[1] = { source.length() - appendGarbage.length() };
835 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
836 glCompileShader(shader);
837
838 GLint compileResult;
839 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
840 EXPECT_NE(compileResult, 0);
841}
842
843// Verify that a negative shader source length is treated as a null-terminated length.
844TYPED_TEST(GLSLTest, NegativeShaderLength)
845{
846 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
847
848 const char *sourceArray[1] = { "void main() { gl_FragColor = vec4(0, 0, 0, 0); }" };
849 GLint lengths[1] = { -10 };
850 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
851 glCompileShader(shader);
852
853 GLint compileResult;
854 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
855 EXPECT_NE(compileResult, 0);
856}
857
858// Verify that a length array with mixed positive and negative values compiles.
859TYPED_TEST(GLSLTest, MixedShaderLengths)
860{
861 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
862
863 const char *sourceArray[] =
864 {
865 "void main()",
866 "{",
867 " gl_FragColor = vec4(0, 0, 0, 0);",
868 "}",
869 };
870 GLint lengths[] =
871 {
872 -10,
873 1,
874 std::strlen(sourceArray[2]),
875 -1,
876 };
877 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
878
879 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
880 glCompileShader(shader);
881
882 GLint compileResult;
883 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
884 EXPECT_NE(compileResult, 0);
885}
886
887// Verify that zero-length shader source does not affect shader compilation.
888TYPED_TEST(GLSLTest, ZeroShaderLength)
889{
890 GLuint shader = glCreateShader(GL_FRAGMENT_SHADER);
891
892 const char *sourceArray[] =
893 {
894 "adfasdf",
895 "34534",
896 "void main() { gl_FragColor = vec4(0, 0, 0, 0); }",
897 "",
898 "asdfasdfsdsdf",
899 };
900 GLint lengths[] =
901 {
902 0,
903 0,
904 -1,
905 0,
906 0,
907 };
908 ASSERT_EQ(ArraySize(sourceArray), ArraySize(lengths));
909
910 glShaderSource(shader, ArraySize(sourceArray), sourceArray, lengths);
911 glCompileShader(shader);
912
913 GLint compileResult;
914 glGetShaderiv(shader, GL_COMPILE_STATUS, &compileResult);
915 EXPECT_NE(compileResult, 0);
916}
Jamie Madill21c1e452014-12-29 11:33:41 -0500917
918// Tests that bad index expressions don't crash ANGLE's translator.
919// https://code.google.com/p/angleproject/issues/detail?id=857
920TYPED_TEST(GLSLTest, BadIndexBug)
921{
922 const std::string &fragmentShaderSourceVec =
923 "precision mediump float;\n"
924 "uniform vec4 uniformVec;\n"
925 "void main()\n"
926 "{\n"
927 " gl_FragColor = vec4(uniformVec[int()]);\n"
928 "}";
929
930 GLuint shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceVec);
931 EXPECT_EQ(0u, shader);
932
933 if (shader != 0)
934 {
935 glDeleteShader(shader);
936 }
937
938 const std::string &fragmentShaderSourceMat =
939 "precision mediump float;\n"
940 "uniform mat4 uniformMat;\n"
941 "void main()\n"
942 "{\n"
943 " gl_FragColor = vec4(uniformMat[int()]);\n"
944 "}";
945
946 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceMat);
947 EXPECT_EQ(0u, shader);
948
949 if (shader != 0)
950 {
951 glDeleteShader(shader);
952 }
953
954 const std::string &fragmentShaderSourceArray =
955 "precision mediump float;\n"
956 "uniform vec4 uniformArray;\n"
957 "void main()\n"
958 "{\n"
959 " gl_FragColor = vec4(uniformArray[int()]);\n"
960 "}";
961
962 shader = CompileShader(GL_FRAGMENT_SHADER, fragmentShaderSourceArray);
963 EXPECT_EQ(0u, shader);
964
965 if (shader != 0)
966 {
967 glDeleteShader(shader);
968 }
Jamie Madill37997142015-01-28 10:06:34 -0500969}
970
971// Tests that using a global static initialized from a varying works as expected.
972// See: https://code.google.com/p/angleproject/issues/detail?id=878
973TYPED_TEST(GLSLTest, GlobalStaticAndVarying)
974{
975 const std::string &vertexShaderSource =
976 "attribute vec4 a_position;\n"
977 "varying float v;\n"
978 "void main() {\n"
979 " gl_Position = a_position;\n"
980 " v = 1.0;\n"
981 "}\n";
982
983 const std::string &fragmentShaderSource =
984 "precision highp float;\n"
985 "varying float v;\n"
986 "float x = v;"
987 "float global_v = x;"
988 "void main() {\n"
989 " gl_FragColor = vec4(global_v, 0.0, 0.0, 1.0);\n"
990 "}\n";
991
992 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
993 ASSERT_NE(0u, program);
994
995 drawQuad(program, "a_position", 0.5f);
996 swapBuffers();
997
998 ASSERT_GL_NO_ERROR();
999 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
1000}
Gregoire Payen de La Garanderieb3dced22015-01-12 14:54:55 +00001001
1002// Tests that using a global static initialized from gl_InstanceID works as expected.
1003TYPED_TEST(GLSLTest_ES3, GlobalStaticAndInstanceID)
1004{
1005 const std::string &vertexShaderSource =
1006 "#version 300 es\n"
1007 "precision highp float;\n"
1008 "in vec4 a_position;\n"
1009 "out vec4 vColour;"
1010 "int x = gl_InstanceID;"
1011 "int global_v = x;"
1012 "void main() {\n"
1013 " gl_Position = a_position;\n"
1014 " vColour = vec4(float(global_v)/255., 0.0, 0.0, 1.0);\n"
1015 "}\n";
1016
1017 const std::string &fragmentShaderSource =
1018 "#version 300 es\n"
1019 "precision highp float;\n"
1020 "in vec4 vColour;"
1021 "out vec4 colour;"
1022 "void main() {\n"
1023 " colour = vColour;\n"
1024 "}\n";
1025
1026 GLuint program = CompileProgram(vertexShaderSource, fragmentShaderSource);
1027 ASSERT_NE(0u, program);
1028
1029 GLint positionLocation = glGetAttribLocation(program, "a_position");
1030
1031 glUseProgram(program);
1032
1033 const GLfloat vertices[] =
1034 {
1035 -1.0f, 1.0f, 0.5f,
1036 -1.0f, -1.0f, 0.5f,
1037 1.0f, -1.0f, 0.5f,
1038
1039 -1.0f, 1.0f, 0.5f,
1040 1.0f, -1.0f, 0.5f,
1041 1.0f, 1.0f, 0.5f,
1042 };
1043
1044 glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
1045 glEnableVertexAttribArray(positionLocation);
1046
1047 glDrawArraysInstanced(GL_TRIANGLES, 0, 6, 7);
1048
1049 glDisableVertexAttribArray(positionLocation);
1050 glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
1051
1052 glUseProgram(0);
1053
1054 swapBuffers();
1055
1056 ASSERT_GL_NO_ERROR();
1057 EXPECT_PIXEL_EQ(0, 0, 6, 0, 0, 255);
1058}
Jamie Madill2e295e22015-04-29 10:41:33 -04001059
1060// Test that structs defined in uniforms are translated correctly.
1061TYPED_TEST(GLSLTest, StructSpecifiersUniforms)
1062{
1063 const std::string fragmentShaderSource = SHADER_SOURCE
1064 (
1065 precision mediump float;
1066
1067 uniform struct S { float field;} s;
1068
1069 void main()
1070 {
1071 gl_FragColor = vec4(1, 0, 0, 1);
1072 gl_FragColor.a += s.field;
1073 }
1074 );
1075
1076 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1077 EXPECT_NE(0u, program);
1078}
Jamie Madill55def582015-05-04 11:24:57 -04001079
1080// Test that gl_DepthRange is not stored as a uniform location. Since uniforms
1081// beginning with "gl_" are filtered out by our validation logic, we must
1082// bypass the validation to test the behaviour of the implementation.
1083// (note this test is still Impl-independent)
1084TYPED_TEST(GLSLTest, DepthRangeUniforms)
1085{
1086 const std::string fragmentShaderSource = SHADER_SOURCE
1087 (
1088 precision mediump float;
1089
1090 void main()
1091 {
1092 gl_FragColor = vec4(gl_DepthRange.near, gl_DepthRange.far, gl_DepthRange.diff, 1);
1093 }
1094 );
1095
1096 GLuint program = CompileProgram(mSimpleVSSource, fragmentShaderSource);
1097 EXPECT_NE(0u, program);
1098
1099 // dive into the ANGLE internals, so we can bypass validation.
1100 gl::Context *context = reinterpret_cast<gl::Context *>(getEGLWindow()->getContext());
1101 gl::Program *glProgram = context->getProgram(program);
1102 GLint nearIndex = glProgram->getUniformLocation("gl_DepthRange.near");
1103 EXPECT_EQ(-1, nearIndex);
1104
1105 // Test drawing does not throw an exception.
1106 drawQuad(program, "inputAttribute", 0.5f);
1107
1108 EXPECT_GL_NO_ERROR();
1109
1110 glDeleteProgram(program);
1111}