• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "base/logging.h"
6 #include "main.h"
7 #include "testbase.h"
8 #include "utils.h"
9 
10 #include <algorithm>
11 
12 
13 namespace glbench {
14 
15 
16 class FillRateTest : public DrawArraysTestFunc {
17  public:
FillRateTest()18   FillRateTest() {}
~FillRateTest()19   virtual ~FillRateTest() {}
20   virtual bool Run();
Name() const21   virtual const char* Name() const { return "fill_rate"; }
22 
23  private:
24   DISALLOW_COPY_AND_ASSIGN(FillRateTest);
25 };
26 
27 class FboFillRateTest : public DrawArraysTestFunc {
28  public:
FboFillRateTest()29   FboFillRateTest() {}
~FboFillRateTest()30   virtual ~FboFillRateTest() {}
31   virtual bool Run();
Name() const32   virtual const char* Name() const { return "fbo_fill_rate"; }
33 
34  private:
35   DISALLOW_COPY_AND_ASSIGN(FboFillRateTest);
36 };
37 
38 const char* kVertexShader1 =
39     "attribute vec4 position;"
40     "void main() {"
41     "  gl_Position = position;"
42     "}";
43 
44 const char* kFragmentShader1 =
45     "uniform vec4 color;"
46     "void main() {"
47     "  gl_FragColor = color;"
48     "}";
49 
50 
51 const char* kVertexShader2 =
52     "attribute vec4 position;"
53     "attribute vec4 texcoord;"
54     "uniform float scale;"
55     "varying vec4 v1;"
56     "void main() {"
57     "  gl_Position = position * vec4(scale, scale, 1., 1.);"
58     "  v1 = texcoord;"
59     "}";
60 
61 const char* kFragmentShader2 =
62     "uniform sampler2D texture;"
63     "varying vec4 v1;"
64     "void main() {"
65     "  gl_FragColor = texture2D(texture, v1.xy);"
66     "}";
67 
68 const GLfloat buffer_vertex[8] = {
69   -1.f, -1.f,
70   1.f,  -1.f,
71   -1.f, 1.f,
72   1.f,  1.f,
73 };
74 
75 const GLfloat buffer_texture[8] = {
76   0.f, 0.f,
77   1.f, 0.f,
78   0.f, 1.f,
79   1.f, 1.f,
80 };
81 
82 const GLfloat red[4] = {1.f, 0.f, 0.f, 1.f};
83 
84 
Run()85 bool FillRateTest::Run() {
86   glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
87   glDisable(GL_DEPTH_TEST);
88   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
89 
90   GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER,
91                                sizeof(buffer_vertex), buffer_vertex);
92   GLuint program = InitShaderProgram(kVertexShader1, kFragmentShader1);
93   GLint position_attribute = glGetAttribLocation(program, "position");
94   glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL);
95   glEnableVertexAttribArray(position_attribute);
96 
97   GLint color_uniform = glGetUniformLocation(program, "color");
98   glUniform4fv(color_uniform, 1, red);
99 
100   FillRateTestNormal("fill_solid");
101   FillRateTestBlendDepth("fill_solid");
102 
103   glDeleteProgram(program);
104 
105   program = InitShaderProgram(kVertexShader2, kFragmentShader2);
106   position_attribute = glGetAttribLocation(program, "position");
107   // Reusing vbo_vertex buffer from the previous test.
108   glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL);
109   glEnableVertexAttribArray(position_attribute);
110 
111   GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER,
112                                 sizeof(buffer_texture), buffer_texture);
113   GLuint texcoord_attribute = glGetAttribLocation(program, "texcoord");
114   glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL);
115   glEnableVertexAttribArray(texcoord_attribute);
116 
117   // Get a fractal looking source texture of size 512x512 and full levels
118   // of detail.
119   GLuint texture = SetupTexture(9);
120 
121   GLuint texture_uniform = glGetUniformLocation(program, "texture");
122   glUniform1i(texture_uniform, 0);
123 
124   GLuint scale_uniform = glGetUniformLocation(program, "scale");
125   glUniform1f(scale_uniform, 1.f);
126 
127   FillRateTestNormal("fill_tex_nearest");
128 
129   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
130   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
131   FillRateTestNormal("fill_tex_bilinear");
132 
133   // lod = 0.5
134   float scale = 0.7071f;
135   glUniform1f(scale_uniform, scale);
136   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
137                   GL_LINEAR_MIPMAP_LINEAR);
138   FillRateTestNormalSubWindow("fill_tex_trilinear_linear_05",
139                               g_width, g_height);
140 
141   // lod = 0.4
142   scale = 0.758f;
143   glUniform1f(scale_uniform, scale);
144   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
145                   GL_LINEAR_MIPMAP_LINEAR);
146   FillRateTestNormalSubWindow("fill_tex_trilinear_linear_04",
147                               g_width, g_height);
148 
149   // lod = 0.1
150   scale = 0.933f;
151   glUniform1f(scale_uniform, scale);
152   glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
153                   GL_LINEAR_MIPMAP_LINEAR);
154   FillRateTestNormalSubWindow("fill_tex_trilinear_linear_01",
155                               g_width, g_height);
156 
157   glDeleteProgram(program);
158   glDeleteBuffers(1, &vbo_vertex);
159   glDeleteBuffers(1, &vbo_texture);
160   glDeleteTextures(1, &texture);
161 
162   return true;
163 }
164 
Run()165 bool FboFillRateTest::Run() {
166   char name[256];
167   CHECK(!glGetError());
168   GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER,
169                                sizeof(buffer_vertex), buffer_vertex);
170   GLuint program = InitShaderProgram(kVertexShader2, kFragmentShader2);
171   GLint position_attribute = glGetAttribLocation(program, "position");
172   glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL);
173   glEnableVertexAttribArray(position_attribute);
174   GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER,
175                                 sizeof(buffer_texture), buffer_texture);
176   GLuint texcoord_attribute = glGetAttribLocation(program, "texcoord");
177   glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL);
178   glEnableVertexAttribArray(texcoord_attribute);
179   glDisable(GL_DEPTH_TEST);
180   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181   CHECK(!glGetError());
182 
183   // We don't care for tiny texture sizes. And why the 8K*8K reference is
184   // only 700kB in size in the failure case it could be huge to upload to GS.
185   // In hasty mode we ignore huge textures all together.
186   const int max_size = std::min(g_hasty ? 512 : 4096, g_max_texture_size);
187   // Start with 32x32 textures and go up from there.
188   int size_log2 = 5;
189   for (int size = 1 << size_log2; size <= max_size; size *= 2) {
190     sprintf(name, "fbofill_tex_bilinear_%d", size);
191 
192     // Setup texture for FBO.
193     GLuint destination_texture = 0;
194     glGenTextures(1, &destination_texture);
195     glBindTexture(GL_TEXTURE_2D, destination_texture);
196     glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA,
197                  GL_UNSIGNED_BYTE, NULL);
198     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
199     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
200     CHECK(!glGetError());
201 
202     // Setup Framebuffer.
203     // TODO(fjhenigman): In WAFFLE_PLATFORM_NULL the default framebuffer
204     // is NOT zero, so we have to save the current binding and restore
205     // that value later.  Fix this.
206     GLint save_fb;
207     glGetIntegerv(GL_FRAMEBUFFER_BINDING, &save_fb);
208     GLuint framebuffer = 0;
209     glGenFramebuffers(1, &framebuffer);
210     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
211     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
212                               GL_TEXTURE_2D, destination_texture, 0);
213     CHECK(!glGetError());
214 
215     // Attach texture and check for completeness.
216     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
217     CHECK(status == GL_FRAMEBUFFER_COMPLETE);
218     glViewport(0, 0, size, size);
219 
220     // Get a fractal looking source texture of size size*size.
221     GLuint source_texture = SetupTexture(size_log2);
222     GLuint texture_uniform = glGetUniformLocation(program, "texture");
223     glUniform1i(texture_uniform, 0);
224     GLuint scale_uniform = glGetUniformLocation(program, "scale");
225     glUniform1f(scale_uniform, 1.f);
226 
227     // Run the benchmark, save the images if desired.
228     FillRateTestNormalSubWindow(name, size, size);
229 
230     // Clean up for this loop.
231     glBindFramebuffer(GL_FRAMEBUFFER, save_fb);
232     glDeleteFramebuffers(1, &framebuffer);
233     glDeleteTextures(1, &source_texture);
234     glDeleteTextures(1, &destination_texture);
235     CHECK(!glGetError());
236 
237     size_log2++;
238   }
239   // Clean up invariants.
240   glDeleteProgram(program);
241   glDeleteBuffers(1, &vbo_vertex);
242   glDeleteBuffers(1, &vbo_texture);
243   // Just in case restore the viewport for all other tests.
244   glViewport(0, 0, g_width, g_height);
245 
246   return true;
247 }
248 
GetFillRateTest()249 TestBase* GetFillRateTest() {
250   return new FillRateTest;
251 }
252 
GetFboFillRateTest()253 TestBase* GetFboFillRateTest() {
254   return new FboFillRateTest;
255 }
256 
257 } // namespace glbench
258