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