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