From 9abbedad09c2501285d2edb00cba7e8e6549c5ba Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Sep 2009 19:33:01 -0600 Subject: 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. --- progs/perf/Makefile | 49 +++++++++ progs/perf/common.c | 93 ++++++++++++++++ progs/perf/common.h | 35 ++++++ progs/perf/drawoverhead.c | 133 +++++++++++++++++++++++ progs/perf/glmain.c | 156 ++++++++++++++++++++++++++ progs/perf/glmain.h | 54 +++++++++ progs/perf/teximage.c | 210 +++++++++++++++++++++++++++++++++++ progs/perf/vbo.c | 138 +++++++++++++++++++++++ progs/perf/vertexrate.c | 271 ++++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 1139 insertions(+) create mode 100644 progs/perf/Makefile create mode 100644 progs/perf/common.c create mode 100644 progs/perf/common.h create mode 100644 progs/perf/drawoverhead.c create mode 100644 progs/perf/glmain.c create mode 100644 progs/perf/glmain.h create mode 100644 progs/perf/teximage.c create mode 100644 progs/perf/vbo.c create mode 100644 progs/perf/vertexrate.c (limited to 'progs/perf') diff --git a/progs/perf/Makefile b/progs/perf/Makefile new file mode 100644 index 0000000000..219667439f --- /dev/null +++ b/progs/perf/Makefile @@ -0,0 +1,49 @@ +# progs/demos/Makefile + +TOP = ../.. +include $(TOP)/configs/current + +INCDIR = $(TOP)/include + +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) \ + -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) + +# using : to avoid APP_CC pointing to CC loop +CC := $(APP_CC) +CFLAGS += -I$(INCDIR) +LDLIBS = $(LIBS) + +PROG_SOURCES = \ + drawoverhead.c \ + teximage.c \ + vbo.c \ + vertexrate.c \ + +PROG_OBJS = $(PROG_SOURCES:.c=.o) + +PROGS = $(PROG_SOURCES:%.c=%) + + +UTIL_SOURCES = \ + common.c \ + glmain.c + +UTIL_HEADERS = \ + common.h \ + glmain.h + +UTIL_OBJS = $(UTIL_SOURCES:.c=.o) + + + +default: $(PROGS) + +$(PROG_OBJS): $(UTIL_HEADERS) + +$(PROGS): $(UTIL_OBJS) + + + +clean: + -rm -f $(PROGS) + -rm -f *.o *~ diff --git a/progs/perf/common.c b/progs/perf/common.c new file mode 100644 index 0000000000..a50fc11cca --- /dev/null +++ b/progs/perf/common.c @@ -0,0 +1,93 @@ +/* + * 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. + */ + +/** + * Common perf code. This should be re-usable with other APIs. + */ + +#include "common.h" +#include "glmain.h" + + +/** + * Run function 'f' for enough iterations to reach a steady state. + * Return the rate (iterations/second). + */ +double +PerfMeasureRate(PerfRateFunc f) +{ + const double minDuration = 1.0; + double rate = 0.0, prevRate = 0.0; + unsigned subiters; + + /* Compute initial number of iterations to try. + * If the test function is pretty slow this helps to avoid + * extraordarily long run times. + */ + subiters = 2; + { + const double t0 = PerfGetTime(); + double t1; + do { + f(subiters); /* call the rendering function */ + t1 = PerfGetTime(); + subiters *= 2; + } while (t1 - t0 < 0.1 * minDuration); + } + /*printf("initial subIters = %u\n", subiters);*/ + + while (1) { + const double t0 = PerfGetTime(); + unsigned iters = 0; + double t1; + + do { + f(subiters); /* call the rendering function */ + t1 = PerfGetTime(); + iters += subiters; + } while (t1 - t0 < minDuration); + + rate = iters / (t1 - t0); + + if (0) + printf("prevRate %f rate %f ratio %f iters %u\n", + prevRate, rate, rate/prevRate, iters); + + /* Try and speed the search up by skipping a few steps: + */ + if (rate > prevRate * 1.6) + subiters *= 8; + else if (rate > prevRate * 1.2) + subiters *= 4; + else if (rate > prevRate * 1.05) + subiters *= 2; + else + break; + + prevRate = rate; + } + + if (0) + printf("%s returning iters %u rate %f\n", __FUNCTION__, subiters, rate); + return rate; +} + + diff --git a/progs/perf/common.h b/progs/perf/common.h new file mode 100644 index 0000000000..8b6091530d --- /dev/null +++ b/progs/perf/common.h @@ -0,0 +1,35 @@ +/* + * 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. + */ + + +#ifndef COMMON_H +#define COMMON_H + + +typedef void (*PerfRateFunc)(unsigned count); + + +extern double +PerfMeasureRate(PerfRateFunc f); + + +#endif /* COMMON_H */ + diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c new file mode 100644 index 0000000000..8c99804d34 --- /dev/null +++ b/progs/perf/drawoverhead.c @@ -0,0 +1,133 @@ +/* + * 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; + +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 +DrawNoStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +static void +DrawNopStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glDisable(GL_ALPHA_TEST); + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +static void +DrawStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (i & 1) + glEnable(GL_TEXTURE_GEN_S); + else + glDisable(GL_TEXTURE_GEN_S); + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate0, rate1, rate2, overhead; + + rate0 = PerfMeasureRate(DrawNoStateChange); + printf(" Draw only: %.1f draws/second\n", rate0); + + rate1 = PerfMeasureRate(DrawNopStateChange); + overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); + printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate1, overhead); + + rate2 = PerfMeasureRate(DrawStateChange); + overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); + printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate2, overhead); + + exit(0); +} + diff --git a/progs/perf/glmain.c b/progs/perf/glmain.c new file mode 100644 index 0000000000..62d14259f8 --- /dev/null +++ b/progs/perf/glmain.c @@ -0,0 +1,156 @@ +/* + * 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. + */ + +/** + * OpenGL/GLUT common code for perf programs. + * Brian Paul + * 15 Sep 2009 + */ + + +#include "glmain.h" +#include + + +static int Win; +static GLfloat Xrot = 0, Yrot = 0, Zrot = 0; +static GLboolean Anim = GL_FALSE; + + +/** Return time in seconds */ +double +PerfGetTime(void) +{ + return glutGet(GLUT_ELAPSED_TIME) * 0.001; +} + + +void +PerfSwapBuffers(void) +{ + glutSwapBuffers(); +} + + +static void +Idle(void) +{ + Xrot += 3.0; + Yrot += 4.0; + Zrot += 2.0; + glutPostRedisplay(); +} + + +static void +Draw(void) +{ + PerfDraw(); + glutSwapBuffers(); +} + + +static void +Reshape(int width, int height) +{ + WinWidth = width; + WinHeight = height; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -15.0); +} + + +static void +Key(unsigned char key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case 'a': + Anim = !Anim; + if (Anim) + glutIdleFunc(Idle); + else + glutIdleFunc(NULL); + break; + case 'z': + Zrot -= step; + break; + case 'Z': + Zrot += step; + break; + case 27: + glutDestroyWindow(Win); + exit(0); + break; + } + glutPostRedisplay(); +} + + +static void +SpecialKey(int key, int x, int y) +{ + const GLfloat step = 3.0; + (void) x; + (void) y; + switch (key) { + case GLUT_KEY_UP: + Xrot -= step; + break; + case GLUT_KEY_DOWN: + Xrot += step; + break; + case GLUT_KEY_LEFT: + Yrot -= step; + break; + case GLUT_KEY_RIGHT: + Yrot += step; + break; + } + glutPostRedisplay(); +} + + +int +main(int argc, char *argv[]) +{ + glutInit(&argc, argv); + glutInitWindowSize(WinWidth, WinHeight); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH); + Win = glutCreateWindow(argv[0]); + glewInit(); + glutReshapeFunc(Reshape); + glutKeyboardFunc(Key); + glutSpecialFunc(SpecialKey); + glutDisplayFunc(Draw); + if (Anim) + glutIdleFunc(Idle); + PerfInit(); + glutMainLoop(); + return 0; +} diff --git a/progs/perf/glmain.h b/progs/perf/glmain.h new file mode 100644 index 0000000000..50480a80c0 --- /dev/null +++ b/progs/perf/glmain.h @@ -0,0 +1,54 @@ +/* + * 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. + */ + + +#ifndef GLMAIN_H +#define GLMAIN_H + + +#define GL_GLEXT_PROTOTYPES +#include +#include +#include +#include + + +/** Test programs can use these vars/functions */ + +extern int WinWidth, WinHeight; + +extern double +PerfGetTime(void); + +extern void +PerfSwapBuffers(void); + + +/** Test programs must implement these functions **/ + +extern void +PerfInit(void); + +extern void +PerfDraw(void); + + +#endif /* GLMAIN_H */ diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c new file mode 100644 index 0000000000..b6d4f644de --- /dev/null +++ b/progs/perf/teximage.c @@ -0,0 +1,210 @@ +/* + * 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 glTexSubImage2D rate + * + * Brian Paul + * 16 Sep 2009 + */ + +#include "glmain.h" +#include "common.h" + + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO; +static GLuint TexObj = 0; +static GLubyte *TexImage = NULL; +static GLsizei TexSize; +static GLenum TexSrcFormat, TexSrcType; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean TexSubImage4 = GL_TRUE; + +struct vertex +{ + GLfloat x, y, s, t; +}; + +static const struct vertex vertices[1] = { + { 0.0, 0.0, 0.5, 0.5 }, +}; + + +#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) + +/** 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), VOFFSET(x)); + glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + /* texture */ + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); +} + + +static void +UploadTexImage2D(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + /* XXX is this equivalent to a glTexSubImage call since we're + * always specifying the same image size? That case isn't optimized + * in Mesa but may be optimized in other drivers. Note sure how + * much difference that might make. + */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + TexSrcFormat, TexSrcType, TexImage); + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static void +UploadTexSubImage2D(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (TexSubImage4) { + GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2; + GLsizei halfPos = TexSize - halfSize; + /* do glTexSubImage2D in four pieces */ + /* lower-left */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize); + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* lower-right */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + halfPos, 0, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* upper-left */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, halfPos, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* upper-right */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); + glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + halfPos, halfPos, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* reset the unpacking state */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + } + else { + /* replace whole texture image at once */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, TexSize, TexSize, + TexSrcFormat, TexSrcType, TexImage); + } + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +/* XXX any other formats to measure? */ +static const struct { + GLenum format, type; + const char *name; +} SrcFormats[] = { + { GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" }, + { GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" }, + { 0, 0, NULL } +}; + + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + GLint maxSize; + double rate; + GLint fmt, subImage; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); + + /* loop over source data formats */ + for (fmt = 0; SrcFormats[fmt].format; fmt++) { + TexSrcFormat = SrcFormats[fmt].format; + TexSrcType = SrcFormats[fmt].type; + + /* loop over glTexImage, glTexSubImage */ + for (subImage = 0; subImage < 2; subImage++) { + + /* loop over texture sizes */ + for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) { + GLint bytesPerImage; + double mbPerSec; + + bytesPerImage = TexSize * TexSize * 4; + TexImage = malloc(bytesPerImage); + + if (subImage) { + /* create initial, empty texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + TexSrcFormat, TexSrcType, NULL); + rate = PerfMeasureRate(UploadTexSubImage2D); + } + else { + rate = PerfMeasureRate(UploadTexImage2D); + } + + mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); + + printf(" glTex%sImage2D(%s %d x %d): " + "%.1f images/sec, %.1f MB/sec\n", + (subImage ? "Sub" : ""), + SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); + + free(TexImage); + } + } + } + + exit(0); +} diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c new file mode 100644 index 0000000000..8545a33b7e --- /dev/null +++ b/progs/perf/vbo.c @@ -0,0 +1,138 @@ +/* + * 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 VBO upload speed. + * That is, measure glBufferDataARB() and glBufferSubDataARB(). + * + * Brian Paul + * 16 Sep 2009 + */ + +#include +#include "glmain.h" +#include "common.h" + + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO; + +static GLsizei VBOSize = 0; +static GLubyte *VBOData = NULL; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean BufferSubDataInHalves = GL_TRUE; + +static const GLfloat Vertex0[2] = { 0.0, 0.0 }; + + +/** Called from test harness/main */ +void +PerfInit(void) +{ + /* setup VBO */ + glGenBuffersARB(1, &VBO); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); + glEnableClientState(GL_VERTEX_ARRAY); +} + + +static void +UploadVBO(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); + + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static void +UploadSubVBO(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (BufferSubDataInHalves) { + GLsizei half = VBOSize / 2; + glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData); + glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half); + } + else { + glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); + } + + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static const GLsizei Sizes[] = { + 64, + 1024, + 16*1024, + 256*1024, + 1024*1024, + 16*1024*1024, + 0 /* end of list */ +}; + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate, mbPerSec; + int sub, sz; + + /* loop over whole/sub buffer upload */ + for (sub = 0; sub < 2; sub++) { + + /* loop over VBO sizes */ + for (sz = 0; Sizes[sz]; sz++) { + VBOSize = Sizes[sz]; + + VBOData = malloc(VBOSize); + memcpy(VBOData, Vertex0, sizeof(Vertex0)); + + if (sub) + rate = PerfMeasureRate(UploadSubVBO); + else + rate = PerfMeasureRate(UploadVBO); + + mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + + printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", + (sub ? "Sub" : ""), VBOSize, mbPerSec); + + free(VBOData); + } + } + + exit(0); +} diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c new file mode 100644 index 0000000000..f7e02624cc --- /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 +#include +#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); +} -- cgit v1.2.3 From e95a3a23dca9fc7aaa89237059d841f624b438db Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Sep 2009 12:08:04 +0100 Subject: progs/perf: add scons support, get working under mingw --- progs/SConscript | 1 + progs/perf/SConscript | 26 ++++++++++++++++++++++++++ progs/perf/common.c | 28 +++++++++++++++++++++++++--- progs/perf/common.h | 4 ++++ progs/perf/drawoverhead.c | 11 ++++++----- progs/perf/glmain.h | 1 - progs/perf/teximage.c | 13 ++++++++----- progs/perf/vbo.c | 4 ++-- progs/perf/vertexrate.c | 16 ++++++++-------- 9 files changed, 80 insertions(+), 24 deletions(-) create mode 100644 progs/perf/SConscript (limited to 'progs/perf') diff --git a/progs/SConscript b/progs/SConscript index 620dd30e69..66eaf9e541 100644 --- a/progs/SConscript +++ b/progs/SConscript @@ -10,4 +10,5 @@ SConscript([ 'vpglsl/SConscript', 'fp/SConscript', 'wgl/SConscript', + 'perf/SConscript', ]) diff --git a/progs/perf/SConscript b/progs/perf/SConscript new file mode 100644 index 0000000000..c019dc95b0 --- /dev/null +++ b/progs/perf/SConscript @@ -0,0 +1,26 @@ +Import('env') + +if not env['GLUT']: + Return() + +env = env.Clone() + +env.Prepend(LIBS = ['$GLUT_LIB']) + +progs = [ + 'drawoverhead', + 'teximage', + 'vbo', + 'vertexrate', +] + +for prog in progs: + env.Program( + target = prog, + source = [ + prog + '.c', + 'common.c', + 'glmain.c', + ] + ) + diff --git a/progs/perf/common.c b/progs/perf/common.c index a50fc11cca..695b8a99d9 100644 --- a/progs/perf/common.c +++ b/progs/perf/common.c @@ -26,6 +26,28 @@ #include "common.h" #include "glmain.h" +#include +#include +#include + + +/* Need to add a fflush windows console with mingw, otherwise nothing + * shows up until program exit. May want to add logging here. + */ +void +perf_printf(const char *format, ...) +{ + va_list ap; + va_start(ap, format); + + fflush(stdout); + vfprintf(stdout, format, ap); + fflush(stdout); + + va_end(ap); +} + + /** * Run function 'f' for enough iterations to reach a steady state. @@ -52,7 +74,7 @@ PerfMeasureRate(PerfRateFunc f) subiters *= 2; } while (t1 - t0 < 0.1 * minDuration); } - /*printf("initial subIters = %u\n", subiters);*/ + /*perf_printf("initial subIters = %u\n", subiters);*/ while (1) { const double t0 = PerfGetTime(); @@ -68,7 +90,7 @@ PerfMeasureRate(PerfRateFunc f) rate = iters / (t1 - t0); if (0) - printf("prevRate %f rate %f ratio %f iters %u\n", + perf_printf("prevRate %f rate %f ratio %f iters %u\n", prevRate, rate, rate/prevRate, iters); /* Try and speed the search up by skipping a few steps: @@ -86,7 +108,7 @@ PerfMeasureRate(PerfRateFunc f) } if (0) - printf("%s returning iters %u rate %f\n", __FUNCTION__, subiters, rate); + perf_printf("%s returning iters %u rate %f\n", __FUNCTION__, subiters, rate); return rate; } diff --git a/progs/perf/common.h b/progs/perf/common.h index 8b6091530d..85db678c64 100644 --- a/progs/perf/common.h +++ b/progs/perf/common.h @@ -31,5 +31,9 @@ extern double PerfMeasureRate(PerfRateFunc f); +extern void +perf_printf(const char *format, ...); + + #endif /* COMMON_H */ diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c index 8c99804d34..a1d5febf19 100644 --- a/progs/perf/drawoverhead.c +++ b/progs/perf/drawoverhead.c @@ -116,17 +116,18 @@ PerfDraw(void) double rate0, rate1, rate2, overhead; rate0 = PerfMeasureRate(DrawNoStateChange); - printf(" Draw only: %.1f draws/second\n", rate0); + perf_printf(" Draw only: %.1f draws/second\n", rate0); + rate1 = PerfMeasureRate(DrawNopStateChange); overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); - printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", - rate1, overhead); + perf_printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate1, overhead); rate2 = PerfMeasureRate(DrawStateChange); overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); - printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", - rate2, overhead); + perf_printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate2, overhead); exit(0); } diff --git a/progs/perf/glmain.h b/progs/perf/glmain.h index 50480a80c0..fe11d7235e 100644 --- a/progs/perf/glmain.h +++ b/progs/perf/glmain.h @@ -26,7 +26,6 @@ #define GL_GLEXT_PROTOTYPES #include -#include #include #include diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c index b6d4f644de..8727536922 100644 --- a/progs/perf/teximage.c +++ b/progs/perf/teximage.c @@ -50,8 +50,11 @@ static const struct vertex vertices[1] = { { 0.0, 0.0, 0.5, 0.5 }, }; - +#if 0 #define VOFFSET(F) ((void *) offsetof(struct vertex, F)) +#else +#define VOFFSET(F) ((void *) &((struct vertex *)NULL)->F) +#endif /** Called from test harness/main */ void @@ -196,10 +199,10 @@ PerfDraw(void) mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); - printf(" glTex%sImage2D(%s %d x %d): " - "%.1f images/sec, %.1f MB/sec\n", - (subImage ? "Sub" : ""), - SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); + perf_printf(" glTex%sImage2D(%s %d x %d): " + "%.1f images/sec, %.1f MB/sec\n", + (subImage ? "Sub" : ""), + SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); free(TexImage); } diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c index 8545a33b7e..4ed6a88fcc 100644 --- a/progs/perf/vbo.c +++ b/progs/perf/vbo.c @@ -127,8 +127,8 @@ PerfDraw(void) mbPerSec = rate * VBOSize / (1024.0 * 1024.0); - printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", - (sub ? "Sub" : ""), VBOSize, mbPerSec); + perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", + (sub ? "Sub" : ""), VBOSize, mbPerSec); free(VBOData); } diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c index f7e02624cc..d3dd0c200f 100644 --- a/progs/perf/vertexrate.c +++ b/progs/perf/vertexrate.c @@ -237,35 +237,35 @@ PerfDraw(void) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); + perf_printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); rate = PerfMeasureRate(DrawImmediate); rate *= NumVerts; - printf(" Immediate mode: %.1f verts/sec\n", rate); + perf_printf(" Immediate mode: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawArraysMem); rate *= NumVerts; - printf(" glDrawArrays: %.1f verts/sec\n", rate); + perf_printf(" glDrawArrays: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawArraysVBO); rate *= NumVerts; - printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); + perf_printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawElementsMem); rate *= NumVerts; - printf(" glDrawElements: %.1f verts/sec\n", rate); + perf_printf(" glDrawElements: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawElementsBO); rate *= NumVerts; - printf(" VBO glDrawElements: %.1f verts/sec\n", rate); + perf_printf(" VBO glDrawElements: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawRangeElementsMem); rate *= NumVerts; - printf(" glDrawRangeElements: %.1f verts/sec\n", rate); + perf_printf(" glDrawRangeElements: %.1f verts/sec\n", rate); rate = PerfMeasureRate(DrawRangeElementsBO); rate *= NumVerts; - printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); + perf_printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); exit(0); } -- cgit v1.2.3 From 2884c31d9494d1b219da6191526e8f297ab7bbae Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 17 Sep 2009 12:09:16 +0100 Subject: progs/perf: convert some DOS line-endings It seems like some of these files were committed with CRLF initially. --- progs/perf/drawoverhead.c | 268 +++++++++++------------ progs/perf/teximage.c | 426 ++++++++++++++++++------------------ progs/perf/vbo.c | 276 +++++++++++------------ progs/perf/vertexrate.c | 542 +++++++++++++++++++++++----------------------- 4 files changed, 756 insertions(+), 756 deletions(-) (limited to 'progs/perf') diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c index a1d5febf19..c1e166e746 100644 --- a/progs/perf/drawoverhead.c +++ b/progs/perf/drawoverhead.c @@ -1,134 +1,134 @@ -/* - * 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; - -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 -DrawNoStateChange(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - glDrawArrays(GL_POINTS, 0, 4); - } - glFinish(); -} - - -static void -DrawNopStateChange(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - glDisable(GL_ALPHA_TEST); - glDrawArrays(GL_POINTS, 0, 4); - } - glFinish(); -} - - -static void -DrawStateChange(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - if (i & 1) - glEnable(GL_TEXTURE_GEN_S); - else - glDisable(GL_TEXTURE_GEN_S); - glDrawArrays(GL_POINTS, 0, 4); - } - glFinish(); -} - - -/** Called from test harness/main */ -void -PerfDraw(void) -{ - double rate0, rate1, rate2, overhead; - - rate0 = PerfMeasureRate(DrawNoStateChange); - perf_printf(" Draw only: %.1f draws/second\n", rate0); - - - rate1 = PerfMeasureRate(DrawNopStateChange); - overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); - perf_printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", - rate1, overhead); - - rate2 = PerfMeasureRate(DrawStateChange); - overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); - perf_printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", - rate2, overhead); - - exit(0); -} - +/* + * 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; + +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 +DrawNoStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +static void +DrawNopStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glDisable(GL_ALPHA_TEST); + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +static void +DrawStateChange(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (i & 1) + glEnable(GL_TEXTURE_GEN_S); + else + glDisable(GL_TEXTURE_GEN_S); + glDrawArrays(GL_POINTS, 0, 4); + } + glFinish(); +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate0, rate1, rate2, overhead; + + rate0 = PerfMeasureRate(DrawNoStateChange); + perf_printf(" Draw only: %.1f draws/second\n", rate0); + + + rate1 = PerfMeasureRate(DrawNopStateChange); + overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0); + perf_printf(" Draw w/ nop state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate1, overhead); + + rate2 = PerfMeasureRate(DrawStateChange); + overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0); + perf_printf(" Draw w/ state change: %.1f draws/sec (overhead: %f ms/draw)\n", + rate2, overhead); + + exit(0); +} + diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c index 8727536922..11d781fccc 100644 --- a/progs/perf/teximage.c +++ b/progs/perf/teximage.c @@ -1,213 +1,213 @@ -/* - * 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 glTexSubImage2D rate - * - * Brian Paul - * 16 Sep 2009 - */ - -#include "glmain.h" -#include "common.h" - - -int WinWidth = 100, WinHeight = 100; - -static GLuint VBO; -static GLuint TexObj = 0; -static GLubyte *TexImage = NULL; -static GLsizei TexSize; -static GLenum TexSrcFormat, TexSrcType; - -static const GLboolean DrawPoint = GL_TRUE; -static const GLboolean TexSubImage4 = GL_TRUE; - -struct vertex -{ - GLfloat x, y, s, t; -}; - -static const struct vertex vertices[1] = { - { 0.0, 0.0, 0.5, 0.5 }, -}; - -#if 0 -#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) -#else -#define VOFFSET(F) ((void *) &((struct vertex *)NULL)->F) -#endif - -/** 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), VOFFSET(x)); - glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - /* texture */ - glGenTextures(1, &TexObj); - glBindTexture(GL_TEXTURE_2D, TexObj); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glEnable(GL_TEXTURE_2D); -} - - -static void -UploadTexImage2D(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - /* XXX is this equivalent to a glTexSubImage call since we're - * always specifying the same image size? That case isn't optimized - * in Mesa but may be optimized in other drivers. Note sure how - * much difference that might make. - */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - TexSize, TexSize, 0, - TexSrcFormat, TexSrcType, TexImage); - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); - } - glFinish(); -} - - -static void -UploadTexSubImage2D(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - if (TexSubImage4) { - GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2; - GLsizei halfPos = TexSize - halfSize; - /* do glTexSubImage2D in four pieces */ - /* lower-left */ - glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize); - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, halfSize, halfSize, - TexSrcFormat, TexSrcType, TexImage); - /* lower-right */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); - glTexSubImage2D(GL_TEXTURE_2D, 0, - halfPos, 0, halfSize, halfSize, - TexSrcFormat, TexSrcType, TexImage); - /* upper-left */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, halfPos, halfSize, halfSize, - TexSrcFormat, TexSrcType, TexImage); - /* upper-right */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); - glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); - glTexSubImage2D(GL_TEXTURE_2D, 0, - halfPos, halfPos, halfSize, halfSize, - TexSrcFormat, TexSrcType, TexImage); - /* reset the unpacking state */ - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); - glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); - } - else { - /* replace whole texture image at once */ - glTexSubImage2D(GL_TEXTURE_2D, 0, - 0, 0, TexSize, TexSize, - TexSrcFormat, TexSrcType, TexImage); - } - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); - } - glFinish(); -} - - -/* XXX any other formats to measure? */ -static const struct { - GLenum format, type; - const char *name; -} SrcFormats[] = { - { GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" }, - { GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" }, - { 0, 0, NULL } -}; - - - -/** Called from test harness/main */ -void -PerfDraw(void) -{ - GLint maxSize; - double rate; - GLint fmt, subImage; - - glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); - - /* loop over source data formats */ - for (fmt = 0; SrcFormats[fmt].format; fmt++) { - TexSrcFormat = SrcFormats[fmt].format; - TexSrcType = SrcFormats[fmt].type; - - /* loop over glTexImage, glTexSubImage */ - for (subImage = 0; subImage < 2; subImage++) { - - /* loop over texture sizes */ - for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) { - GLint bytesPerImage; - double mbPerSec; - - bytesPerImage = TexSize * TexSize * 4; - TexImage = malloc(bytesPerImage); - - if (subImage) { - /* create initial, empty texture */ - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - TexSize, TexSize, 0, - TexSrcFormat, TexSrcType, NULL); - rate = PerfMeasureRate(UploadTexSubImage2D); - } - else { - rate = PerfMeasureRate(UploadTexImage2D); - } - - mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); - - perf_printf(" glTex%sImage2D(%s %d x %d): " - "%.1f images/sec, %.1f MB/sec\n", - (subImage ? "Sub" : ""), - SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); - - free(TexImage); - } - } - } - - exit(0); -} +/* + * 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 glTexSubImage2D rate + * + * Brian Paul + * 16 Sep 2009 + */ + +#include "glmain.h" +#include "common.h" + + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO; +static GLuint TexObj = 0; +static GLubyte *TexImage = NULL; +static GLsizei TexSize; +static GLenum TexSrcFormat, TexSrcType; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean TexSubImage4 = GL_TRUE; + +struct vertex +{ + GLfloat x, y, s, t; +}; + +static const struct vertex vertices[1] = { + { 0.0, 0.0, 0.5, 0.5 }, +}; + +#if 0 +#define VOFFSET(F) ((void *) offsetof(struct vertex, F)) +#else +#define VOFFSET(F) ((void *) &((struct vertex *)NULL)->F) +#endif + +/** 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), VOFFSET(x)); + glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s)); + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + /* texture */ + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glEnable(GL_TEXTURE_2D); +} + + +static void +UploadTexImage2D(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + /* XXX is this equivalent to a glTexSubImage call since we're + * always specifying the same image size? That case isn't optimized + * in Mesa but may be optimized in other drivers. Note sure how + * much difference that might make. + */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + TexSrcFormat, TexSrcType, TexImage); + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static void +UploadTexSubImage2D(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (TexSubImage4) { + GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2; + GLsizei halfPos = TexSize - halfSize; + /* do glTexSubImage2D in four pieces */ + /* lower-left */ + glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize); + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* lower-right */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + halfPos, 0, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* upper-left */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, halfPos, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* upper-right */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos); + glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos); + glTexSubImage2D(GL_TEXTURE_2D, 0, + halfPos, halfPos, halfSize, halfSize, + TexSrcFormat, TexSrcType, TexImage); + /* reset the unpacking state */ + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_SKIP_ROWS, 0); + } + else { + /* replace whole texture image at once */ + glTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, TexSize, TexSize, + TexSrcFormat, TexSrcType, TexImage); + } + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +/* XXX any other formats to measure? */ +static const struct { + GLenum format, type; + const char *name; +} SrcFormats[] = { + { GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" }, + { GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" }, + { 0, 0, NULL } +}; + + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + GLint maxSize; + double rate; + GLint fmt, subImage; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize); + + /* loop over source data formats */ + for (fmt = 0; SrcFormats[fmt].format; fmt++) { + TexSrcFormat = SrcFormats[fmt].format; + TexSrcType = SrcFormats[fmt].type; + + /* loop over glTexImage, glTexSubImage */ + for (subImage = 0; subImage < 2; subImage++) { + + /* loop over texture sizes */ + for (TexSize = 16; TexSize <= maxSize; TexSize *= 2) { + GLint bytesPerImage; + double mbPerSec; + + bytesPerImage = TexSize * TexSize * 4; + TexImage = malloc(bytesPerImage); + + if (subImage) { + /* create initial, empty texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + TexSrcFormat, TexSrcType, NULL); + rate = PerfMeasureRate(UploadTexSubImage2D); + } + else { + rate = PerfMeasureRate(UploadTexImage2D); + } + + mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); + + perf_printf(" glTex%sImage2D(%s %d x %d): " + "%.1f images/sec, %.1f MB/sec\n", + (subImage ? "Sub" : ""), + SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec); + + free(TexImage); + } + } + } + + exit(0); +} diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c index 4ed6a88fcc..d2630796ae 100644 --- a/progs/perf/vbo.c +++ b/progs/perf/vbo.c @@ -1,138 +1,138 @@ -/* - * 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 VBO upload speed. - * That is, measure glBufferDataARB() and glBufferSubDataARB(). - * - * Brian Paul - * 16 Sep 2009 - */ - -#include -#include "glmain.h" -#include "common.h" - - -int WinWidth = 100, WinHeight = 100; - -static GLuint VBO; - -static GLsizei VBOSize = 0; -static GLubyte *VBOData = NULL; - -static const GLboolean DrawPoint = GL_TRUE; -static const GLboolean BufferSubDataInHalves = GL_TRUE; - -static const GLfloat Vertex0[2] = { 0.0, 0.0 }; - - -/** Called from test harness/main */ -void -PerfInit(void) -{ - /* setup VBO */ - glGenBuffersARB(1, &VBO); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); - glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); - glEnableClientState(GL_VERTEX_ARRAY); -} - - -static void -UploadVBO(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); - - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); - } - glFinish(); -} - - -static void -UploadSubVBO(unsigned count) -{ - unsigned i; - for (i = 0; i < count; i++) { - if (BufferSubDataInHalves) { - GLsizei half = VBOSize / 2; - glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData); - glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half); - } - else { - glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); - } - - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); - } - glFinish(); -} - - -static const GLsizei Sizes[] = { - 64, - 1024, - 16*1024, - 256*1024, - 1024*1024, - 16*1024*1024, - 0 /* end of list */ -}; - - -/** Called from test harness/main */ -void -PerfDraw(void) -{ - double rate, mbPerSec; - int sub, sz; - - /* loop over whole/sub buffer upload */ - for (sub = 0; sub < 2; sub++) { - - /* loop over VBO sizes */ - for (sz = 0; Sizes[sz]; sz++) { - VBOSize = Sizes[sz]; - - VBOData = malloc(VBOSize); - memcpy(VBOData, Vertex0, sizeof(Vertex0)); - - if (sub) - rate = PerfMeasureRate(UploadSubVBO); - else - rate = PerfMeasureRate(UploadVBO); - - mbPerSec = rate * VBOSize / (1024.0 * 1024.0); - - perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", - (sub ? "Sub" : ""), VBOSize, mbPerSec); - - free(VBOData); - } - } - - exit(0); -} +/* + * 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 VBO upload speed. + * That is, measure glBufferDataARB() and glBufferSubDataARB(). + * + * Brian Paul + * 16 Sep 2009 + */ + +#include +#include "glmain.h" +#include "common.h" + + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO; + +static GLsizei VBOSize = 0; +static GLubyte *VBOData = NULL; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean BufferSubDataInHalves = GL_TRUE; + +static const GLfloat Vertex0[2] = { 0.0, 0.0 }; + + +/** Called from test harness/main */ +void +PerfInit(void) +{ + /* setup VBO */ + glGenBuffersARB(1, &VBO); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); + glEnableClientState(GL_VERTEX_ARRAY); +} + + +static void +UploadVBO(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); + + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static void +UploadSubVBO(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + if (BufferSubDataInHalves) { + GLsizei half = VBOSize / 2; + glBufferSubDataARB(GL_ARRAY_BUFFER, 0, half, VBOData); + glBufferSubDataARB(GL_ARRAY_BUFFER, half, half, VBOData + half); + } + else { + glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); + } + + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +static const GLsizei Sizes[] = { + 64, + 1024, + 16*1024, + 256*1024, + 1024*1024, + 16*1024*1024, + 0 /* end of list */ +}; + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate, mbPerSec; + int sub, sz; + + /* loop over whole/sub buffer upload */ + for (sub = 0; sub < 2; sub++) { + + /* loop over VBO sizes */ + for (sz = 0; Sizes[sz]; sz++) { + VBOSize = Sizes[sz]; + + VBOData = malloc(VBOSize); + memcpy(VBOData, Vertex0, sizeof(Vertex0)); + + if (sub) + rate = PerfMeasureRate(UploadSubVBO); + else + rate = PerfMeasureRate(UploadVBO); + + mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + + perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", + (sub ? "Sub" : ""), VBOSize, mbPerSec); + + free(VBOData); + } + } + + exit(0); +} diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c index d3dd0c200f..b84b22a4c4 100644 --- a/progs/perf/vertexrate.c +++ b/progs/perf/vertexrate.c @@ -1,271 +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 -#include -#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); - - perf_printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); - - rate = PerfMeasureRate(DrawImmediate); - rate *= NumVerts; - perf_printf(" Immediate mode: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawArraysMem); - rate *= NumVerts; - perf_printf(" glDrawArrays: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawArraysVBO); - rate *= NumVerts; - perf_printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawElementsMem); - rate *= NumVerts; - perf_printf(" glDrawElements: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawElementsBO); - rate *= NumVerts; - perf_printf(" VBO glDrawElements: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawRangeElementsMem); - rate *= NumVerts; - perf_printf(" glDrawRangeElements: %.1f verts/sec\n", rate); - - rate = PerfMeasureRate(DrawRangeElementsBO); - rate *= NumVerts; - perf_printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); - - exit(0); -} +/* + * 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 +#include +#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); + + perf_printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE); + + rate = PerfMeasureRate(DrawImmediate); + rate *= NumVerts; + perf_printf(" Immediate mode: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawArraysMem); + rate *= NumVerts; + perf_printf(" glDrawArrays: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawArraysVBO); + rate *= NumVerts; + perf_printf(" VBO glDrawArrays: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawElementsMem); + rate *= NumVerts; + perf_printf(" glDrawElements: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawElementsBO); + rate *= NumVerts; + perf_printf(" VBO glDrawElements: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawRangeElementsMem); + rate *= NumVerts; + perf_printf(" glDrawRangeElements: %.1f verts/sec\n", rate); + + rate = PerfMeasureRate(DrawRangeElementsBO); + rate *= NumVerts; + perf_printf(" VBO glDrawRangeElements: %.1f verts/sec\n", rate); + + exit(0); +} -- cgit v1.2.3