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 
10 namespace glbench {
11 
12 
13 class VaryingsAndDdxyShaderTest : public DrawElementsTestFunc {
14  public:
VaryingsAndDdxyShaderTest()15   VaryingsAndDdxyShaderTest() {}
~VaryingsAndDdxyShaderTest()16   virtual ~VaryingsAndDdxyShaderTest() {}
17   virtual bool Run();
Name() const18   virtual const char* Name() const { return "varyings_ddx_shader"; }
Unit() const19   virtual const char* Unit() const { return "mpixels_sec"; }
20 
21  private:
22   DISALLOW_COPY_AND_ASSIGN(VaryingsAndDdxyShaderTest);
23 };
24 
25 const 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 
33 const 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 
42 const 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 
53 const 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 
68 const char *fragment_shader_1_varying =
69 "varying vec4 v1;"
70 "void main() {"
71 "  gl_FragColor = v1;"
72 "}";
73 
74 const char *fragment_shader_2_varying =
75 "varying vec4 v1;"
76 "varying vec4 v2;"
77 "void main() {"
78 "  gl_FragColor = v1 + v2;"
79 "}";
80 
81 const 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 
90 const 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 
VaryingsShaderProgram(int varyings_count,GLuint vertex_buffer)103 GLuint 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 
137 const 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 
144 const 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 
DdxDdyShaderProgram(bool ddx,GLuint vertex_buffer)151 GLuint 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 
Run()165 bool 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 
GetVaryingsAndDdxyShaderTest()223 TestBase* GetVaryingsAndDdxyShaderTest() {
224   return new VaryingsAndDdxyShaderTest;
225 }
226 
227 
228 } // namespace glbench
229