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
;
57 AttributeMap attrib_map
;
58 UniformMap uniform_map
;
59 VaryingMap varying_map
;
61 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
69 // Info log must be NULL.
70 EXPECT_TRUE(info_log
.empty());
71 // Translated shader must be valid and non-empty.
72 ASSERT_FALSE(translated_source
.empty());
73 // There should be no attributes, uniforms, and only one built-in
74 // varying: gl_Position.
75 EXPECT_TRUE(attrib_map
.empty());
76 EXPECT_TRUE(uniform_map
.empty());
77 EXPECT_EQ(1u, varying_map
.size());
78 // There should be no name mapping.
79 EXPECT_TRUE(name_map
.empty());
82 TEST_F(ShaderTranslatorTest
, InvalidVertexShader
) {
83 const char* bad_shader
= "foo-bar";
84 const char* good_shader
=
86 " gl_Position = vec4(1.0);\n"
89 // An invalid shader should fail.
90 std::string info_log
, translated_source
;
92 AttributeMap attrib_map
;
93 UniformMap uniform_map
;
94 VaryingMap varying_map
;
96 EXPECT_FALSE(vertex_translator_
->Translate(bad_shader
,
104 // Info log must be valid and non-empty.
105 ASSERT_FALSE(info_log
.empty());
106 // Translated shader must be NULL.
107 EXPECT_TRUE(translated_source
.empty());
108 // There should be no attributes, uniforms, varyings, or name mapping.
109 EXPECT_TRUE(attrib_map
.empty());
110 EXPECT_TRUE(uniform_map
.empty());
111 EXPECT_TRUE(varying_map
.empty());
112 EXPECT_TRUE(name_map
.empty());
114 // Try a good shader after bad.
116 EXPECT_TRUE(vertex_translator_
->Translate(good_shader
,
124 EXPECT_TRUE(info_log
.empty());
125 EXPECT_FALSE(translated_source
.empty());
128 TEST_F(ShaderTranslatorTest
, ValidFragmentShader
) {
131 " gl_FragColor = vec4(1.0);\n"
134 // A valid shader should be successfully translated.
135 std::string info_log
, translated_source
;
137 AttributeMap attrib_map
;
138 UniformMap uniform_map
;
139 VaryingMap varying_map
;
141 EXPECT_TRUE(fragment_translator_
->Translate(shader
,
149 // Info log must be NULL.
150 EXPECT_TRUE(info_log
.empty());
151 // Translated shader must be valid and non-empty.
152 ASSERT_FALSE(translated_source
.empty());
153 // There should be no attributes, uniforms, varyings, or name mapping.
154 EXPECT_TRUE(attrib_map
.empty());
155 EXPECT_TRUE(uniform_map
.empty());
156 EXPECT_TRUE(varying_map
.empty());
157 EXPECT_TRUE(name_map
.empty());
160 TEST_F(ShaderTranslatorTest
, InvalidFragmentShader
) {
161 const char* shader
= "foo-bar";
163 std::string info_log
, translated_source
;
165 AttributeMap attrib_map
;
166 UniformMap uniform_map
;
167 VaryingMap varying_map
;
169 // An invalid shader should fail.
170 EXPECT_FALSE(fragment_translator_
->Translate(shader
,
178 // Info log must be valid and non-empty.
179 EXPECT_FALSE(info_log
.empty());
180 // Translated shader must be NULL.
181 EXPECT_TRUE(translated_source
.empty());
182 // There should be no attributes or uniforms.
183 EXPECT_TRUE(attrib_map
.empty());
184 EXPECT_TRUE(uniform_map
.empty());
185 EXPECT_TRUE(varying_map
.empty());
186 EXPECT_TRUE(name_map
.empty());
189 TEST_F(ShaderTranslatorTest
, GetAttributes
) {
191 "attribute vec4 vPosition;\n"
193 " gl_Position = vPosition;\n"
196 std::string info_log
, translated_source
;
198 AttributeMap attrib_map
;
199 UniformMap uniform_map
;
200 VaryingMap varying_map
;
202 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
210 // Info log must be NULL.
211 EXPECT_TRUE(info_log
.empty());
212 // Translated shader must be valid and non-empty.
213 EXPECT_FALSE(translated_source
.empty());
214 // There should be no uniforms.
215 EXPECT_TRUE(uniform_map
.empty());
216 // There should be one attribute with following characteristics:
217 // name:vPosition type:GL_FLOAT_VEC4 size:0.
218 EXPECT_EQ(1u, attrib_map
.size());
219 AttributeMap::const_iterator iter
= attrib_map
.find("vPosition");
220 EXPECT_TRUE(iter
!= attrib_map
.end());
221 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), iter
->second
.type
);
222 EXPECT_EQ(0u, iter
->second
.arraySize
);
223 EXPECT_EQ("vPosition", iter
->second
.name
);
226 TEST_F(ShaderTranslatorTest
, GetUniforms
) {
228 "precision mediump float;\n"
235 "uniform Bar bar[2];\n"
237 " gl_FragColor = bar[0].foo.color[0] + bar[1].foo.color[0];\n"
240 std::string info_log
, translated_source
;
242 AttributeMap attrib_map
;
243 UniformMap uniform_map
;
244 VaryingMap varying_map
;
246 EXPECT_TRUE(fragment_translator_
->Translate(shader
,
254 // Info log must be NULL.
255 EXPECT_TRUE(info_log
.empty());
256 // Translated shader must be valid and non-empty.
257 EXPECT_FALSE(translated_source
.empty());
258 // There should be no attributes.
259 EXPECT_TRUE(attrib_map
.empty());
260 // There should be two uniforms with following characteristics:
261 // 1. name:bar[0].foo.color[0] type:GL_FLOAT_VEC4 size:1
262 // 2. name:bar[1].foo.color[0] type:GL_FLOAT_VEC4 size:1
263 // However, there will be only one entry "bar" in the map.
264 EXPECT_EQ(1u, uniform_map
.size());
265 UniformMap::const_iterator iter
= uniform_map
.find("bar");
266 EXPECT_TRUE(iter
!= uniform_map
.end());
268 const sh::ShaderVariable
* info
;
269 std::string original_name
;
270 EXPECT_TRUE(iter
->second
.findInfoByMappedName(
271 "bar[0].foo.color[0]", &info
, &original_name
));
272 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), info
->type
);
273 EXPECT_EQ(1u, info
->arraySize
);
274 EXPECT_STREQ("color", info
->name
.c_str());
275 EXPECT_STREQ("bar[0].foo.color[0]", original_name
.c_str());
277 EXPECT_TRUE(iter
->second
.findInfoByMappedName(
278 "bar[1].foo.color[0]", &info
, &original_name
));
279 EXPECT_EQ(static_cast<GLenum
>(GL_FLOAT_VEC4
), info
->type
);
280 EXPECT_EQ(1u, info
->arraySize
);
281 EXPECT_STREQ("color", info
->name
.c_str());
282 EXPECT_STREQ("bar[1].foo.color[0]", original_name
.c_str());
285 #if defined(OS_MACOSX)
286 TEST_F(ShaderTranslatorTest
, BuiltInFunctionEmulation
) {
287 // This test might become invalid in the future when ANGLE Translator is no
288 // longer emulate dot(float, float) in Mac, or the emulated function name is
289 // no longer webgl_dot_emu.
292 " gl_Position = vec4(dot(1.0, 1.0), 1.0, 1.0, 1.0);\n"
295 std::string info_log
, translated_source
;
297 AttributeMap attrib_map
;
298 UniformMap uniform_map
;
299 VaryingMap varying_map
;
301 EXPECT_TRUE(vertex_translator_
->Translate(shader
,
309 // Info log must be NULL.
310 EXPECT_TRUE(info_log
.empty());
311 // Translated shader must be valid and non-empty.
312 ASSERT_FALSE(translated_source
.empty());
313 EXPECT_TRUE(strstr(translated_source
.c_str(),
314 "webgl_dot_emu") != NULL
);
318 TEST_F(ShaderTranslatorTest
, OptionsString
) {
319 scoped_refptr
<ShaderTranslator
> translator_1
= new ShaderTranslator();
320 scoped_refptr
<ShaderTranslator
> translator_2
= new ShaderTranslator();
321 scoped_refptr
<ShaderTranslator
> translator_3
= new ShaderTranslator();
323 ShBuiltInResources resources
;
324 ShInitBuiltInResources(&resources
);
326 ASSERT_TRUE(translator_1
->Init(
327 GL_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
328 ShaderTranslatorInterface::kGlsl
,
329 SH_EMULATE_BUILT_IN_FUNCTIONS
));
330 ASSERT_TRUE(translator_2
->Init(
331 GL_FRAGMENT_SHADER
, SH_GLES2_SPEC
, &resources
,
332 ShaderTranslatorInterface::kGlsl
,
333 static_cast<ShCompileOptions
>(0)));
334 resources
.EXT_draw_buffers
= 1;
335 ASSERT_TRUE(translator_3
->Init(
336 GL_VERTEX_SHADER
, SH_GLES2_SPEC
, &resources
,
337 ShaderTranslatorInterface::kGlsl
,
338 SH_EMULATE_BUILT_IN_FUNCTIONS
));
340 std::string
options_1(
341 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
342 std::string
options_2(
343 translator_1
->GetStringForOptionsThatWouldAffectCompilation());
344 std::string
options_3(
345 translator_2
->GetStringForOptionsThatWouldAffectCompilation());
346 std::string
options_4(
347 translator_3
->GetStringForOptionsThatWouldAffectCompilation());
349 EXPECT_EQ(options_1
, options_2
);
350 EXPECT_NE(options_1
, options_3
);
351 EXPECT_NE(options_1
, options_4
);
352 EXPECT_NE(options_3
, options_4
);