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