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