123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286 |
- // Copyright 2014 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include <GLES2/gl2.h>
- #include <GLES2/gl2ext.h>
- #include <GLES2/gl2extchromium.h>
- #include <stdint.h>
- #include "gpu/command_buffer/service/context_group.h"
- #include "gpu/command_buffer/tests/gl_manager.h"
- #include "gpu/command_buffer/tests/gl_test_utils.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- #define SHADER(Src) #Src
- namespace gpu {
- class GLProgramTest : public testing::Test {
- protected:
- void SetUp() override { gl_.Initialize(GLManager::Options()); }
- void TearDown() override { gl_.Destroy(); }
- GLManager gl_;
- };
- class WebGLProgramTest : public GLProgramTest {
- protected:
- void SetUp() override {
- GLManager::Options options;
- options.context_type = CONTEXT_TYPE_WEBGL1;
- gl_.Initialize(options);
- }
- };
- TEST_F(GLProgramTest, GetSetUniform) {
- static const char* v_shader_str = SHADER(
- attribute vec4 a_vertex;
- attribute vec3 a_normal;
- uniform mat4 u_modelViewProjMatrix;
- struct MyStruct
- {
- int x;
- int y;
- };
- uniform MyStruct u_struct;
- uniform float u_array[4];
- varying vec3 v_normal;
- void main()
- {
- v_normal = a_normal;
- gl_Position = u_modelViewProjMatrix * a_vertex +
- vec4(u_struct.x, u_struct.y, 0, 1) +
- vec4(u_array[0], u_array[1], u_array[2], u_array[3]);
- }
- );
- static const char* f_shader_str = SHADER(
- varying mediump vec3 v_normal;
- void main()
- {
- gl_FragColor = vec4(v_normal/2.0+vec3(0.5), 1);
- }
- );
- // Load the program.
- GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
- glUseProgram(program);
- // Relink program.
- glLinkProgram(program);
- // These tests will fail on NVidia if not worked around by
- // command buffer.
- GLint location_sx = glGetUniformLocation(program, "u_struct.x");
- GLint location_array_0 = glGetUniformLocation(program, "u_array[0]");
- glUniform1i(location_sx, 3);
- glUniform1f(location_array_0, 123);
- GLint int_value = 0;
- GLfloat float_value = 0;
- glGetUniformiv(program, location_sx, &int_value);
- EXPECT_EQ(3, int_value);
- glGetUniformfv(program, location_array_0, &float_value);
- EXPECT_EQ(123.0f, float_value);
- GLTestHelper::CheckGLError("no errors", __LINE__);
- }
- TEST_F(GLProgramTest, NewShaderInCurrentProgram) {
- static const char* v_shader_str = SHADER(
- attribute vec4 a_position;
- void main()
- {
- gl_Position = a_position;
- }
- );
- static const char* f_red_shader_str = SHADER(
- void main()
- {
- gl_FragColor = vec4(1, 0, 0, 1);
- }
- );
- static const char* f_blue_shader_str = SHADER(
- void main()
- {
- gl_FragColor = vec4(0, 0, 1, 1);
- }
- );
- // Load the program.
- GLuint vs = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shader_str);
- GLuint fs = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_red_shader_str);
- GLuint program = GLTestHelper::SetupProgram(vs, fs);
- glUseProgram(program);
- glShaderSource(fs, 1, &f_blue_shader_str, nullptr);
- glCompileShader(fs);
- glLinkProgram(program);
- // We specifically don't call UseProgram again.
- GLuint position_loc = glGetAttribLocation(program, "a_position");
- GLTestHelper::SetupUnitQuad(position_loc);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- uint8_t expected_color[] = {
- 0, 0, 255, 255,
- };
- EXPECT_TRUE(
- GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr));
- GLTestHelper::CheckGLError("no errors", __LINE__);
- }
- TEST_F(GLProgramTest, ShaderLengthSpecified) {
- const std::string valid_shader_str = SHADER(
- attribute vec4 a_position;
- void main()
- {
- gl_Position = a_position;
- }
- );
- const std::string invalid_shader = valid_shader_str + "invalid suffix";
- // Compiling invalid program should fail.
- const char* invalid_shader_strings[] = { invalid_shader.c_str() };
- GLuint vs = glCreateShader(GL_VERTEX_SHADER);
- glShaderSource(vs, 1, invalid_shader_strings, nullptr);
- glCompileShader(vs);
- GLint compile_state = 0;
- glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state);
- EXPECT_EQ(GL_FALSE, compile_state);
- // Compiling program cutting off invalid parts should succeed.
- const GLint lengths[] = {static_cast<GLint>(valid_shader_str.length())};
- glShaderSource(vs, 1, invalid_shader_strings, lengths);
- glCompileShader(vs);
- glGetShaderiv(vs, GL_COMPILE_STATUS, &compile_state);
- EXPECT_EQ(GL_TRUE, compile_state);
- }
- TEST_F(GLProgramTest, UniformsInCurrentProgram) {
- static const char* v_shader_str = SHADER(
- attribute vec4 a_position;
- void main()
- {
- gl_Position = a_position;
- }
- );
- static const char* f_shader_str = SHADER(
- precision mediump float;
- uniform vec4 u_color;
- void main()
- {
- gl_FragColor = u_color;
- }
- );
- // Load the program.
- GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str);
- glUseProgram(program);
- // Relink.
- glLinkProgram(program);
- // This test will fail on NVidia Linux if not worked around.
- GLint color_location = glGetUniformLocation(program, "u_color");
- glUniform4f(color_location, 0.0f, 0.0f, 1.0f, 1.0f);
- // We specifically don't call UseProgram again.
- GLuint position_loc = glGetAttribLocation(program, "a_position");
- GLTestHelper::SetupUnitQuad(position_loc);
- glDrawArrays(GL_TRIANGLES, 0, 6);
- uint8_t expected_color[] = {
- 0, 0, 255, 255,
- };
- EXPECT_TRUE(
- GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color, nullptr));
- GLTestHelper::CheckGLError("no errors", __LINE__);
- }
- TEST_F(WebGLProgramTest, DeferCompileWithExt) {
- // This test must have extensions enabled.
- gles2::ContextGroup* context_group = gl_.decoder()->GetContextGroup();
- gles2::FeatureInfo* feature_info = context_group->feature_info();
- const gles2::FeatureInfo::FeatureFlags& flags = feature_info->feature_flags();
- if (!flags.ext_frag_depth)
- return;
- static const char* v_shdr_str = R"(
- attribute vec4 vPosition;
- void main()
- {
- gl_Position = vPosition;
- }
- )";
- static const char* f_shdr_str = R"(
- #extension GL_EXT_frag_depth : enable
- void main()
- {
- gl_FragDepthEXT = 1.0;
- }
- )";
- // Extension is disabled by default and be sure shader does not compile.
- GLuint vs_bad = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
- GLuint fs_bad = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
- GLuint program_bad = GLTestHelper::LinkProgram(vs_bad, fs_bad);
- GLint linked_bad = 0;
- glGetProgramiv(program_bad, GL_LINK_STATUS, &linked_bad);
- EXPECT_EQ(0, linked_bad);
- // linking bad compilations with extension enabled should still not link.
- glRequestExtensionCHROMIUM("GL_EXT_frag_depth");
- program_bad = GLTestHelper::LinkProgram(vs_bad, fs_bad);
- linked_bad = 0;
- glGetProgramiv(program_bad, GL_LINK_STATUS, &linked_bad);
- EXPECT_EQ(0, linked_bad);
- // Be sure extension was actually turned on by recompiling.
- GLuint vs_good = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shdr_str);
- GLuint fs_good = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_shdr_str);
- GLuint program_good = GLTestHelper::SetupProgram(vs_good, fs_good);
- EXPECT_NE(0u, program_good);
- }
- TEST_F(GLProgramTest, DeleteAttachedShaderLinks) {
- static const char* v_shdr_str = R"(
- attribute vec4 vPosition;
- void main()
- {
- gl_Position = vPosition;
- }
- )";
- static const char* f_shdr_str = R"(
- void main()
- {
- gl_FragColor = vec4(1, 1, 1, 1);
- }
- )";
- // Compiling the shaders, attaching, then deleting before linking should work.
- GLuint vs = GLTestHelper::CompileShader(GL_VERTEX_SHADER, v_shdr_str);
- GLuint fs = GLTestHelper::CompileShader(GL_FRAGMENT_SHADER, f_shdr_str);
- GLuint program = glCreateProgram();
- glAttachShader(program, vs);
- glAttachShader(program, fs);
- glDeleteShader(vs);
- glDeleteShader(fs);
- glLinkProgram(program);
- GLint linked = 0;
- glGetProgramiv(program, GL_LINK_STATUS, &linked);
- EXPECT_NE(0, linked);
- }
- } // namespace gpu
|