progs/perf: add first attempt at a swapbuffers rate test
authorKeith Whitwell <keithw@vmware.com>
Mon, 21 Sep 2009 15:55:12 +0000 (16:55 +0100)
committerKeith Whitwell <keithw@vmware.com>
Tue, 22 Sep 2009 10:21:09 +0000 (11:21 +0100)
This is pretty ugly as the original framework assumed you'd set
a single window size at startup and keep it throughout, but for
swapbuffers you want to test the rate at various window sizes.

With luck a nicer solution can be found, but this at least lays out
a marker.

progs/perf/Makefile
progs/perf/SConscript
progs/perf/drawoverhead.c
progs/perf/glmain.c
progs/perf/glmain.h
progs/perf/swapbuffers.c [new file with mode: 0644]
progs/perf/teximage.c
progs/perf/vbo.c
progs/perf/vertexrate.c

index b2fe1af26a09f11c9899aeaf3cde6e59d9cd94c8..e8fe720eaaa6191cf377236d385513a772097bbb 100644 (file)
@@ -16,6 +16,7 @@ LDLIBS = $(LIBS)
 PROG_SOURCES = \
        drawoverhead.c \
        fill.c \
+       swapbuffers.c \
        teximage.c \
        vbo.c \
        vertexrate.c \
index 98a4112dbae37a0e50f6a3f55c30354c96a59cbc..fa43d73d96ae6d42d263dc3f0dec3e106304e99a 100644 (file)
@@ -11,6 +11,7 @@ progs = [
       'drawoverhead',
       'fill',
       'teximage',
+      'swapbuffers',
       'vbo',
       'vertexrate',
 ]
index d581f4b18724cb90e75cffdb0d5573bba12b35cc..0de549b0dc506ae7f270b0dbacaf780b6d197cb7 100644 (file)
@@ -108,6 +108,10 @@ DrawStateChange(unsigned count)
    glFinish();
 }
 
+void
+PerfNextRound(void)
+{
+}
 
 /** Called from test harness/main */
 void
index 83c7b8a79c8dfbc359a442b35ab7aa7910bb0fab..8b41b8ee829ed5002386e6887d96ba70e8995aaf 100644 (file)
@@ -33,7 +33,6 @@
 
 static int Win;
 static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
-static GLboolean Anim = GL_FALSE;
 
 
 /** Return time in seconds */
@@ -153,13 +152,23 @@ PerfShaderProgram(const char *vertShader, const char *fragShader)
 }
 
 
+int
+PerfReshapeWindow( unsigned w, unsigned h )
+{
+   if (glutGet(GLUT_SCREEN_WIDTH) < w ||
+       glutGet(GLUT_SCREEN_HEIGHT) < h)
+      return 0;
+
+   glutReshapeWindow( w, h );
+   glutPostRedisplay();
+   return 1;
+}
+
+
 static void
 Idle(void)
 {
-   Xrot += 3.0;
-   Yrot += 4.0;
-   Zrot += 2.0;
-   glutPostRedisplay();
+   PerfNextRound();
 }
 
 
