Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_program_unittest.cc
blobef11ae4955fbfc814956c03ff1c8167dce24f2b5
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.
5 #include <GLES2/gl2.h>
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
17 namespace gpu {
19 class GLProgramTest : public testing::Test {
20 protected:
21 void SetUp() override { gl_.Initialize(GLManager::Options()); }
23 void TearDown() override { gl_.Destroy(); }
25 GLManager gl_;
28 class WebGLProgramTest : public GLProgramTest {
29 protected:
30 void SetUp() override {
31 GLManager::Options options;
32 options.webgl_version = 1;
33 gl_.Initialize(options);
37 TEST_F(GLProgramTest, GetSetUniform) {
38 static const char* v_shader_str = SHADER(
39 attribute vec4 a_vertex;
40 attribute vec3 a_normal;
42 uniform mat4 u_modelViewProjMatrix;
44 struct MyStruct
46 int x;
47 int y;
50 uniform MyStruct u_struct;
51 uniform float u_array[4];
53 varying vec3 v_normal;
55 void main()
57 v_normal = a_normal;
58 gl_Position = u_modelViewProjMatrix * a_vertex +
59 vec4(u_struct.x, u_struct.y, 0, 1) +
60 vec4(u_array[0], u_array[1], u_array[2], u_array[3]);
63 static const char* f_shader_str = SHADER(
64 varying mediump vec3 v_normal;
66 void main()
68 gl_FragColor = vec4(v_normal/2.0+vec3(0.5), 1);
72 // Load the program.
73 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
74 glUseProgram(program);
75 // Relink program.
76 glLinkProgram(program);
78 // These tests will fail on NVidia if not worked around by
79 // command buffer.
80 GLint location_sx = glGetUniformLocation(program, "u_struct.x");
81 GLint location_array_0 = glGetUniformLocation(program, "u_array[0]");
83 glUniform1i(location_sx, 3);
84 glUniform1f(location_array_0, 123);
86 GLint int_value = 0;
87 GLfloat float_value = 0;
89 glGetUniformiv(program, location_sx, &int_value);
90 EXPECT_EQ(3, int_value);
91 glGetUniformfv(program, location_array_0, &float_value);
92 EXPECT_EQ(123.0f, float_value);
94 GLTestHelper::CheckGLError("no errors", __LINE__);
97 TEST_F(GLProgramTest, NewShaderInCurrentProgram) {
98 static const char* v_shader_str = SHADER(
99 attribute vec4 a_position;
100 void main()
102 gl_Position = a_position;
105 static const char* f_red_shader_str = SHADER(
106 void main()
108 gl_FragColor = vec4(1, 0, 0, 1);
111 static const char* f_blue_shader_str = SHADER(
112 void main()
114 gl_FragColor = vec4(0, 0, 1, 1);
118 // Load the program.
119 GLuint vs = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shader_str);
120 GLuint fs = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_red_shader_str);
121 GLuint program = GLTestHelper::SetupProgram(vs, fs);
122 glUseProgram(program);
123 glShaderSource(fs, 1, &f_blue_shader_str, NULL);
124 glCompileShader(fs);
125 glLinkProgram(program);
126 // We specifically don't call UseProgram again.
127 GLuint position_loc = glGetAttribLocation(program, "a_position");
128 GLTestHelper::SetupUnitQuad(position_loc);
129 glDrawArrays(GL_TRIANGLES, 0, 6);
130 uint8 expected_color[] = { 0, 0, 255, 255, };
131 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color));
132 GLTestHelper::CheckGLError("no errors", __LINE__);
135 TEST_F(GLProgramTest, ShaderLengthSpecified) {
136 const std::string valid_shader_str = SHADER(
137 attribute vec4 a_position;
138 void main()
140 gl_Position = a_position;
144 const std::string invalid_shader = valid_shader_str + "invalid suffix";
146 // Compiling invalid program should fail.
147 const char* invalid_shader_strings[] = { invalid_shader.c_str() };
148 GLuint vs = glCreateShader(GL_VERTEX_SHADER);
149 glShaderSource(vs, 1, invalid_shader_strings, NULL);
150 glCompileShader(vs);
152 GLint compile_state = 0;
153 glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state);
154 EXPECT_EQ(GL_FALSE, compile_state);
156 // Compiling program cutting off invalid parts should succeed.
157 const GLint lengths[] = { valid_shader_str.length() };
158 glShaderSource(vs, 1, invalid_shader_strings, lengths);
159 glCompileShader(vs);
160 glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state);
161 EXPECT_EQ(GL_TRUE, compile_state);
164 TEST_F(GLProgramTest, UniformsInCurrentProgram) {
165 static const char* v_shader_str = SHADER(
166 attribute vec4 a_position;
167 void main()
169 gl_Position = a_position;
172 static const char* f_shader_str = SHADER(
173 precision mediump float;
174 uniform vec4 u_color;
175 void main()
177 gl_FragColor = u_color;;
181 // Load the program.
182 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
183 glUseProgram(program);
185 // Relink.
186 glLinkProgram(program);
188 // This test will fail on NVidia Linux if not worked around.
189 GLint color_location = glGetUniformLocation(program, "u_color");
190 glUniform4f(color_location, 0.0f, 0.0f, 1.0f, 1.0f);
192 // We specifically don't call UseProgram again.
193 GLuint position_loc = glGetAttribLocation(program, "a_position");
194 GLTestHelper::SetupUnitQuad(position_loc);
195 glDrawArrays(GL_TRIANGLES, 0, 6);
196 uint8 expected_color[] = { 0, 0, 255, 255, };
197 EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color));
198 GLTestHelper::CheckGLError("no errors", __LINE__);
201 TEST_F(WebGLProgramTest, DeferCompileWithExt) {
202 // This test must have extensions enabled.
203 gles2::ContextGroup* context_group = gl_.decoder()->GetContextGroup();
204 gles2::FeatureInfo* feature_info = context_group->feature_info();
205 const gles2::FeatureInfo::FeatureFlags& flags = feature_info->feature_flags();
206 if (!flags.ext_frag_depth)
207 return;
209 static const char* v_shdr_str = R"(
210 attribute vec4 vPosition;
211 void main()
213 gl_Position = vPosition;
216 static const char* f_shdr_str = R"(
217 #extension GL_EXT_frag_depth : enable
218 void main()
220 gl_FragDepthEXT = 1.0;
224 // Extension is disabled by default and be sure shader does not compile.
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 // linking bad compilations with extension enabled should still not link.
233 glRequestExtensionCHROMIUM("GL_EXT_frag_depth");
234 program_bad = GLTestHelper::LinkProgram(vs_bad, fs_bad);
235 linked_bad = 0;
236 glGetProgramiv(program_bad, GL_LINK_STATUS, &linked_bad);
237 EXPECT_EQ(0, linked_bad);
239 // Be sure extension was actually turned on by recompiling.
240 GLuint vs_good = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shdr_str);
241 GLuint fs_good = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_shdr_str);
242 GLuint program_good = GLTestHelper::SetupProgram(vs_good, fs_good);
243 EXPECT_NE(0u, program_good);
246 TEST_F(GLProgramTest, DeleteAttachedShaderLinks) {
247 static const char* v_shdr_str = R"(
248 attribute vec4 vPosition;
249 void main()
251 gl_Position = vPosition;
254 static const char* f_shdr_str = R"(
255 void main()
257 gl_FragColor = vec4(1, 1, 1, 1);
261 // Compiling the shaders, attaching, then deleting before linking should work.
262 GLuint vs = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
263 GLuint fs = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
265 GLuint program = glCreateProgram();
266 glAttachShader(program, vs);
267 glAttachShader(program, fs);
269 glDeleteShader(vs);
270 glDeleteShader(fs);
272 glLinkProgram(program);
274 GLint linked = 0;
275 glGetProgramiv(program, GL_LINK_STATUS, &linked);
276 EXPECT_NE(0, linked);
279 } // namespace gpu