1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gpu/command_buffer/service/shader_translator.h"
6 #include "testing/gtest/include/gtest/gtest.h"
7 #include "ui/gl/gl_bindings.h"
8 #include "ui/gl/gl_version_info.h"
9 
10 namespace gpu {
11 namespace gles2 {
12 
13 class ShaderTranslatorTest : public testing::Test {
14  public:
ShaderTranslatorTest()15   ShaderTranslatorTest() {
16     shader_output_language_ =
17         ShaderTranslator::GetShaderOutputLanguageForContext(
18             gl::GLVersionInfo("2.0", "", gfx::ExtensionSet()));
19   }
20 
21   ~ShaderTranslatorTest() override = default;
22 
23  protected:
SetUp()24   void SetUp() override {
25     ShBuiltInResources resources;
26     sh::InitBuiltInResources(&resources);
27     resources.MaxExpressionComplexity = 32;
28     resources.MaxCallStackDepth = 32;
29 
30     vertex_translator_ = new ShaderTranslator();
31     fragment_translator_ = new ShaderTranslator();
32 
33     ASSERT_TRUE(vertex_translator_->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC,
34                                          &resources, shader_output_language_,
35                                          static_cast<ShCompileOptions>(0),
36                                          false));
37     ASSERT_TRUE(fragment_translator_->Init(GL_FRAGMENT_SHADER, SH_GLES2_SPEC,
38                                            &resources, shader_output_language_,
39                                            static_cast<ShCompileOptions>(0),
40                                            false));
41   }
TearDown()42   void TearDown() override {
43     vertex_translator_ = nullptr;
44     fragment_translator_ = nullptr;
45   }
46 
47   scoped_refptr<ShaderTranslator> vertex_translator_;
48   scoped_refptr<ShaderTranslator> fragment_translator_;
49   ShShaderOutput shader_output_language_;
50 };
51 
52 class ES3ShaderTranslatorTest : public testing::Test {
53  public:
ES3ShaderTranslatorTest()54   ES3ShaderTranslatorTest() {
55     shader_output_language_ =
56         ShaderTranslator::GetShaderOutputLanguageForContext(
57             gl::GLVersionInfo("3.0", "", gfx::ExtensionSet()));
58   }
59 
60   ~ES3ShaderTranslatorTest() override = default;
61 
62  protected:
SetUp()63   void SetUp() override {
64     ShBuiltInResources resources;
65     sh::InitBuiltInResources(&resources);
66     resources.MaxExpressionComplexity = 32;
67     resources.MaxCallStackDepth = 32;
68 
69     vertex_translator_ = new ShaderTranslator();
70     fragment_translator_ = new ShaderTranslator();
71 
72     ASSERT_TRUE(vertex_translator_->Init(GL_VERTEX_SHADER, SH_GLES3_SPEC,
73                                          &resources, shader_output_language_,
74                                          static_cast<ShCompileOptions>(0),
75                                          false));
76     ASSERT_TRUE(fragment_translator_->Init(GL_FRAGMENT_SHADER, SH_GLES3_SPEC,
77                                            &resources, shader_output_language_,
78                                            static_cast<ShCompileOptions>(0),
79                                            false));
80   }
TearDown()81   void TearDown() override {
82     vertex_translator_ = nullptr;
83     fragment_translator_ = nullptr;
84   }
85 
86   scoped_refptr<ShaderTranslator> vertex_translator_;
87   scoped_refptr<ShaderTranslator> fragment_translator_;
88   ShShaderOutput shader_output_language_;
89 };
90 
TEST_F(ShaderTranslatorTest,ValidVertexShader)91 TEST_F(ShaderTranslatorTest, ValidVertexShader) {
92   const char* shader =
93       "void main() {\n"
94       "  gl_Position = vec4(1.0);\n"
95       "}";
96 
97   // A valid shader should be successfully translated.
98   std::string info_log, translated_source;
99   int shader_version;
100   AttributeMap attrib_map;
101   UniformMap uniform_map;
102   VaryingMap varying_map;
103   InterfaceBlockMap interface_block_map;
104   OutputVariableList output_variable_list;
105   EXPECT_TRUE(vertex_translator_->Translate(
106       shader, &info_log, &translated_source, &shader_version, &attrib_map,
107       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
108 
109   // Info log must be NULL.
110   EXPECT_TRUE(info_log.empty());
111   // Translated shader must be valid and non-empty.
112   ASSERT_FALSE(translated_source.empty());
113   // There should be no attributes, uniforms, and only one built-in
114   // varying: gl_Position.
115   EXPECT_TRUE(attrib_map.empty());
116   EXPECT_TRUE(uniform_map.empty());
117   EXPECT_TRUE(interface_block_map.empty());
118   EXPECT_EQ(1u, varying_map.size());
119   EXPECT_TRUE(output_variable_list.empty());
120 }
121 
TEST_F(ShaderTranslatorTest,InvalidVertexShader)122 TEST_F(ShaderTranslatorTest, InvalidVertexShader) {
123   const char* bad_shader = "foo-bar";
124   const char* good_shader =
125       "void main() {\n"
126       "  gl_Position = vec4(1.0);\n"
127       "}";
128 
129   // An invalid shader should fail.
130   std::string info_log, translated_source;
131   int shader_version;
132   AttributeMap attrib_map;
133   UniformMap uniform_map;
134   VaryingMap varying_map;
135   InterfaceBlockMap interface_block_map;
136   OutputVariableList output_variable_list;
137   EXPECT_FALSE(vertex_translator_->Translate(
138       bad_shader, &info_log, &translated_source, &shader_version, &attrib_map,
139       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
140   // Info log must be valid and non-empty.
141   ASSERT_FALSE(info_log.empty());
142   // Translated shader must be NULL.
143   EXPECT_TRUE(translated_source.empty());
144   // There should be no attributes, uniforms, varyings, interface block or
145   // name mapping.
146   EXPECT_TRUE(attrib_map.empty());
147   EXPECT_TRUE(uniform_map.empty());
148   EXPECT_TRUE(varying_map.empty());
149   EXPECT_TRUE(interface_block_map.empty());
150   EXPECT_TRUE(output_variable_list.empty());
151 
152   // Try a good shader after bad.
153   info_log.clear();
154   EXPECT_TRUE(vertex_translator_->Translate(
155       good_shader, &info_log, &translated_source, &shader_version, &attrib_map,
156       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
157   EXPECT_TRUE(info_log.empty());
158   EXPECT_FALSE(translated_source.empty());
159   EXPECT_TRUE(interface_block_map.empty());
160 }
161 
TEST_F(ShaderTranslatorTest,ValidFragmentShader)162 TEST_F(ShaderTranslatorTest, ValidFragmentShader) {
163   const char* shader =
164       "void main() {\n"
165       "  gl_FragColor = vec4(1.0);\n"
166       "}";
167 
168   // A valid shader should be successfully translated.
169   std::string info_log, translated_source;
170   int shader_version;
171   AttributeMap attrib_map;
172   UniformMap uniform_map;
173   VaryingMap varying_map;
174   InterfaceBlockMap interface_block_map;
175   OutputVariableList output_variable_list;
176   EXPECT_TRUE(fragment_translator_->Translate(
177       shader, &info_log, &translated_source, &shader_version, &attrib_map,
178       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
179   // Info log must be NULL.
180   EXPECT_TRUE(info_log.empty());
181   // Translated shader must be valid and non-empty.
182   ASSERT_FALSE(translated_source.empty());
183   // There should be no attributes, uniforms, varyings, interface block or
184   // name mapping.
185   EXPECT_TRUE(attrib_map.empty());
186   EXPECT_TRUE(uniform_map.empty());
187   EXPECT_TRUE(varying_map.empty());
188   EXPECT_TRUE(interface_block_map.empty());
189   // gl_FragColor.
190   EXPECT_EQ(1u, output_variable_list.size());
191 }
192 
TEST_F(ShaderTranslatorTest,InvalidFragmentShader)193 TEST_F(ShaderTranslatorTest, InvalidFragmentShader) {
194   const char* shader = "foo-bar";
195 
196   std::string info_log, translated_source;
197   int shader_version;
198   AttributeMap attrib_map;
199   UniformMap uniform_map;
200   VaryingMap varying_map;
201   InterfaceBlockMap interface_block_map;
202   OutputVariableList output_variable_list;
203   // An invalid shader should fail.
204   EXPECT_FALSE(fragment_translator_->Translate(
205       shader, &info_log, &translated_source, &shader_version, &attrib_map,
206       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
207   // Info log must be valid and non-empty.
208   EXPECT_FALSE(info_log.empty());
209   // Translated shader must be NULL.
210   EXPECT_TRUE(translated_source.empty());
211   // There should be no attributes, uniforms, varyings, interface block or
212   // name mapping.
213   EXPECT_TRUE(attrib_map.empty());
214   EXPECT_TRUE(uniform_map.empty());
215   EXPECT_TRUE(varying_map.empty());
216   EXPECT_TRUE(output_variable_list.empty());
217 }
218 
TEST_F(ShaderTranslatorTest,GetAttributes)219 TEST_F(ShaderTranslatorTest, GetAttributes) {
220   const char* shader =
221       "attribute vec4 vPosition;\n"
222       "void main() {\n"
223       "  gl_Position = vPosition;\n"
224       "}";
225 
226   std::string info_log, translated_source;
227   int shader_version;
228   AttributeMap attrib_map;
229   UniformMap uniform_map;
230   VaryingMap varying_map;
231   InterfaceBlockMap interface_block_map;
232   OutputVariableList output_variable_list;
233   EXPECT_TRUE(vertex_translator_->Translate(
234       shader, &info_log, &translated_source, &shader_version, &attrib_map,
235       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
236   // Info log must be NULL.
237   EXPECT_TRUE(info_log.empty());
238   // Translated shader must be valid and non-empty.
239   EXPECT_FALSE(translated_source.empty());
240   // There should be no uniforms.
241   EXPECT_TRUE(uniform_map.empty());
242   // There should be no interface blocks.
243   EXPECT_TRUE(interface_block_map.empty());
244   // There should be one attribute with following characteristics:
245   // name:vPosition type:GL_FLOAT_VEC4 size:0.
246   EXPECT_EQ(1u, attrib_map.size());
247   // The shader translator adds a "_u" prefix to user-defined names.
248   AttributeMap::const_iterator iter = attrib_map.find("_uvPosition");
249   EXPECT_TRUE(iter != attrib_map.end());
250   EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), iter->second.type);
251   EXPECT_EQ(0u, iter->second.getOutermostArraySize());
252   EXPECT_EQ("vPosition", iter->second.name);
253 }
254 
TEST_F(ShaderTranslatorTest,GetUniforms)255 TEST_F(ShaderTranslatorTest, GetUniforms) {
256   const char* shader =
257       "precision mediump float;\n"
258       "struct Foo {\n"
259       "  vec4 color[1];\n"
260       "};\n"
261       "struct Bar {\n"
262       "  Foo foo;\n"
263       "};\n"
264       "uniform Bar bar[2];\n"
265       "void main() {\n"
266       "  gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
267       "}";
268 
269   std::string info_log, translated_source;
270   int shader_version;
271   AttributeMap attrib_map;
272   UniformMap uniform_map;
273   VaryingMap varying_map;
274   InterfaceBlockMap interface_block_map;
275   OutputVariableList output_variable_list;
276   EXPECT_TRUE(fragment_translator_->Translate(
277       shader, &info_log, &translated_source, &shader_version, &attrib_map,
278       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
279   // Info log must be NULL.
280   EXPECT_TRUE(info_log.empty());
281   // Translated shader must be valid and non-empty.
282   EXPECT_FALSE(translated_source.empty());
283   // There should be no attributes.
284   EXPECT_TRUE(attrib_map.empty());
285   // There should be no interface blocks.
286   EXPECT_TRUE(interface_block_map.empty());
287   // There should be two uniforms with following characteristics:
288   // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
289   // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
290   // However, there will be only one entry "bar" in the map.
291   EXPECT_EQ(1u, uniform_map.size());
292   // The shader translator adds a "_u" prefix to user-defined names.
293   UniformMap::const_iterator iter = uniform_map.find("_ubar");
294   EXPECT_TRUE(iter != uniform_map.end());
295   // First uniform.
296   const sh::ShaderVariable* info;
297   std::string original_name;
298   EXPECT_TRUE(iter->second.findInfoByMappedName("_ubar[0]._ufoo._ucolor[0]",
299                                                 &info, &original_name));
300   EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
301   EXPECT_EQ(1u, info->getOutermostArraySize());
302   EXPECT_STREQ("color", info->name.c_str());
303   EXPECT_STREQ("bar[0].foo.color[0]", original_name.c_str());
304   // Second uniform.
305   EXPECT_TRUE(iter->second.findInfoByMappedName("_ubar[1]._ufoo._ucolor[0]",
306                                                 &info, &original_name));
307   EXPECT_EQ(static_cast<GLenum>(GL_FLOAT_VEC4), info->type);
308   EXPECT_EQ(1u, info->getOutermostArraySize());
309   EXPECT_STREQ("color", info->name.c_str());
310   EXPECT_STREQ("bar[1].foo.color[0]", original_name.c_str());
311   EXPECT_EQ(1u, output_variable_list.size());
312   ASSERT_TRUE(output_variable_list.size() > 0);
313   EXPECT_EQ(output_variable_list[0].mappedName, "gl_FragColor");
314 }
315 
316 
TEST_F(ES3ShaderTranslatorTest,InvalidInterfaceBlocks)317 TEST_F(ES3ShaderTranslatorTest, InvalidInterfaceBlocks) {
318   const char* shader =
319       "#version 300 es\n"
320       "precision mediump float;\n"
321       "layout(location=0) out vec4 oColor;\n"
322       "uniform Color {\n"
323       "  float red;\n"
324       "  float green;\n"
325       "  float blue;\n"
326       "};\n"
327       "uniform Color2 {\n"
328       "  float R;\n"
329       "  float green;\n"
330       "  float B;\n"
331       "};\n"
332       "void main() {\n"
333       "  oColor = vec4(red * R, green * green, blue * B, 1.0);\n"
334       "}";
335 
336   std::string info_log, translated_source;
337   int shader_version;
338   AttributeMap attrib_map;
339   UniformMap uniform_map;
340   VaryingMap varying_map;
341   InterfaceBlockMap interface_block_map;
342   OutputVariableList output_variable_list;
343   EXPECT_FALSE(fragment_translator_->Translate(
344       shader, &info_log, &translated_source, &shader_version, &attrib_map,
345       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
346   // Info log must be valid and non-empty.
347   ASSERT_FALSE(info_log.empty());
348   // Translated shader must be NULL.
349   EXPECT_TRUE(translated_source.empty());
350   // There should be no attributes, uniforms, varyings, interface block or
351   // name mapping.
352   EXPECT_TRUE(attrib_map.empty());
353   EXPECT_TRUE(uniform_map.empty());
354   EXPECT_TRUE(varying_map.empty());
355   EXPECT_TRUE(interface_block_map.empty());
356 }
357 
TEST_F(ES3ShaderTranslatorTest,GetInterfaceBlocks)358 TEST_F(ES3ShaderTranslatorTest, GetInterfaceBlocks) {
359   const char* shader =
360       "#version 300 es\n"
361       "precision mediump float;\n"
362       "layout(location=0) out vec4 oColor;\n"
363       "uniform Color {\n"
364       "  float red;\n"
365       "  float green;\n"
366       "  float blue;\n"
367       "};\n"
368       "void main() {\n"
369       "  oColor = vec4(red, green, blue, 1.0);\n"
370       "}";
371 
372   std::string info_log, translated_source;
373   int shader_version;
374   AttributeMap attrib_map;
375   UniformMap uniform_map;
376   VaryingMap varying_map;
377   InterfaceBlockMap interface_block_map;
378   OutputVariableList output_variable_list;
379   EXPECT_TRUE(fragment_translator_->Translate(
380       shader, &info_log, &translated_source, &shader_version, &attrib_map,
381       &uniform_map, &varying_map, &interface_block_map, &output_variable_list));
382   // Info log must be NULL.
383   EXPECT_TRUE(info_log.empty());
384   // Translated shader must be valid and non-empty.
385   EXPECT_FALSE(translated_source.empty());
386   // There should be no attributes.
387   EXPECT_TRUE(attrib_map.empty());
388   // There should be one block in interface_block_map
389   EXPECT_EQ(1u, interface_block_map.size());
390   InterfaceBlockMap::const_iterator iter;
391   for (iter = interface_block_map.begin();
392        iter != interface_block_map.end(); ++iter) {
393     if (iter->second.name == "Color")
394       break;
395   }
396   EXPECT_TRUE(iter != interface_block_map.end());
397 }
398 
TEST_F(ShaderTranslatorTest,OptionsString)399 TEST_F(ShaderTranslatorTest, OptionsString) {
400   scoped_refptr<ShaderTranslator> translator_1 = new ShaderTranslator();
401   scoped_refptr<ShaderTranslator> translator_2 = new ShaderTranslator();
402   scoped_refptr<ShaderTranslator> translator_3 = new ShaderTranslator();
403 
404   ShBuiltInResources resources;
405   sh::InitBuiltInResources(&resources);
406 
407   ASSERT_TRUE(translator_1->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
408                                  SH_GLSL_150_CORE_OUTPUT,
409                                  static_cast<ShCompileOptions>(0),
410                                  false));
411   ASSERT_TRUE(translator_2->Init(GL_FRAGMENT_SHADER, SH_GLES2_SPEC, &resources,
412                                  SH_GLSL_150_CORE_OUTPUT,
413                                  SH_INIT_OUTPUT_VARIABLES,
414                                  false));
415   resources.EXT_draw_buffers = 1;
416   ASSERT_TRUE(translator_3->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
417                                  SH_GLSL_150_CORE_OUTPUT,
418                                  static_cast<ShCompileOptions>(0),
419                                  false));
420 
421   std::string options_1(
422       translator_1->GetStringForOptionsThatWouldAffectCompilation()->data);
423   std::string options_2(
424       translator_1->GetStringForOptionsThatWouldAffectCompilation()->data);
425   std::string options_3(
426       translator_2->GetStringForOptionsThatWouldAffectCompilation()->data);
427   std::string options_4(
428       translator_3->GetStringForOptionsThatWouldAffectCompilation()->data);
429 
430   EXPECT_EQ(options_1, options_2);
431   EXPECT_NE(options_1, options_3);
432   EXPECT_NE(options_1, options_4);
433   EXPECT_NE(options_3, options_4);
434 }
435 
436 class ShaderTranslatorOutputVersionTest
437     : public testing::TestWithParam<testing::tuple<const char*, const char*>> {
438 };
439 
440 // crbug.com/540543
441 // https://bugs.chromium.org/p/angleproject/issues/detail?id=1276
442 // https://bugs.chromium.org/p/angleproject/issues/detail?id=1277
TEST_F(ShaderTranslatorOutputVersionTest,DISABLED_CompatibilityOutput)443 TEST_F(ShaderTranslatorOutputVersionTest, DISABLED_CompatibilityOutput) {
444   ShBuiltInResources resources;
445   sh::InitBuiltInResources(&resources);
446   ShCompileOptions compile_options = SH_OBJECT_CODE;
447   ShShaderOutput shader_output_language = SH_GLSL_COMPATIBILITY_OUTPUT;
448   scoped_refptr<ShaderTranslator> vertex_translator = new ShaderTranslator();
449   ASSERT_TRUE(vertex_translator->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC,
450                                       &resources, shader_output_language,
451                                       compile_options,
452                                       false));
453   scoped_refptr<ShaderTranslator> fragment_translator = new ShaderTranslator();
454   ASSERT_TRUE(fragment_translator->Init(GL_FRAGMENT_SHADER, SH_GLES2_SPEC,
455                                         &resources, shader_output_language,
456                                         compile_options,
457                                         false));
458 
459   std::string translated_source;
460   int shader_version;
461   {
462     const char* kShader =
463         "attribute vec4 vPosition;\n"
464         "void main() {\n"
465         "}";
466 
467     EXPECT_TRUE(vertex_translator->Translate(
468         kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr,
469         nullptr, nullptr, nullptr));
470     EXPECT_TRUE(translated_source.find("#version") == std::string::npos);
471     if (translated_source.find("gl_Position =") == std::string::npos) {
472       ADD_FAILURE() << "Did not find gl_Position initialization.";
473       LOG(ERROR) << "Generated output:\n" << translated_source;
474     }
475   }
476   {
477     const char* kShader =
478         "#pragma STDGL invariant(all)\n"
479         "precision mediump float;\n"
480         "varying vec4 v_varying;\n"
481         "void main() {\n"
482         "    gl_FragColor = v_varying;\n"
483         "}\n";
484 
485     EXPECT_TRUE(fragment_translator->Translate(
486         kShader, nullptr, &translated_source, &shader_version, nullptr, nullptr,
487         nullptr, nullptr, nullptr));
488     EXPECT_TRUE(translated_source.find("#version 120") != std::string::npos);
489     if (translated_source.find("#pragma STDGL invariant(all)") !=
490         std::string::npos) {
491       ADD_FAILURE() << "Found forbidden pragma.";
492       LOG(ERROR) << "Generated output:\n" << translated_source;
493     }
494   }
495 }
496 
TEST_P(ShaderTranslatorOutputVersionTest,HasCorrectOutputGLSLVersion)497 TEST_P(ShaderTranslatorOutputVersionTest, HasCorrectOutputGLSLVersion) {
498   // Test that translating to a shader targeting certain OpenGL context version
499   // (version string in test param tuple index 0) produces a GLSL shader that
500   // contains correct version string for that context (version directive
501   // in test param tuple index 1).
502 
503   const char* kShader =
504       "attribute vec4 vPosition;\n"
505       "void main() {\n"
506       "  gl_Position = vPosition;\n"
507       "}";
508 
509   gl::GLVersionInfo output_context_version(testing::get<0>(GetParam()), "",
510                                            gfx::ExtensionSet());
511 
512   scoped_refptr<ShaderTranslator> translator = new ShaderTranslator();
513   ShBuiltInResources resources;
514   sh::InitBuiltInResources(&resources);
515   ShCompileOptions compile_options = SH_OBJECT_CODE;
516   ShShaderOutput shader_output_language =
517       ShaderTranslator::GetShaderOutputLanguageForContext(
518           output_context_version);
519   ASSERT_TRUE(translator->Init(GL_VERTEX_SHADER, SH_GLES2_SPEC, &resources,
520                                shader_output_language, compile_options, false));
521 
522   std::string translated_source;
523   int shader_version;
524   EXPECT_TRUE(translator->Translate(kShader, nullptr, &translated_source,
525                                     &shader_version, nullptr, nullptr, nullptr,
526                                     nullptr, nullptr));
527 
528   std::string expected_version_directive = testing::get<1>(GetParam());
529   if (expected_version_directive.empty()) {
530     EXPECT_TRUE(translated_source.find("#version") == std::string::npos)
531         << "Translation was:\n" << translated_source;
532   } else {
533     EXPECT_TRUE(translated_source.find(expected_version_directive) !=
534                 std::string::npos)
535         << "Translation was:\n" << translated_source;
536   }
537 }
538 
539 // For some compilers, using make_tuple("a", "bb") would end up
540 // instantiating make_tuple<char[1], char[2]>. This does not work.
541 namespace {
make_gl_glsl_tuple(const char * gl_version,const char * glsl_version_directive)542 testing::tuple<const char*, const char*> make_gl_glsl_tuple(
543     const char* gl_version,
544     const char* glsl_version_directive) {
545   return testing::make_tuple(gl_version, glsl_version_directive);
546 }
547 }
548 
549 // Test data for the above test. OpenGL specifications specify a
550 // certain version of GLSL to be guaranteed to be supported. Test
551 // that ShaderTranslator produces a GLSL shader with the exact
552 // specified GLSL version for each known OpenGL version.
553 INSTANTIATE_TEST_SUITE_P(
554     KnownOpenGLContexts,
555     ShaderTranslatorOutputVersionTest,
556     testing::Values(make_gl_glsl_tuple("4.5", "#version 450\n"),
557                     make_gl_glsl_tuple("4.4", "#version 440\n"),
558                     make_gl_glsl_tuple("4.3", "#version 430\n"),
559                     make_gl_glsl_tuple("4.2", "#version 420\n"),
560                     make_gl_glsl_tuple("4.1", "#version 410\n"),
561                     make_gl_glsl_tuple("4.0", "#version 400\n"),
562                     make_gl_glsl_tuple("3.3", "#version 330\n"),
563                     make_gl_glsl_tuple("3.2", "#version 150\n"),
564                     make_gl_glsl_tuple("3.1", ""),
565                     make_gl_glsl_tuple("3.0", "")));
566 
567 // Test data for the above test. Check that early OpenGL contexts get
568 // GLSL compatibility profile shader, e.g. shader has no #version
569 // directive. Also check that future version 3.3+ OpenGL contexts get
570 // similar shader. We do not expect that future 3.3+ specs contain
571 // the "all eariler GLSL versions" clause, since 3.3 did not contain
572 // it either.
573 INSTANTIATE_TEST_SUITE_P(OldOrUnknownOpenGLContexts,
574                          ShaderTranslatorOutputVersionTest,
575                          testing::Values(make_gl_glsl_tuple("3.4", ""),
576                                          make_gl_glsl_tuple("2.0", "")));
577 
578 // Test data for the above test. Cases for the future OpenGL versions. The
579 // code assumes that the future OpenGL specs specify the clause that all
580 // earlier GLSL versions are supported. We select the highest GLSL
581 // version known at the time of writing.
582 INSTANTIATE_TEST_SUITE_P(
583     BackwardsCompatibleFutureOpenGLContexts,
584     ShaderTranslatorOutputVersionTest,
585     testing::Values(make_gl_glsl_tuple("5.0", "#version 450\n"),
586                     make_gl_glsl_tuple("4.6", "#version 450\n")));
587 
588 // Test data for the above test. Check that for the OpenGL ES output
589 // contexts, the shader is such that GLSL 1.0 is used. The translator
590 // selects GLSL 1.0 by not output any version at the moment, though we
591 // do not know if that would be correct for the future OpenGL ES specs.
592 INSTANTIATE_TEST_SUITE_P(
593     OpenGLESContexts,
594     ShaderTranslatorOutputVersionTest,
595     testing::Values(make_gl_glsl_tuple("opengl es 2.0", ""),
596                     make_gl_glsl_tuple("opengl es 3.0", ""),
597                     make_gl_glsl_tuple("opengl es 3.1", ""),
598                     make_gl_glsl_tuple("opengl es 3.2", "")));
599 
600 }  // namespace gles2
601 }  // namespace gpu
602