1/* 2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included 12 * in all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 */ 21 22/** 23 * Measure glGenerateMipmap() speed. 24 * 25 * Brian Paul 26 * 24 Sep 2009 27 */ 28 29#include <string.h> 30#include <stdio.h> 31#include "glmain.h" 32#include "common.h" 33 34 35int WinWidth = 100, WinHeight = 100; 36 37static GLboolean DrawPoint = GL_TRUE; 38static GLuint VBO; 39static GLuint TexObj = 0; 40static GLint BaseLevel, MaxLevel; 41 42struct vertex 43{ 44 GLfloat x, y, s, t; 45}; 46 47static const struct vertex vertices[1] = { 48 { 0.0, 0.0, 0.5, 0.5 }, 49}; 50 51#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) 52 53/** Called from test harness/main */ 54void 55PerfInit(void) 56{ 57 if (!PerfExtensionSupported("GL_ARB_framebuffer_object")) { 58 printf("Sorry, this test requires GL_ARB_framebuffer_object\n"); 59 exit(1); 60 } 61 62 /* setup VBO w/ vertex data */ 63 glGenBuffersARB(1, &VBO); 64 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); 65 glBufferDataARB(GL_ARRAY_BUFFER_ARB, 66 sizeof(vertices), vertices, GL_STATIC_DRAW_ARB); 67 glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x)); 68 glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); 69 glEnableClientState(GL_VERTEX_ARRAY); 70 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 71 72 glGenTextures(1, &TexObj); 73 glBindTexture(GL_TEXTURE_2D, TexObj); 74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); 75 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); 76 glEnable(GL_TEXTURE_2D); 77} 78 79 80static void 81GenMipmap(unsigned count) 82{ 83 unsigned i; 84 for (i = 0; i < count; i++) { 85 GLubyte texel[4]; 86 texel[0] = texel[1] = texel[2] = texel[3] = i & 0xff; 87 /* dirty the base image */ 88 glTexSubImage2D(GL_TEXTURE_2D, BaseLevel, 89 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texel); 90 glGenerateMipmap(GL_TEXTURE_2D); 91 if (DrawPoint) 92 glDrawArrays(GL_POINTS, 0, 1); 93 } 94 glFinish(); 95} 96 97 98/** Called from test harness/main */ 99void 100PerfNextRound(void) 101{ 102} 103 104 105/** Called from test harness/main */ 106void 107PerfDraw(void) 108{ 109 const GLint NumLevels = 12; 110 const GLint TexWidth = 2048, TexHeight = 2048; 111 GLubyte *img; 112 double rate; 113 114 /* Make 2K x 2K texture */ 115 img = (GLubyte *) malloc(TexWidth * TexHeight * 4); 116 memset(img, 128, TexWidth * TexHeight * 4); 117 glTexImage2D(GL_TEXTURE_2D, 0, 118 GL_RGBA, TexWidth, TexHeight, 0, 119 GL_RGBA, GL_UNSIGNED_BYTE, img); 120 free(img); 121 122 perf_printf("Texture level[0] size: %d x %d, %d levels\n", 123 TexWidth, TexHeight, NumLevels); 124 125 /* loop over base levels 0, 2, 4 */ 126 for (BaseLevel = 0; BaseLevel <= 4; BaseLevel += 2) { 127 128 /* loop over max level */ 129 for (MaxLevel = NumLevels; MaxLevel > BaseLevel; MaxLevel--) { 130 131 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel); 132 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel); 133 134 rate = PerfMeasureRate(GenMipmap); 135 136 perf_printf(" glGenerateMipmap(levels %d..%d): %.2f gens/sec\n", 137 BaseLevel + 1, MaxLevel, rate); 138 } 139 } 140 141 exit(0); 142} 143