summaryrefslogtreecommitdiffstats
path: root/progs/perf/vertexrate.c
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2009-09-16 19:33:01 -0600
committerBrian Paul <[email protected]>2009-09-16 19:33:01 -0600
commit9abbedad09c2501285d2edb00cba7e8e6549c5ba (patch)
tree113ca0f873db469d6ec47aae9e4eba9081b52f01 /progs/perf/vertexrate.c
parent4df2f7af5e9b2c00ead92fe0ae49ed8491aef1d0 (diff)
progs/perf: initial set of simple performance test programs
Initial tests include: drawoverhead - measure overhead of state changes w.r.t drawing commands teximage - measure glTexImage2D() and glTexSubImage2D() speed vbo - measure glBufferData() and glBufferSubData() speed vertexrate - measure vertex rate for immediate mode, glDrawArrays, VBOs, etc.
Diffstat (limited to 'progs/perf/vertexrate.c')
-rw-r--r--progs/perf/vertexrate.c271
1 files changed, 271 insertions, 0 deletions
diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c
new file mode 100644
index 00000000000..f7e02624cc9
--- /dev/null
+++ b/progs/perf/vertexrate.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Measure simple vertex processing rate via:
+ * - immediate mode
+ * - vertex arrays
+ * - VBO vertex arrays
+ * - glDrawElements
+ * - VBO glDrawElements
+ * - glDrawRangeElements
+ * - VBO glDrawRangeElements
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+
+#define MAX_VERTS (100 * 100)
+
+/** glVertex2/3/4 size */
+#define VERT_SIZE 4
+
+int WinWidth = 500, WinHeight = 500;
+
+static GLuint VertexBO, ElementBO;
+
+static unsigned NumVerts = MAX_VERTS;
+static unsigned VertBytes = VERT_SIZE * sizeof(float);
+static float *VertexData = NULL;
+
+static unsigned NumElements = MAX_VERTS;
+static GLuint *Elements = NULL;
+
+
+/**
+ * Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2.
+ */
+static void
+InitializeVertexData(void)
+{
+ unsigned i;
+ float x = -1.0, y = -1.0;
+ float dx = 2.0 / 100;
+ float dy = 2.0 / 100;
+
+ VertexData = (float *) malloc(NumVerts * VertBytes);
+
+ for (i = 0; i < NumVerts; i++) {
+ VertexData[i * VERT_SIZE + 0] = x;
+ VertexData[i * VERT_SIZE + 1] = y;
+ VertexData[i * VERT_SIZE + 2] = 0.0;
+ VertexData[i * VERT_SIZE + 3] = 1.0;
+ x += dx;
+ if (x > 1.0) {
+ x = -1.0;
+ y += dy;
+ }
+ }
+
+ Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint));
+
+ for (i = 0; i < NumVerts; i++) {
+ Elements[i] = NumVerts - i - 1;
+ }
+}
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ InitializeVertexData();
+
+ /* setup VertexBO */
+ glGenBuffersARB(1, &VertexBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* setup ElementBO */
+ glGenBuffersARB(1, &ElementBO);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB);
+}
+
+
+static void
+DrawImmediate(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ for (i = 0; i < count; i++) {
+ unsigned j;
+ glBegin(GL_POINTS);
+ for (j = 0; j < NumVerts; j++) {
+#if VERT_SIZE == 4
+ glVertex4fv(VertexData + j * 4);
+#elif VERT_SIZE == 3
+ glVertex3fv(VertexData + j * 3);
+#elif VERT_SIZE == 2
+ glVertex2fv(VertexData + j * 2);
+#else
+ abort();
+#endif
+ }
+ glEnd();
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysVBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE);
+
+ rate = PerfMeasureRate(DrawImmediate);
+ rate *= NumVerts;
+ printf(" Immediate mode: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawArraysMem);
+ rate *= NumVerts;
+ printf(" glDrawArrays: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawArraysVBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawArrays: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawElementsMem);
+ rate *= NumVerts;
+ printf(" glDrawElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawElementsBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawRangeElementsMem);
+ rate *= NumVerts;
+ printf(" glDrawRangeElements: %.1f verts/sec\n", rate);
+
+ rate = PerfMeasureRate(DrawRangeElementsBO);
+ rate *= NumVerts;
+ printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate);
+
+ exit(0);
+}