We started redesigning GpuMemoryBuffer interface to handle multiple buffers [0].
[chromium-blink-merge.git] / gpu / command_buffer / tests / gl_program_unittest.cc
blobc0abb12aa81688a9d60fd55ebca18f6e92bc8fee
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 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;
35 struct MyStruct
37 int x;
38 int y;
41 uniform MyStruct u_struct;
42 uniform float u_array[4];
44 varying vec3 v_normal;
46 void main()
48 v_normal = a_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;
57 void main()
59 gl_FragColor = vec4(v_normal/2.0+vec3(0.5), 1);
63 // Load the program.
64 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
65 glUseProgram(program);
66 // Relink program.
67 glLinkProgram(program);
69 // These tests will fail on NVidia if not worked around by
70 // command buffer.
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);
77 GLint int_value = 0;
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;
91 void main()
93 gl_Position = a_position;
96 static const char* f_red_shader_str = SHADER(
97 void main()
99 gl_FragColor = vec4(1, 0, 0, 1);
102 static const char* f_blue_shader_str = SHADER(
103 void main()
105 gl_FragColor = vec4(0, 0, 1, 1);
109 // Load the program.
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);
115 glCompileShader(fs);
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;
129 void main()
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);
141 glCompileShader(vs);
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);
150 glCompileShader(vs);
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;
158 void main()
160 gl_Position = a_position;
163 static const char* f_shader_str = SHADER(
164 precision mediump float;
165 uniform vec4 u_color;
166 void main()
168 gl_FragColor = u_color;;
172 // Load the program.
173 GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
174 glUseProgram(program);
176 // Relink.
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)
198 return;
200 static const char* v_shdr_str = R"(
201 attribute vec4 vPosition;
202 void main()
204 gl_Position = vPosition;
207 static const char* f_shdr_str = R"(
208 #extension GL_EXT_frag_depth : enable
209 void main()
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;
257 void main()
259 gl_Position = vPosition;
262 static const char* f_shdr_str = R"(
263 void main()
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);
277 glDeleteShader(vs);
278 glDeleteShader(fs);
280 glLinkProgram(program);
282 GLint linked = 0;
283 glGetProgramiv(program, GL_LINK_STATUS, &linked);
284 EXPECT_NE(0, linked);
287 } // namespace gpu