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 "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:
     15   FillRateTest() {}
     16   virtual ~FillRateTest() {}
     17   virtual bool Run();
     18   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:
     26   FboFillRateTest() {}
     27   virtual ~FboFillRateTest() {}
     28   virtual bool Run();
     29   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 
     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 
    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 
    244 TestBase* GetFillRateTest() {
    245   return new FillRateTest;
    246 }
    247 
    248 TestBase* GetFboFillRateTest() {
    249   return new FboFillRateTest;
    250 }
    251 
    252 }  // namespace glbench
    253