Brian Paul | 9abbeda | 2009-09-16 19:33:01 -0600 | [diff] [blame] | 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 simple vertex processing rate via:
|
| 24 | * - immediate mode
|
| 25 | * - vertex arrays
|
| 26 | * - VBO vertex arrays
|
| 27 | * - glDrawElements
|
| 28 | * - VBO glDrawElements
|
| 29 | * - glDrawRangeElements
|
| 30 | * - VBO glDrawRangeElements
|
| 31 | *
|
| 32 | * Brian Paul
|
| 33 | * 16 Sep 2009
|
| 34 | */
|
| 35 |
|
| 36 | #include <assert.h>
|
| 37 | #include <string.h>
|
| 38 | #include "glmain.h"
|
| 39 | #include "common.h"
|
| 40 |
|
| 41 |
|
| 42 | #define MAX_VERTS (100 * 100)
|
| 43 |
|
| 44 | /** glVertex2/3/4 size */
|
| 45 | #define VERT_SIZE 4
|
| 46 |
|
| 47 | int WinWidth = 500, WinHeight = 500;
|
| 48 |
|
| 49 | static GLuint VertexBO, ElementBO;
|
| 50 |
|
| 51 | static unsigned NumVerts = MAX_VERTS;
|
| 52 | static unsigned VertBytes = VERT_SIZE * sizeof(float);
|
| 53 | static float *VertexData = NULL;
|
| 54 |
|
| 55 | static unsigned NumElements = MAX_VERTS;
|
| 56 | static GLuint *Elements = NULL;
|
| 57 |
|
| 58 |
|
| 59 | /**
|
| 60 | * Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2.
|
| 61 | */
|
| 62 | static void
|
| 63 | InitializeVertexData(void)
|
| 64 | {
|
| 65 | unsigned i;
|
| 66 | float x = -1.0, y = -1.0;
|
| 67 | float dx = 2.0 / 100;
|
| 68 | float dy = 2.0 / 100;
|
| 69 |
|
| 70 | VertexData = (float *) malloc(NumVerts * VertBytes);
|
| 71 |
|
| 72 | for (i = 0; i < NumVerts; i++) {
|
| 73 | VertexData[i * VERT_SIZE + 0] = x;
|
| 74 | VertexData[i * VERT_SIZE + 1] = y;
|
| 75 | VertexData[i * VERT_SIZE + 2] = 0.0;
|
| 76 | VertexData[i * VERT_SIZE + 3] = 1.0;
|
| 77 | x += dx;
|
| 78 | if (x > 1.0) {
|
| 79 | x = -1.0;
|
| 80 | y += dy;
|
| 81 | }
|
| 82 | }
|
| 83 |
|
| 84 | Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint));
|
| 85 |
|
| 86 | for (i = 0; i < NumVerts; i++) {
|
| 87 | Elements[i] = NumVerts - i - 1;
|
| 88 | }
|
| 89 | }
|
| 90 |
|
| 91 |
|
| 92 | /** Called from test harness/main */
|
| 93 | void
|
| 94 | PerfInit(void)
|
| 95 | {
|
| 96 | InitializeVertexData();
|
| 97 |
|
| 98 | /* setup VertexBO */
|
| 99 | glGenBuffersARB(1, &VertexBO);
|
| 100 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO);
|
| 101 | glBufferDataARB(GL_ARRAY_BUFFER_ARB,
|
| 102 | NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB);
|
| 103 | glEnableClientState(GL_VERTEX_ARRAY);
|
| 104 |
|
| 105 | /* setup ElementBO */
|
| 106 | glGenBuffersARB(1, &ElementBO);
|
| 107 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO);
|
| 108 | glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
|
| 109 | NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB);
|
| 110 | }
|
| 111 |
|
| 112 |
|
| 113 | static void
|
| 114 | DrawImmediate(unsigned count)
|
| 115 | {
|
| 116 | unsigned i;
|
| 117 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| 118 | glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
| 119 | for (i = 0; i < count; i++) {
|
| 120 | unsigned j;
|
| 121 | glBegin(GL_POINTS);
|
| 122 | for (j = 0; j < NumVerts; j++) {
|
| 123 | #if VERT_SIZE == 4
|
| 124 | glVertex4fv(VertexData + j * 4);
|
| 125 | #elif VERT_SIZE == 3
|
| 126 | glVertex3fv(VertexData + j * 3);
|
| 127 | #elif VERT_SIZE == 2
|
| 128 | glVertex2fv(VertexData + j * 2);
|
| 129 | #else
|
| 130 | abort();
|
| 131 | #endif
|
| 132 | }
|
| 133 | glEnd();
|
| 134 | }
|
| 135 | glFinish();
|
| 136 | PerfSwapBuffers();
|
| 137 | }
|
| 138 |
|
| 139 |
|
| 140 | static void
|
| 141 | DrawArraysMem(unsigned count)
|
| 142 | {
|
| 143 | unsigned i;
|
| 144 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| 145 | glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
| 146 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
|
| 147 | for (i = 0; i < count; i++) {
|
| 148 | glDrawArrays(GL_POINTS, 0, NumVerts);
|
| 149 | }
|
| 150 | glFinish();
|
| 151 | PerfSwapBuffers();
|
| 152 | }
|
| 153 |
|
| 154 |
|
| 155 | static void
|
| 156 | DrawArraysVBO(unsigned count)
|
| 157 | {
|
| 158 | unsigned i;
|
| 159 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| 160 | glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
|
| 161 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
|
| 162 | for (i = 0; i < count; i++) {
|
| 163 | glDrawArrays(GL_POINTS, 0, NumVerts);
|
| 164 | }
|
| 165 | glFinish();
|
| 166 | PerfSwapBuffers();
|
| 167 | }
|
| 168 |
|
| 169 |
|
| 170 | static void
|
| 171 | DrawElementsMem(unsigned count)
|
| 172 | {
|
| 173 | unsigned i;
|
| 174 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| 175 | glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
| 176 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
|
| 177 | for (i = 0; i < count; i++) {
|
| 178 | glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements);
|
| 179 | }
|
| 180 | glFinish();
|
| 181 | PerfSwapBuffers();
|
| 182 | }
|
| 183 |
|
| 184 |
|
| 185 | static void
|
| 186 | DrawElementsBO(unsigned count)
|
| 187 | {
|
| 188 | unsigned i;
|
| 189 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
|
| 190 | glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
|
| 191 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
|
| 192 | for (i = 0; i < count; i++) {
|
| 193 | glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0);
|
| 194 | }
|
| 195 | glFinish();
|
| 196 | PerfSwapBuffers();
|
| 197 | }
|
| 198 |
|
| 199 |
|
| 200 | static void
|
| 201 | DrawRangeElementsMem(unsigned count)
|
| 202 | {
|
| 203 | unsigned i;
|
| 204 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
|
| 205 | glBindBufferARB(GL_ARRAY_BUFFER, 0);
|
| 206 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
|
| 207 | for (i = 0; i < count; i++) {
|
| 208 | glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
|
| 209 | NumVerts, GL_UNSIGNED_INT, Elements);
|
| 210 | }
|
| 211 | glFinish();
|
| 212 | PerfSwapBuffers();
|
| 213 | }
|
| 214 |
|
| 215 |
|
| 216 | static void
|
| 217 | DrawRangeElementsBO(unsigned count)
|
| 218 | {
|
| 219 | unsigned i;
|
| 220 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
|
| 221 | glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
|
| 222 | glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
|
| 223 | for (i = 0; i < count; i++) {
|
| 224 | glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
|
| 225 | NumVerts, GL_UNSIGNED_INT, (void *) 0);
|
| 226 | }
|
| 227 | glFinish();
|
| 228 | PerfSwapBuffers();
|
| 229 | }
|
| 230 |
|
| 231 |
|
| 232 | /** Called from test harness/main */
|
| 233 | void
|
| 234 | PerfDraw(void)
|
| 235 | {
|
| 236 | double rate;
|
| 237 |
|
| 238 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
| 239 |
|
| 240 | printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE);
|
| 241 |
|
| 242 | rate = PerfMeasureRate(DrawImmediate);
|
| 243 | rate *= NumVerts;
|
| 244 | printf(" Immediate mode: %.1f verts/sec\n", rate);
|
| 245 |
|
| 246 | rate = PerfMeasureRate(DrawArraysMem);
|
| 247 | rate *= NumVerts;
|
| 248 | printf(" glDrawArrays: %.1f verts/sec\n", rate);
|
| 249 |
|
| 250 | rate = PerfMeasureRate(DrawArraysVBO);
|
| 251 | rate *= NumVerts;
|
| 252 | printf(" VBO glDrawArrays: %.1f verts/sec\n", rate);
|
| 253 |
|
| 254 | rate = PerfMeasureRate(DrawElementsMem);
|
| 255 | rate *= NumVerts;
|
| 256 | printf(" glDrawElements: %.1f verts/sec\n", rate);
|
| 257 |
|
| 258 | rate = PerfMeasureRate(DrawElementsBO);
|
| 259 | rate *= NumVerts;
|
| 260 | printf(" VBO glDrawElements: %.1f verts/sec\n", rate);
|
| 261 |
|
| 262 | rate = PerfMeasureRate(DrawRangeElementsMem);
|
| 263 | rate *= NumVerts;
|
| 264 | printf(" glDrawRangeElements: %.1f verts/sec\n", rate);
|
| 265 |
|
| 266 | rate = PerfMeasureRate(DrawRangeElementsBO);
|
| 267 | rate *= NumVerts;
|
| 268 | printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate);
|
| 269 |
|
| 270 | exit(0);
|
| 271 | }
|