1 // Copyright (c) 2010 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 "base/logging.h" 6 #include "main.h" 7 #include "testbase.h" 8 #include "utils.h" 9 10 #include <algorithm> 11 12 13 namespace glbench { 14 15 16 class FillRateTest : public DrawArraysTestFunc { 17 public: 18 FillRateTest() {} 19 virtual ~FillRateTest() {} 20 virtual bool Run(); 21 virtual const char* Name() const { return "fill_rate"; } 22 23 private: 24 DISALLOW_COPY_AND_ASSIGN(FillRateTest); 25 }; 26 27 class FboFillRateTest : public DrawArraysTestFunc { 28 public: 29 FboFillRateTest() {} 30 virtual ~FboFillRateTest() {} 31 virtual bool Run(); 32 virtual const char* Name() const { return "fbo_fill_rate"; } 33 34 private: 35 DISALLOW_COPY_AND_ASSIGN(FboFillRateTest); 36 }; 37 38 const char* kVertexShader1 = 39 "attribute vec4 position;" 40 "void main() {" 41 " gl_Position = position;" 42 "}"; 43 44 const char* kFragmentShader1 = 45 "uniform vec4 color;" 46 "void main() {" 47 " gl_FragColor = color;" 48 "}"; 49 50 51 const char* kVertexShader2 = 52 "attribute vec4 position;" 53 "attribute vec4 texcoord;" 54 "uniform float scale;" 55 "varying vec4 v1;" 56 "void main() {" 57 " gl_Position = position * vec4(scale, scale, 1., 1.);" 58 " v1 = texcoord;" 59 "}"; 60 61 const char* kFragmentShader2 = 62 "uniform sampler2D texture;" 63 "varying vec4 v1;" 64 "void main() {" 65 " gl_FragColor = texture2D(texture, v1.xy);" 66 "}"; 67 68 const GLfloat buffer_vertex[8] = { 69 -1.f, -1.f, 70 1.f, -1.f, 71 -1.f, 1.f, 72 1.f, 1.f, 73 }; 74 75 const GLfloat buffer_texture[8] = { 76 0.f, 0.f, 77 1.f, 0.f, 78 0.f, 1.f, 79 1.f, 1.f, 80 }; 81 82 const GLfloat red[4] = {1.f, 0.f, 0.f, 1.f}; 83 84 85 bool FillRateTest::Run() { 86 glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 87 glDisable(GL_DEPTH_TEST); 88 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 89 90 GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER, 91 sizeof(buffer_vertex), buffer_vertex); 92 GLuint program = InitShaderProgram(kVertexShader1, kFragmentShader1); 93 GLint position_attribute = glGetAttribLocation(program, "position"); 94 glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL); 95 glEnableVertexAttribArray(position_attribute); 96 97 GLint color_uniform = glGetUniformLocation(program, "color"); 98 glUniform4fv(color_uniform, 1, red); 99 100 FillRateTestNormal("fill_solid"); 101 FillRateTestBlendDepth("fill_solid"); 102 103 glDeleteProgram(program); 104 105 program = InitShaderProgram(kVertexShader2, kFragmentShader2); 106 position_attribute = glGetAttribLocation(program, "position"); 107 // Reusing vbo_vertex buffer from the previous test. 108 glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL); 109 glEnableVertexAttribArray(position_attribute); 110 111 GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER, 112 sizeof(buffer_texture), buffer_texture); 113 GLuint texcoord_attribute = glGetAttribLocation(program, "texcoord"); 114 glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL); 115 glEnableVertexAttribArray(texcoord_attribute); 116 117 // Get a fractal looking source texture of size 512x512 and full levels 118 // of detail. 119 GLuint texture = SetupTexture(9); 120 121 GLuint texture_uniform = glGetUniformLocation(program, "texture"); 122 glUniform1i(texture_uniform, 0); 123 124 GLuint scale_uniform = glGetUniformLocation(program, "scale"); 125 glUniform1f(scale_uniform, 1.f); 126 127 FillRateTestNormal("fill_tex_nearest"); 128 129 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 130 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 131 FillRateTestNormal("fill_tex_bilinear"); 132 133 // lod = 0.5 134 float scale = 0.7071f; 135 glUniform1f(scale_uniform, scale); 136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 137 GL_LINEAR_MIPMAP_LINEAR); 138 FillRateTestNormalSubWindow("fill_tex_trilinear_linear_05", 139 g_width, g_height); 140 141 // lod = 0.4 142 scale = 0.758f; 143 glUniform1f(scale_uniform, scale); 144 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 145 GL_LINEAR_MIPMAP_LINEAR); 146 FillRateTestNormalSubWindow("fill_tex_trilinear_linear_04", 147 g_width, g_height); 148 149 // lod = 0.1 150 scale = 0.933f; 151 glUniform1f(scale_uniform, scale); 152 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 153 GL_LINEAR_MIPMAP_LINEAR); 154 FillRateTestNormalSubWindow("fill_tex_trilinear_linear_01", 155 g_width, g_height); 156 157 glDeleteProgram(program); 158 glDeleteBuffers(1, &vbo_vertex); 159 glDeleteBuffers(1, &vbo_texture); 160 glDeleteTextures(1, &texture); 161 162 return true; 163 } 164 165 bool FboFillRateTest::Run() { 166 char name[256]; 167 CHECK(!glGetError()); 168 GLuint vbo_vertex = SetupVBO(GL_ARRAY_BUFFER, 169 sizeof(buffer_vertex), buffer_vertex); 170 GLuint program = InitShaderProgram(kVertexShader2, kFragmentShader2); 171 GLint position_attribute = glGetAttribLocation(program, "position"); 172 glVertexAttribPointer(position_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL); 173 glEnableVertexAttribArray(position_attribute); 174 GLuint vbo_texture = SetupVBO(GL_ARRAY_BUFFER, 175 sizeof(buffer_texture), buffer_texture); 176 GLuint texcoord_attribute = glGetAttribLocation(program, "texcoord"); 177 glVertexAttribPointer(texcoord_attribute, 2, GL_FLOAT, GL_FALSE, 0, NULL); 178 glEnableVertexAttribArray(texcoord_attribute); 179 glDisable(GL_DEPTH_TEST); 180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 181 CHECK(!glGetError()); 182 183 // We don't care for tiny texture sizes. And why the 8K*8K reference is 184 // only 700kB in size in the failure case it could be huge to upload to GS. 185 // In hasty mode we ignore huge textures all together. 186 const int max_size = std::min(g_hasty ? 512 : 4096, g_max_texture_size); 187 // Start with 32x32 textures and go up from there. 188 int size_log2 = 5; 189 for (int size = 1 << size_log2; size <= max_size; size *= 2) { 190 sprintf(name, "fbofill_tex_bilinear_%d", size); 191 192 // Setup texture for FBO. 193 GLuint destination_texture = 0; 194 glGenTextures(1, &destination_texture); 195 glBindTexture(GL_TEXTURE_2D, destination_texture); 196 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size, size, 0, GL_RGBA, 197 GL_UNSIGNED_BYTE, NULL); 198 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 199 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 200 CHECK(!glGetError()); 201 202 // Setup Framebuffer. 203 // TODO(fjhenigman): In WAFFLE_PLATFORM_NULL the default framebuffer 204 // is NOT zero, so we have to save the current binding and restore 205 // that value later. Fix this. 206 GLint save_fb; 207 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &save_fb); 208 GLuint framebuffer = 0; 209 glGenFramebuffers(1, &framebuffer); 210 glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); 211 glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 212 GL_TEXTURE_2D, destination_texture, 0); 213 CHECK(!glGetError()); 214 215 // Attach texture and check for completeness. 216 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); 217 CHECK(status == GL_FRAMEBUFFER_COMPLETE); 218 glViewport(0, 0, size, size); 219 220 // Get a fractal looking source texture of size size*size. 221 GLuint source_texture = SetupTexture(size_log2); 222 GLuint texture_uniform = glGetUniformLocation(program, "texture"); 223 glUniform1i(texture_uniform, 0); 224 GLuint scale_uniform = glGetUniformLocation(program, "scale"); 225 glUniform1f(scale_uniform, 1.f); 226 227 // Run the benchmark, save the images if desired. 228 FillRateTestNormalSubWindow(name, size, size); 229 230 // Clean up for this loop. 231 glBindFramebuffer(GL_FRAMEBUFFER, save_fb); 232 glDeleteFramebuffers(1, &framebuffer); 233 glDeleteTextures(1, &source_texture); 234 glDeleteTextures(1, &destination_texture); 235 CHECK(!glGetError()); 236 237 size_log2++; 238 } 239 // Clean up invariants. 240 glDeleteProgram(program); 241 glDeleteBuffers(1, &vbo_vertex); 242 glDeleteBuffers(1, &vbo_texture); 243 // Just in case restore the viewport for all other tests. 244 glViewport(0, 0, g_width, g_height); 245 246 return true; 247 } 248 249 TestBase* GetFillRateTest() { 250 return new FillRateTest; 251 } 252 253 TestBase* GetFboFillRateTest() { 254 return new FboFillRateTest; 255 } 256 257 } // namespace glbench 258