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