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.
7 #include "gpu/command_buffer/service/shader_translator.h"
8 #include "testing/gtest/include/gtest/gtest.h"
13 class ShaderTranslatorTest
: public testing::Test
{
15 ShaderTranslatorTest() {
18 ~ShaderTranslatorTest() override
{}
21 void SetUp() override
{
22 ShBuiltInResources resources
;
23 ShInitBuiltInResources(&resources
);
24 resources
.MaxExpressionComplexity
= 32;
25 resources
.MaxCallStackDepth
= 32;
27 vertex_translator_
= new ShaderTranslator();
28 fragment_translator_
= new ShaderTranslator();
30 ASSERT_TRUE(vertex_translator_
->Init(
31 GL_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
32 ShaderTranslatorInterface::kGlsl
,
33 SH_EMULATE_BUILT_IN_FUNCTIONS
));
34 ASSERT_TRUE(fragment_translator_
->Init(
35 GL_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
36 ShaderTranslatorInterface::kGlsl
,
37 static_cast<ShCompileOptions
>(0)));
39 void TearDown() override
{
40 vertex_translator_
= NULL
;
41 fragment_translator_
= NULL
;
44 scoped_refptr
<ShaderTranslator
> vertex_translator_
;
45 scoped_refptr
<ShaderTranslator
> fragment_translator_
;
48 TEST_F(ShaderTranslatorTest
, ValidVertexShader
) {
51 " gl_Position = vec4(1.0);\n"
54 // A valid shader should be successfully translated.
55 std::string info_log
, translated_source
;
56 AttributeMap attrib_map
;
57 UniformMap uniform_map
;
58 VaryingMap varying_map
;
60 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
67 // Info log must be NULL.
68 EXPECT_TRUE(info_log
.empty());
69 // Translated shader must be valid and non-empty.
70 ASSERT_FALSE(translated_source
.empty());
71 // There should be no attributes, uniforms, and only one built-in
72 // varying: gl_Position.
73 EXPECT_TRUE(attrib_map
.empty());
74 EXPECT_TRUE(uniform_map
.empty());
75 EXPECT_EQ(1u, varying_map
.size());
76 // There should be no name mapping.
77 EXPECT_TRUE(name_map
.empty());
80 TEST_F(ShaderTranslatorTest
, InvalidVertexShader
) {
81 const char* bad_shader
= "foo-bar";
82 const char* good_shader
=
84 " gl_Position = vec4(1.0);\n"
87 // An invalid shader should fail.
88 std::string info_log
, translated_source
;
89 AttributeMap attrib_map
;
90 UniformMap uniform_map
;
91 VaryingMap varying_map
;
93 EXPECT_FALSE(vertex_translator_
->Translate(bad_shader
,
100 // Info log must be valid and non-empty.
101 ASSERT_FALSE(info_log
.empty());
102 // Translated shader must be NULL.
103 EXPECT_TRUE(translated_source
.empty());
104 // There should be no attributes, uniforms, varyings, or name mapping.
105 EXPECT_TRUE(attrib_map
.empty());
106 EXPECT_TRUE(uniform_map
.empty());
107 EXPECT_TRUE(varying_map
.empty());
108 EXPECT_TRUE(name_map
.empty());
110 // Try a good shader after bad.
112 EXPECT_TRUE(vertex_translator_
->Translate(good_shader
,
119 EXPECT_TRUE(info_log
.empty());
120 EXPECT_FALSE(translated_source
.empty());
123 TEST_F(ShaderTranslatorTest
, ValidFragmentShader
) {
126 " gl_FragColor = vec4(1.0);\n"
129 // A valid shader should be successfully translated.
130 std::string info_log
, translated_source
;
131 AttributeMap attrib_map
;
132 UniformMap uniform_map
;
133 VaryingMap varying_map
;
135 EXPECT_TRUE(fragment_translator_
->Translate(shader
,
142 // Info log must be NULL.
143 EXPECT_TRUE(info_log
.empty());
144 // Translated shader must be valid and non-empty.
145 ASSERT_FALSE(translated_source
.empty());
146 // There should be no attributes, uniforms, varyings, or name mapping.
147 EXPECT_TRUE(attrib_map
.empty());
148 EXPECT_TRUE(uniform_map
.empty());
149 EXPECT_TRUE(varying_map
.empty());
150 EXPECT_TRUE(name_map
.empty());
153 TEST_F(ShaderTranslatorTest
, InvalidFragmentShader
) {
154 const char* shader
= "foo-bar";
156 std::string info_log
, translated_source
;
157 AttributeMap attrib_map
;
158 UniformMap uniform_map
;
159 VaryingMap varying_map
;
161 // An invalid shader should fail.
162 EXPECT_FALSE(fragment_translator_
->Translate(shader
,
169 // Info log must be valid and non-empty.
170 EXPECT_FALSE(info_log
.empty());
171 // Translated shader must be NULL.
172 EXPECT_TRUE(translated_source
.empty());
173 // There should be no attributes or uniforms.
174 EXPECT_TRUE(attrib_map
.empty());
175 EXPECT_TRUE(uniform_map
.empty());
176 EXPECT_TRUE(varying_map
.empty());
177 EXPECT_TRUE(name_map
.empty());
180 TEST_F(ShaderTranslatorTest
, GetAttributes
) {
182 "attribute vec4 vPosition;\n"
184 " gl_Position = vPosition;\n"
187 std::string info_log
, translated_source
;
188 AttributeMap attrib_map
;
189 UniformMap uniform_map
;
190 VaryingMap varying_map
;
192 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
199 // Info log must be NULL.
200 EXPECT_TRUE(info_log
.empty());
201 // Translated shader must be valid and non-empty.
202 EXPECT_FALSE(translated_source
.empty());
203 // There should be no uniforms.
204 EXPECT_TRUE(uniform_map
.empty());
205 // There should be one attribute with following characteristics:
206 // name:vPosition type:GL_FLOAT_VEC4 size:0.
207 EXPECT_EQ(1u, attrib_map
.size());
208 AttributeMap::const_iterator iter
= attrib_map
.find("vPosition");
209 EXPECT_TRUE(iter
!= attrib_map
.end());
210 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), iter
->second
.type
);
211 EXPECT_EQ(0u, iter
->second
.arraySize
);
212 EXPECT_EQ("vPosition", iter
->second
.name
);
215 TEST_F(ShaderTranslatorTest
, GetUniforms
) {
217 "precision mediump float;\n"
224 "uniform Bar bar[2];\n"
226 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
229 std::string info_log
, translated_source
;
230 AttributeMap attrib_map
;
231 UniformMap uniform_map
;
232 VaryingMap varying_map
;
234 EXPECT_TRUE(fragment_translator_
->Translate(shader
,
241 // Info log must be NULL.
242 EXPECT_TRUE(info_log
.empty());
243 // Translated shader must be valid and non-empty.
244 EXPECT_FALSE(translated_source
.empty());
245 // There should be no attributes.
246 EXPECT_TRUE(attrib_map
.empty());
247 // There should be two uniforms with following characteristics:
248 // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
249 // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
250 // However, there will be only one entry "bar" in the map.
251 EXPECT_EQ(1u, uniform_map
.size());
252 UniformMap::const_iterator iter
= uniform_map
.find("bar");
253 EXPECT_TRUE(iter
!= uniform_map
.end());
255 const sh::ShaderVariable
* info
;
256 std::string original_name
;
257 EXPECT_TRUE(iter
->second
.findInfoByMappedName(
258 "bar[0].foo.color[0]", &info
, &original_name
));
259 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), info
->type
);
260 EXPECT_EQ(1u, info
->arraySize
);
261 EXPECT_STREQ("color", info
->name
.c_str());
262 EXPECT_STREQ("bar[0].foo.color[0]", original_name
.c_str());
264 EXPECT_TRUE(iter
->second
.findInfoByMappedName(
265 "bar[1].foo.color[0]", &info
, &original_name
));
266 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), info
->type
);
267 EXPECT_EQ(1u, info
->arraySize
);
268 EXPECT_STREQ("color", info
->name
.c_str());
269 EXPECT_STREQ("bar[1].foo.color[0]", original_name
.c_str());
272 #if defined(OS_MACOSX)
273 TEST_F(ShaderTranslatorTest
, BuiltInFunctionEmulation
) {
274 // This test might become invalid in the future when ANGLE Translator is no
275 // longer emulate dot(float, float) in Mac, or the emulated function name is
276 // no longer webgl_dot_emu.
279 " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
282 std::string info_log
, translated_source
;
283 AttributeMap attrib_map
;
284 UniformMap uniform_map
;
285 VaryingMap varying_map
;
287 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
294 // Info log must be NULL.
295 EXPECT_TRUE(info_log
.empty());
296 // Translated shader must be valid and non-empty.
297 ASSERT_FALSE(translated_source
.empty());
298 EXPECT_TRUE(strstr(translated_source
.c_str(),
299 "webgl_dot_emu") != NULL
);
303 TEST_F(ShaderTranslatorTest
, OptionsString
) {
304 scoped_refptr
<ShaderTranslator
> translator_1
= new ShaderTranslator();
305 scoped_refptr
<ShaderTranslator
> translator_2
= new ShaderTranslator();
306 scoped_refptr
<ShaderTranslator
> translator_3
= new ShaderTranslator();
308 ShBuiltInResources resources
;
309 ShInitBuiltInResources(&resources
);
311 ASSERT_TRUE(translator_1
->Init(
312 GL_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
313 ShaderTranslatorInterface::kGlsl
,
314 SH_EMULATE_BUILT_IN_FUNCTIONS
));
315 ASSERT_TRUE(translator_2
->Init(
316 GL_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
317 ShaderTranslatorInterface::kGlsl
,
318 static_cast<ShCompileOptions
>(0)));
319 resources
.EXT_draw_buffers
= 1;
320 ASSERT_TRUE(translator_3
->Init(
321 GL_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
322 ShaderTranslatorInterface::kGlsl
,
323 SH_EMULATE_BUILT_IN_FUNCTIONS
));
325 std::string
options_1(
326 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
327 std::string
options_2(
328 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
329 std::string
options_3(
330 translator_2
->GetStringForOptionsThatWouldAffectCompilation());
331 std::string
options_4(
332 translator_3
->GetStringForOptionsThatWouldAffectCompilation());
334 EXPECT_EQ(options_1
, options_2
);
335 EXPECT_NE(options_1
, options_3
);
336 EXPECT_NE(options_1
, options_4
);
337 EXPECT_NE(options_3
, options_4
);