1 // Copyright 2014 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.
6 #include <GLES2/gl2ext.h>
7 #include <GLES2/gl2extchromium.h>
9 #include "gpu/command_buffer/service/context_group.h"
10 #include "gpu/command_buffer/tests/gl_manager.h"
11 #include "gpu/command_buffer/tests/gl_test_utils.h"
12 #include "testing/gmock/include/gmock/gmock.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 #define SHADER(Src) #Src
19 class GLProgramTest
: public testing::Test
{
21 void SetUp() override
{ gl_
.Initialize(GLManager::Options()); }
23 void TearDown() override
{ gl_
.Destroy(); }
28 TEST_F(GLProgramTest
, GetSetUniform
) {
29 static const char* v_shader_str
= SHADER(
30 attribute vec4 a_vertex
;
31 attribute vec3 a_normal
;
33 uniform mat4 u_modelViewProjMatrix
;
41 uniform MyStruct u_struct
;
42 uniform
float u_array
[4];
44 varying vec3 v_normal
;
49 gl_Position
= u_modelViewProjMatrix
* a_vertex
+
50 vec4(u_struct
.x
, u_struct
.y
, 0, 1) +
51 vec4(u_array
[0], u_array
[1], u_array
[2], u_array
[3]);
54 static const char* f_shader_str
= SHADER(
55 varying mediump vec3 v_normal
;
59 gl_FragColor
= vec4(v_normal
/2.0+vec3(0.5), 1);
64 GLuint program
= GLTestHelper::LoadProgram(v_shader_str
, f_shader_str
);
65 glUseProgram(program
);
67 glLinkProgram(program
);
69 // These tests will fail on NVidia if not worked around by
71 GLint location_sx
= glGetUniformLocation(program
, "u_struct.x");
72 GLint location_array_0
= glGetUniformLocation(program
, "u_array[0]");
74 glUniform1i(location_sx
, 3);
75 glUniform1f(location_array_0
, 123);
78 GLfloat float_value
= 0;
80 glGetUniformiv(program
, location_sx
, &int_value
);
81 EXPECT_EQ(3, int_value
);
82 glGetUniformfv(program
, location_array_0
, &float_value
);
83 EXPECT_EQ(123.0f
, float_value
);
85 GLTestHelper::CheckGLError("no errors", __LINE__
);
88 TEST_F(GLProgramTest
, NewShaderInCurrentProgram
) {
89 static const char* v_shader_str
= SHADER(
90 attribute vec4 a_position
;
93 gl_Position
= a_position
;
96 static const char* f_red_shader_str
= SHADER(
99 gl_FragColor
= vec4(1, 0, 0, 1);
102 static const char* f_blue_shader_str
= SHADER(
105 gl_FragColor
= vec4(0, 0, 1, 1);
110 GLuint vs
= GLTestHelper::LoadShader(GL_VERTEX_SHADER
, v_shader_str
);
111 GLuint fs
= GLTestHelper::LoadShader(GL_FRAGMENT_SHADER
, f_red_shader_str
);
112 GLuint program
= GLTestHelper::SetupProgram(vs
, fs
);
113 glUseProgram(program
);
114 glShaderSource(fs
, 1, &f_blue_shader_str
, NULL
);
116 glLinkProgram(program
);
117 // We specifically don't call UseProgram again.
118 GLuint position_loc
= glGetAttribLocation(program
, "a_position");
119 GLTestHelper::SetupUnitQuad(position_loc
);
120 glDrawArrays(GL_TRIANGLES
, 0, 6);
121 uint8 expected_color
[] = { 0, 0, 255, 255, };
122 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color
));
123 GLTestHelper::CheckGLError("no errors", __LINE__
);
126 TEST_F(GLProgramTest
, ShaderLengthSpecified
) {
127 const std::string valid_shader_str
= SHADER(
128 attribute vec4 a_position
;
131 gl_Position
= a_position
;
135 const std::string invalid_shader
= valid_shader_str
+ "invalid suffix";
137 // Compiling invalid program should fail.
138 const char* invalid_shader_strings
[] = { invalid_shader
.c_str() };
139 GLuint vs
= glCreateShader(GL_VERTEX_SHADER
);
140 glShaderSource(vs
, 1, invalid_shader_strings
, NULL
);
143 GLint compile_state
= 0;
144 glGetShaderiv(vs
, GL_COMPILE_STATUS
, &compile_state
);
145 EXPECT_EQ(GL_FALSE
, compile_state
);
147 // Compiling program cutting off invalid parts should succeed.
148 const GLint lengths
[] = { valid_shader_str
.length() };
149 glShaderSource(vs
, 1, invalid_shader_strings
, lengths
);
151 glGetShaderiv(vs
, GL_COMPILE_STATUS
, &compile_state
);
152 EXPECT_EQ(GL_TRUE
, compile_state
);
155 TEST_F(GLProgramTest
, UniformsInCurrentProgram
) {
156 static const char* v_shader_str
= SHADER(
157 attribute vec4 a_position
;
160 gl_Position
= a_position
;
163 static const char* f_shader_str
= SHADER(
164 precision mediump
float;
165 uniform vec4 u_color
;
168 gl_FragColor
= u_color
;;
173 GLuint program
= GLTestHelper::LoadProgram(v_shader_str
, f_shader_str
);
174 glUseProgram(program
);
177 glLinkProgram(program
);
179 // This test will fail on NVidia Linux if not worked around.
180 GLint color_location
= glGetUniformLocation(program
, "u_color");
181 glUniform4f(color_location
, 0.0f
, 0.0f
, 1.0f
, 1.0f
);
183 // We specifically don't call UseProgram again.
184 GLuint position_loc
= glGetAttribLocation(program
, "a_position");
185 GLTestHelper::SetupUnitQuad(position_loc
);
186 glDrawArrays(GL_TRIANGLES
, 0, 6);
187 uint8 expected_color
[] = { 0, 0, 255, 255, };
188 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color
));
189 GLTestHelper::CheckGLError("no errors", __LINE__
);
192 TEST_F(GLProgramTest
, DeferCompileWithExt
) {
193 // This test must have extensions enabled.
194 gles2::ContextGroup
* context_group
= gl_
.decoder()->GetContextGroup();
195 gles2::FeatureInfo
* feature_info
= context_group
->feature_info();
196 const gles2::FeatureInfo::FeatureFlags
& flags
= feature_info
->feature_flags();
197 if (!flags
.ext_frag_depth
)
200 static const char* v_shdr_str
= R
"(
201 attribute vec4 vPosition;
204 gl_Position = vPosition;
207 static const char* f_shdr_str
= R
"(
208 #extension GL_EXT_frag_depth : enable
211 gl_FragDepthEXT = 1.0;
215 // First compile and link to be shader compiles.
216 GLuint vs_good
= GLTestHelper::CompileShader(GL_VERTEX_SHADER
, v_shdr_str
);
217 GLuint fs_good
= GLTestHelper::CompileShader(GL_FRAGMENT_SHADER
, f_shdr_str
);
218 GLuint program_good
= GLTestHelper::LinkProgram(vs_good
, fs_good
);
219 GLint linked_good
= 0;
220 glGetProgramiv(program_good
, GL_LINK_STATUS
, &linked_good
);
221 EXPECT_NE(0, linked_good
);
223 // Disable extension and be sure shader no longer compiles.
224 ASSERT_TRUE(glEnableFeatureCHROMIUM("webgl_enable_glsl_webgl_validation"));
225 GLuint vs_bad
= GLTestHelper::CompileShader(GL_VERTEX_SHADER
, v_shdr_str
);
226 GLuint fs_bad
= GLTestHelper::CompileShader(GL_FRAGMENT_SHADER
, f_shdr_str
);
227 GLuint program_bad
= GLTestHelper::LinkProgram(vs_bad
, fs_bad
);
228 GLint linked_bad
= 0;
229 glGetProgramiv(program_bad
, GL_LINK_STATUS
, &linked_bad
);
230 EXPECT_EQ(0, linked_bad
);
232 // Relinking good compilations without extension disabled should still link.
233 GLuint program_defer_good
= GLTestHelper::LinkProgram(vs_good
, fs_good
);
234 GLint linked_defer_good
= 0;
235 glGetProgramiv(program_defer_good
, GL_LINK_STATUS
, &linked_defer_good
);
236 EXPECT_NE(0, linked_defer_good
);
238 // linking bad compilations with extension enabled should still not link.
239 GLuint vs_bad2
= GLTestHelper::CompileShader(GL_VERTEX_SHADER
, v_shdr_str
);
240 GLuint fs_bad2
= GLTestHelper::CompileShader(GL_FRAGMENT_SHADER
, f_shdr_str
);
241 glRequestExtensionCHROMIUM("GL_EXT_frag_depth");
242 GLuint program_bad2
= GLTestHelper::LinkProgram(vs_bad2
, fs_bad2
);
243 GLint linked_bad2
= 0;
244 glGetProgramiv(program_bad2
, GL_LINK_STATUS
, &linked_bad2
);
245 EXPECT_EQ(0, linked_bad2
);
247 // Be sure extension was actually turned on by recompiling.
248 GLuint vs_good2
= GLTestHelper::LoadShader(GL_VERTEX_SHADER
, v_shdr_str
);
249 GLuint fs_good2
= GLTestHelper::LoadShader(GL_FRAGMENT_SHADER
, f_shdr_str
);
250 GLuint program_good2
= GLTestHelper::SetupProgram(vs_good2
, fs_good2
);
251 EXPECT_NE(0u, program_good2
);
254 TEST_F(GLProgramTest
, DeleteAttachedShaderLinks
) {
255 static const char* v_shdr_str
= R
"(
256 attribute vec4 vPosition;
259 gl_Position = vPosition;
262 static const char* f_shdr_str
= R
"(
265 gl_FragColor = vec4(1, 1, 1, 1);
269 // Compiling the shaders, attaching, then deleting before linking should work.
270 GLuint vs
= GLTestHelper::CompileShader(GL_VERTEX_SHADER
, v_shdr_str
);
271 GLuint fs
= GLTestHelper::CompileShader(GL_FRAGMENT_SHADER
, f_shdr_str
);
273 GLuint program
= glCreateProgram();
274 glAttachShader(program
, vs
);
275 glAttachShader(program
, fs
);
280 glLinkProgram(program
);
283 glGetProgramiv(program
, GL_LINK_STATUS
, &linked
);
284 EXPECT_NE(0, linked
);