Home | History | Annotate | Download | only in src
      1 // Copyright (c) 2013 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 "texturetest.h"
      6 
      7 #include "base/logging.h"
      8 #include "base/strings/string_number_conversions.h"
      9 #include "base/strings/string_util.h"
     10 
     11 namespace glbench {
     12 
     13 namespace {
     14 
     15 // Vertex and fragment shader code.
     16 const char* kVertexShader =
     17     "attribute vec4 c1;"
     18     "attribute vec4 c2;"
     19     "varying vec4 v1;"
     20     "void main() {"
     21     "  gl_Position = c1;"
     22     "  v1 = c2;"
     23     "}";
     24 
     25 const char* kFragmentShader =
     26     "varying vec4 v1;"
     27     "uniform sampler2D texture;"
     28     "void main() {"
     29     "  gl_FragColor = texture2D(texture, v1.xy);"
     30     "}";
     31 
     32 }  // namespace
     33 
     34 bool TextureTest::Run() {
     35   // Two triangles that form one pixel at 0, 0.
     36   const GLfloat kVertices[8] = {
     37     0.f, 0.f,
     38     2.f / g_width, 0.f,
     39     0.f, 2.f / g_height,
     40     2.f / g_width, 2.f / g_height,
     41   };
     42   const GLfloat kTexCoords[8] = {
     43     0.f, 0.f, 0.f, 0.f,
     44     0.f, 0.f, 0.f, 0.f,
     45   };
     46 
     47   program_ = InitShaderProgram(kVertexShader, kFragmentShader);
     48 
     49   int attr1 = glGetAttribLocation(program_, "c1");
     50   glVertexAttribPointer(attr1, 2, GL_FLOAT, GL_FALSE, 0, kVertices);
     51   glEnableVertexAttribArray(attr1);
     52 
     53   int attr2 = glGetAttribLocation(program_, "c2");
     54   glVertexAttribPointer(attr2, 2, GL_FLOAT, GL_FALSE, 0, kTexCoords);
     55   glEnableVertexAttribArray(attr2);
     56 
     57   int texture_sampler = glGetUniformLocation(program_, "texture");
     58   glUniform1i(texture_sampler, 0);
     59   glActiveTexture(GL_TEXTURE0);
     60 
     61   glGenTextures(kNumberOfTextures, textures_);
     62   for (int i = 0; i < kNumberOfTextures; ++i) {
     63     glBindTexture(GL_TEXTURE_2D, textures_[i]);
     64     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     65     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
     66   }
     67 
     68   // Textures formats
     69   // TODO(djkurtz): Other formats such as GL_BGRA, GL_RGB, GL_BGR, ... ?
     70   const GLenum kTexelFormats[] =
     71      { GL_LUMINANCE, GL_RGBA }; // , GL_BGRA, GL_RGB, GL_BGR };
     72   const unsigned int kTexelFormatSizes[] = { 1, 4 }; // , 4, 3, 3 };
     73   const std::string kTexelFormatNames[] =
     74       { "luminance", "rgba" }; // , "bgra", "rgb", "bgr" };
     75 
     76   // Texture upload commands
     77   UpdateFlavor kFlavors[] = { TEX_IMAGE, TEX_SUBIMAGE };
     78   const std::string kFlavorNames[] = { "teximage2d", "texsubimage2d" };
     79 
     80   for (unsigned int fmt = 0; fmt < arraysize(kTexelFormats); fmt++) {
     81     texel_gl_format_ = kTexelFormats[fmt];
     82     unsigned int texel_size = kTexelFormatSizes[fmt];
     83     for (unsigned int flavor = 0; flavor < arraysize(kFlavors); flavor++) {
     84       flavor_ = kFlavors[flavor];
     85       const int sizes[] = { 32, 128, 256, 512, 768, 1024, 1536, 2048 };
     86       for (unsigned int j = 0; j < arraysize(sizes); j++) {
     87         // In hasty mode only do at most 512x512 sized problems.
     88         if (g_hasty && sizes[j] > 512)
     89           continue;
     90 
     91         std::string name = std::string(Name()) + "_" +
     92             kTexelFormatNames[fmt] + "_" + kFlavorNames[flavor] + "_" +
     93             base::IntToString(sizes[j]);
     94 
     95         width_ = height_ = sizes[j];
     96         const unsigned int buffer_size = width_ * height_ * texel_size;
     97         for (int i = 0; i < kNumberOfTextures; ++i) {
     98           pixels_[i].reset(new char[buffer_size]);
     99           memset(pixels_[i].get(), 255, buffer_size);
    100 
    101           // For NPOT texture we must set GL_TEXTURE_WRAP as GL_CLAMP_TO_EDGE
    102           glBindTexture(GL_TEXTURE_2D, textures_[i]);
    103           glTexImage2D(GL_TEXTURE_2D, 0, texel_gl_format_, width_, height_, 0,
    104                        texel_gl_format_, GL_UNSIGNED_BYTE, NULL);
    105           if (glGetError() != 0) {
    106             printf("# Error: Failed to allocate %dx%d %u-byte texel texture.\n",
    107                    width_, height_, texel_size);
    108           }
    109           if (IS_NOT_POWER_OF_2(width_) || IS_NOT_POWER_OF_2(height_)) {
    110             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    111             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    112           }
    113         }
    114         RunTest(this, name.c_str(), buffer_size, g_width, g_height, true);
    115         GLenum error = glGetError();
    116         if (error != GL_NO_ERROR) {
    117           printf("# GL error code %d after RunTest() with %dx%d %d-byte texture.\n",
    118                  error, width_, height_, texel_size);
    119        }
    120       }
    121     }
    122   }
    123   for (int i = 0; i < kNumberOfTextures; ++i)
    124     pixels_[i].reset();
    125 
    126   glDeleteTextures(kNumberOfTextures, textures_);
    127   glDeleteProgram(program_);
    128   return true;
    129 }
    130 
    131 } // namespace glbench
    132