@@ -193,13 +202,6 @@ Key(unsigned char key, int x, int y)
    (void) x;
    (void) y;
    switch (key) {
-   case 'a':
-      Anim = !Anim;
-      if (Anim)
-         glutIdleFunc(Idle);
-      else
-         glutIdleFunc(NULL);
-      break;
    case 'z':
       Zrot -= step;
       break;
@@ -251,8 +253,7 @@ main(int argc, char *argv[])
    glutKeyboardFunc(Key);
    glutSpecialFunc(SpecialKey);
    glutDisplayFunc(Draw);
-   if (Anim)
-      glutIdleFunc(Idle);
+   glutIdleFunc(Idle);
    PerfInit();
    glutMainLoop();
    return 0;
index 91f2eb3e74e540e18cb27c88100ec42c68c8a653..ccfd289880d1cda8e1398c24b6eb56883e9e64f1 100644 (file)
@@ -46,12 +46,18 @@ PerfCheckerTexture(GLsizei width, GLsizei height);
 extern GLuint
 PerfShaderProgram(const char *vertShader, const char *fragShader);
 
+extern int
+PerfReshapeWindow( unsigned w, unsigned h );
+
 
 /** Test programs must implement these functions **/
 
 extern void
 PerfInit(void);
 
+extern void
+PerfNextRound(void);
+
 extern void
 PerfDraw(void);
 
diff --git a/progs/perf/swapbuffers.c b/progs/perf/swapbuffers.c
new file mode 100644 (file)
index 0000000..79ac372
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ * 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 drawing overhead
+ *
+ * This is the first in a series of simple performance benchmarks.
+ * The code in this file should be as simple as possible to make it
+ * easily portable to other APIs.
+ *
+ * All the window-system stuff should be contained in glmain.c (or TBDmain.c).
+ * All the re-usable, generic code should be in common.c (XXX not done yet).
+ *
+ * Brian Paul
+ * 15 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+int real_WinWidth, real_WinHeight; /* don't know whats going on here */
+
+static GLuint VBO;
+
+struct vertex
+{
+   GLfloat x, y;
+};
+
+static const struct vertex vertices[4] = {
+   { -1.0, -1.0 },
+   {  1.0, -1.0 },
+   {  1.0,  1.0 },
+   { -1.0,  1.0 }
+};
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+   /* setup VBO w/ vertex data */
+   glGenBuffersARB(1, &VBO);
+   glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+   glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+                   sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+   glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0);
+   glEnableClientState(GL_VERTEX_ARRAY);
+
+   /* misc GL state */
+   glAlphaFunc(GL_ALWAYS, 0.0);
+}
+
+static void
+SwapNaked(unsigned count)
+{
+   unsigned i;
+   for (i = 0; i < count; i++) {
+      PerfSwapBuffers();
+   }
+}
+
+
+static void
+SwapClear(unsigned count)
+{
+   unsigned i;
+   for (i = 0; i < count; i++) {
+      glClear(GL_COLOR_BUFFER_BIT);
+      PerfSwapBuffers();
+   }
+}
+
+static void
+SwapClearPoint(unsigned count)
+{
+   unsigned i;
+   for (i = 0; i < count; i++) {
+      glClear(GL_COLOR_BUFFER_BIT);
+      glDrawArrays(GL_POINTS, 0, 4);
+      PerfSwapBuffers();
+   }
+}
+
+
+static const struct {
+   unsigned w;
+   unsigned h;
+} sizes[] = {
+   { 320, 240 },
+   { 640, 480 },
+   { 1024, 768 },
+   { 1200, 1024 },
+   { 1600, 1200 }
+};
+
+void
+PerfNextRound(void)
+{
+   static unsigned i;
+   
+   if (i < sizeof(sizes) / sizeof(sizes[0])) {
+      perf_printf("Reshape %dx%d\n", sizes[i].w, sizes[i].h);
+      PerfReshapeWindow( sizes[i].w, sizes[i].h );
+      real_WinWidth = sizes[i].w;
+      real_WinHeight = sizes[i].h;
+      i++;
+   }
+   else {
+      exit(0);
+   }
+}
+
+
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+   double rate0;
+
+   rate0 = PerfMeasureRate(SwapNaked);
+   perf_printf("   Swapbuffers (Bare) %dx%d: %s swaps/second", 
+               real_WinWidth, real_WinHeight,
+               PerfHumanFloat(rate0));
+   perf_printf(" %s pixels/second\n",
+               PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+
+
+
+   rate0 = PerfMeasureRate(SwapClear);
+   perf_printf("   Swapbuffers + Clear %dx%d: %s swaps/second", 
+               real_WinWidth, real_WinHeight,
+               PerfHumanFloat(rate0));
+   perf_printf(" %s pixels/second\n",
+               PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+
+
+   rate0 = PerfMeasureRate(SwapClearPoint);
+   perf_printf("   Swapbuffers + Clear + DrawPoint %dx%d: %s swaps/second", 
+               real_WinWidth, real_WinHeight,
+               PerfHumanFloat(rate0));
+   perf_printf(" %s pixels/second\n",
+               PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+}
+
index 634cd835588b1ba7f6cc53274f9a6d510b6110b8..86f0ef873665beafcd35db9ba24d0bf5d81157c8 100644 (file)
@@ -155,6 +155,10 @@ static const struct {
    { 0, 0, NULL }
 };
 
+void
+PerfNextRound(void)
+{
+}
 
 
 /** Called from test harness/main */
index 4b6e3f18746c4575bd7fdf96a3ec5dc035135a50..03c896321b5329a68b3bbcdd0f14d13f26ec2e7f 100644 (file)
@@ -142,6 +142,10 @@ static const GLsizei Sizes[] = {
    0 /* end of list */
 };
 
+void
+PerfNextRound(void)
+{
+}
 
 /** Called from test harness/main */
 void
index 21231d82082f8f4d05c1095cf7467dc1b00ccf67..b5355525d068e416f3c834806c2e696b0f118716 100644 (file)
@@ -228,6 +228,11 @@ DrawRangeElementsBO(unsigned count)
    PerfSwapBuffers();
 }
 
+void
+PerfNextRound(void)
+{
+}
+
 
 /** Called from test harness/main */
 void