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
Run()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