Home | History | Annotate | Download | only in src
      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:
     18   FillRateTest() {}
     19   virtual ~FillRateTest() {}
     20   virtual bool Run();
     21   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:
     29   FboFillRateTest() {}
     30   virtual ~FboFillRateTest() {}
     31   virtual bool Run();
     32   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 
     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 
    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 
    249 TestBase* GetFillRateTest() {
    250   return new FillRateTest;
    251 }
    252 
    253 TestBase* GetFboFillRateTest() {
    254   return new FboFillRateTest;
    255 }
    256 
    257 } // namespace glbench
    258