1// Copyright (c) 2010 The Chromium OS 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.
4
5#include "main.h"
6#include "testbase.h"
7#include "utils.h"
8
9
10namespace glbench {
11
12
13class VaryingsAndDdxyShaderTest : public DrawElementsTestFunc {
14 public:
15  VaryingsAndDdxyShaderTest() {}
16  virtual ~VaryingsAndDdxyShaderTest() {}
17  virtual bool Run();
18  virtual const char* Name() const { return "varyings_ddx_shader"; }
19  virtual const char* Unit() const { return "mpixels_sec"; }
20
21 private:
22  DISALLOW_COPY_AND_ASSIGN(VaryingsAndDdxyShaderTest);
23};
24
25const char *vertex_shader_1_varying =
26"attribute vec4 c;"
27"varying vec4 v1;"
28"void main() {"
29"  gl_Position = c;"
30"  v1 = c;"
31"}";
32
33const char *vertex_shader_2_varying =
34"attribute vec4 c;"
35"varying vec4 v1;"
36"varying vec4 v2;"
37"void main() {"
38"  gl_Position = c;"
39"  v1 = v2 = c/2.;"
40"}";
41
42const char *vertex_shader_4_varying =
43"attribute vec4 c;"
44"varying vec4 v1;"
45"varying vec4 v2;"
46"varying vec4 v3;"
47"varying vec4 v4;"
48"void main() {"
49"  gl_Position = c;"
50"  v1 = v2 = v3 = v4 = c/4.;"
51"}";
52
53const char *vertex_shader_8_varying =
54"attribute vec4 c;"
55"varying vec4 v1;"
56"varying vec4 v2;"
57"varying vec4 v3;"
58"varying vec4 v4;"
59"varying vec4 v5;"
60"varying vec4 v6;"
61"varying vec4 v7;"
62"varying vec4 v8;"
63"void main() {"
64"  gl_Position = c;"
65"  v1 = v2 = v3 = v4 = v5 = v6 = v7 = v8 = c/8.;"
66"}";
67
68const char *fragment_shader_1_varying =
69"varying vec4 v1;"
70"void main() {"
71"  gl_FragColor = v1;"
72"}";
73
74const char *fragment_shader_2_varying =
75"varying vec4 v1;"
76"varying vec4 v2;"
77"void main() {"
78"  gl_FragColor = v1 + v2;"
79"}";
80
81const char *fragment_shader_4_varying =
82"varying vec4 v1;"
83"varying vec4 v2;"
84"varying vec4 v3;"
85"varying vec4 v4;"
86"void main() {"
87"  gl_FragColor = v1 + v2 + v3 + v4;"
88"}";
89
90const char *fragment_shader_8_varying =
91"varying vec4 v1;"
92"varying vec4 v2;"
93"varying vec4 v3;"
94"varying vec4 v4;"
95"varying vec4 v5;"
96"varying vec4 v6;"
97"varying vec4 v7;"
98"varying vec4 v8;"
99"void main() {"
100"  gl_FragColor = v1 + v2 + v3 + v4 + v5 + v6 + v7 + v8;"
101"}";
102
103GLuint VaryingsShaderProgram(int varyings_count, GLuint vertex_buffer) {
104  const char *vertex_shader = NULL;
105  const char *fragment_shader = NULL;
106  switch (varyings_count) {
107    case 1:
108      vertex_shader = vertex_shader_1_varying;
109      fragment_shader = fragment_shader_1_varying;
110      break;
111    case 2:
112      vertex_shader = vertex_shader_2_varying;
113      fragment_shader = fragment_shader_2_varying;
114      break;
115    case 4:
116      vertex_shader = vertex_shader_4_varying;
117      fragment_shader = fragment_shader_4_varying;
118      break;
119    case 8:
120      vertex_shader = vertex_shader_8_varying;
121      fragment_shader = fragment_shader_8_varying;
122      break;
123    default: return 0;
124  }
125  GLuint program =
126    InitShaderProgram(vertex_shader, fragment_shader);
127
128  int attribute_index = glGetAttribLocation(program, "c");
129  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
130  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
131  glEnableVertexAttribArray(attribute_index);
132
133  return program;
134}
135
136
137const char *fragment_shader_ddx =
138"#extension GL_OES_standard_derivatives : enable\n"
139"varying vec4 v1;"
140"void main() {"
141"  gl_FragColor = vec4(dFdx(v1.x), 0., 0., 1.);"
142"}";
143
144const char *fragment_shader_ddy =
145"#extension GL_OES_standard_derivatives : enable\n"
146"varying vec4 v1;"
147"void main() {"
148"  gl_FragColor = vec4(dFdy(v1.y), 0., 0., 1.);"
149"}";
150
151GLuint DdxDdyShaderProgram(bool ddx, GLuint vertex_buffer) {
152  GLuint program =
153    InitShaderProgram(vertex_shader_1_varying,
154                      ddx ? fragment_shader_ddx : fragment_shader_ddy);
155
156  int attribute_index = glGetAttribLocation(program, "c");
157  glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
158  glVertexAttribPointer(attribute_index, 2, GL_FLOAT, GL_FALSE, 0, NULL);
159  glEnableVertexAttribArray(attribute_index);
160
161  return program;
162}
163
164
165bool VaryingsAndDdxyShaderTest::Run() {
166  glViewport(0, 0, g_width, g_height);
167
168  const int c = 4;
169  GLfloat *vertices = NULL;
170  GLsizeiptr vertex_buffer_size = 0;
171  CreateLattice(&vertices, &vertex_buffer_size, 1.f / c, 1.f / c, c, c);
172  GLuint vertex_buffer = SetupVBO(GL_ARRAY_BUFFER,
173                                  vertex_buffer_size, vertices);
174
175  GLushort *indices = NULL;
176  GLuint index_buffer = 0;
177  GLsizeiptr index_buffer_size = 0;
178
179  count_ = CreateMesh(&indices, &index_buffer_size, c, c, 0);
180  index_buffer = SetupVBO(GL_ELEMENT_ARRAY_BUFFER,
181                          index_buffer_size, indices);
182
183  GLuint program = VaryingsShaderProgram(1, vertex_buffer);
184  RunTest(this,
185          "varyings_shader_1", g_width * g_height, g_width, g_height, true);
186  glDeleteProgram(program);
187
188  program = VaryingsShaderProgram(2, vertex_buffer);
189  RunTest(this,
190          "varyings_shader_2", g_width * g_height, g_width, g_height, true);
191  glDeleteProgram(program);
192
193  program = VaryingsShaderProgram(4, vertex_buffer);
194  RunTest(this,
195          "varyings_shader_4", g_width * g_height, g_width, g_height, true);
196  glDeleteProgram(program);
197
198  program = VaryingsShaderProgram(8, vertex_buffer);
199  RunTest(this,
200          "varyings_shader_8", g_width * g_height, g_width, g_height, true);
201  glDeleteProgram(program);
202
203#if !defined(DISABLE_SOME_TESTS_FOR_INTEL_DRIVER)
204  program = DdxDdyShaderProgram(true, vertex_buffer);
205  RunTest(this, "ddx_shader", g_width * g_height, g_width, g_height, true);
206  glDeleteProgram(program);
207
208  program = DdxDdyShaderProgram(false, vertex_buffer);
209  RunTest(this, "ddy_shader", g_width * g_height, g_width, g_height, true);
210  glDeleteProgram(program);
211#endif
212
213  glDeleteBuffers(1, &index_buffer);
214  delete[] indices;
215
216  glDeleteBuffers(1, &vertex_buffer);
217  delete[] vertices;
218
219  return true;
220}
221
222
223TestBase* GetVaryingsAndDdxyShaderTest() {
224  return new VaryingsAndDdxyShaderTest;
225}
226
227
228} // namespace glbench
229