15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <GLES2/gl2ext.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_manager.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/tests/gl_test_utils.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SHADER(Src) #Src 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GLProgramTest : public testing::Test { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) gl_.Initialize(GLManager::Options()); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_.Destroy(); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLManager gl_; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLProgramTest, GetSetUniform) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* v_shader_str = SHADER( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute vec4 a_vertex; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute vec3 a_normal; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uniform mat4 u_modelViewProjMatrix; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct MyStruct 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int x; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int y; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uniform MyStruct u_struct; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uniform float u_array[4]; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varying vec3 v_normal; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) v_normal = a_normal; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_Position = u_modelViewProjMatrix * a_vertex + 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vec4(u_struct.x, u_struct.y, 0, 1) + 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vec4(u_array[0], u_array[1], u_array[2], u_array[3]); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* f_shader_str = SHADER( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) varying mediump vec3 v_normal; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_FragColor = vec4(v_normal/2.0+vec3(0.5), 1); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load the program. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUseProgram(program); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Relink program. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glLinkProgram(program); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // These tests will fail on NVidia if not worked around by 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // command buffer. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint location_sx = glGetUniformLocation(program, "u_struct.x"); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint location_array_0 = glGetUniformLocation(program, "u_array[0]"); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUniform1i(location_sx, 3); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUniform1f(location_array_0, 123); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint int_value = 0; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLfloat float_value = 0; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetUniformiv(program, location_sx, &int_value); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3, int_value); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glGetUniformfv(program, location_array_0, &float_value); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(123.0f, float_value); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLTestHelper::CheckGLError("no errors", __LINE__); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLProgramTest, NewShaderInCurrentProgram) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* v_shader_str = SHADER( 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute vec4 a_position; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_Position = a_position; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* f_red_shader_str = SHADER( 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_FragColor = vec4(1, 0, 0, 1); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* f_blue_shader_str = SHADER( 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_FragColor = vec4(0, 0, 1, 1); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load the program. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint vs = GLTestHelper::LoadShader(GL_VERTEX_SHADER, v_shader_str); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint fs = GLTestHelper::LoadShader(GL_FRAGMENT_SHADER, f_red_shader_str); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint program = GLTestHelper::SetupProgram(vs, fs); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUseProgram(program); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glShaderSource(fs, 1, &f_blue_shader_str, NULL); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glCompileShader(fs); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glLinkProgram(program); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We specifically don't call UseProgram again. 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint position_loc = glGetAttribLocation(program, "a_position"); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLTestHelper::SetupUnitQuad(position_loc); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glDrawArrays(GL_TRIANGLES, 0, 6); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 expected_color[] = { 0, 0, 255, 255, }; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color)); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLTestHelper::CheckGLError("no errors", __LINE__); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(GLProgramTest, UniformsInCurrentProgram) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* v_shader_str = SHADER( 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attribute vec4 a_position; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_Position = a_position; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* f_shader_str = SHADER( 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) precision mediump float; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uniform vec4 u_color; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void main() 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gl_FragColor = u_color;; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load the program. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint program = GLTestHelper::LoadProgram(v_shader_str, f_shader_str); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUseProgram(program); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Relink. 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glLinkProgram(program); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This test will fail on NVidia Linux if not worked around. 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLint color_location = glGetUniformLocation(program, "u_color"); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glUniform4f(color_location, 0.0f, 0.0f, 1.0f, 1.0f); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We specifically don't call UseProgram again. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLuint position_loc = glGetAttribLocation(program, "a_position"); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLTestHelper::SetupUnitQuad(position_loc); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) glDrawArrays(GL_TRIANGLES, 0, 6); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 expected_color[] = { 0, 0, 255, 255, }; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(GLTestHelper::CheckPixels(0, 0, 1, 1, 0, expected_color)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GLTestHelper::CheckGLError("no errors", __LINE__); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167