• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
TextureMetaDataInit()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 
Run()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