From 9297e6968ae16564f3d6a6e78b42da72f9c88e91 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 21 Sep 2009 12:17:49 -0600 Subject: progs/perf: added fill-rate test Many more fill modes could be tested, but this hits the basics including blending, texturing and shaders. --- progs/perf/SConscript | 1 + 1 file changed, 1 insertion(+) (limited to 'progs/perf/SConscript') diff --git a/progs/perf/SConscript b/progs/perf/SConscript index c019dc95b0..98a4112dba 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -9,6 +9,7 @@ env.Prepend(LIBS = ['$GLUT_LIB']) progs = [ 'drawoverhead', + 'fill', 'teximage', 'vbo', 'vertexrate', -- cgit v1.2.3 From a7b2659f02c503bd2110b9fd9799efc113807ad9 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Mon, 21 Sep 2009 16:55:12 +0100 Subject: progs/perf: add first attempt at a swapbuffers rate test 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 | 1 + progs/perf/SConscript | 1 + progs/perf/drawoverhead.c | 4 ++ progs/perf/glmain.c | 29 ++++---- progs/perf/glmain.h | 6 ++ progs/perf/swapbuffers.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++ progs/perf/teximage.c | 4 ++ progs/perf/vbo.c | 4 ++ progs/perf/vertexrate.c | 5 ++ 9 files changed, 207 insertions(+), 14 deletions(-) create mode 100644 progs/perf/swapbuffers.c (limited to 'progs/perf/SConscript') diff --git a/progs/perf/Makefile b/progs/perf/Makefile index b2fe1af26a..e8fe720eaa 100644 --- a/progs/perf/Makefile +++ b/progs/perf/Makefile @@ -16,6 +16,7 @@ LDLIBS = $(LIBS) PROG_SOURCES = \ drawoverhead.c \ fill.c \ + swapbuffers.c \ teximage.c \ vbo.c \ vertexrate.c \ diff --git a/progs/perf/SConscript b/progs/perf/SConscript index 98a4112dba..fa43d73d96 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -11,6 +11,7 @@ progs = [ 'drawoverhead', 'fill', 'teximage', + 'swapbuffers', 'vbo', 'vertexrate', ] diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c index d581f4b187..0de549b0dc 100644 --- a/progs/perf/drawoverhead.c +++ b/progs/perf/drawoverhead.c @@ -108,6 +108,10 @@ DrawStateChange(unsigned count) glFinish(); } +void +PerfNextRound(void) +{ +} /** Called from test harness/main */ void diff --git a/progs/perf/glmain.c b/progs/perf/glmain.c index 83c7b8a79c..8b41b8ee82 100644 --- a/progs/perf/glmain.c +++ b/progs/perf/glmain.c @@ -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; diff --git a/progs/perf/glmain.h b/progs/perf/glmain.h index 91f2eb3e74..ccfd289880 100644 --- a/progs/perf/glmain.h +++ b/progs/perf/glmain.h @@ -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 index 0000000000..79ac372f27 --- /dev/null +++ b/progs/perf/swapbuffers.c @@ -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)); +} + diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c index 634cd83558..86f0ef8736 100644 --- a/progs/perf/teximage.c +++ b/progs/perf/teximage.c @@ -155,6 +155,10 @@ static const struct { { 0, 0, NULL } }; +void +PerfNextRound(void) +{ +} /** Called from test harness/main */ diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c index 4b6e3f1874..03c896321b 100644 --- a/progs/perf/vbo.c +++ b/progs/perf/vbo.c @@ -142,6 +142,10 @@ static const GLsizei Sizes[] = { 0 /* end of list */ }; +void +PerfNextRound(void) +{ +} /** Called from test harness/main */ void diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c index 21231d8208..b5355525d0 100644 --- a/progs/perf/vertexrate.c +++ b/progs/perf/vertexrate.c @@ -228,6 +228,11 @@ DrawRangeElementsBO(unsigned count) PerfSwapBuffers(); } +void +PerfNextRound(void) +{ +} + /** Called from test harness/main */ void -- cgit v1.2.3 From ed113da12e4fdc77b477d44113dfa450e19b80d0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Sep 2009 11:03:43 -0600 Subject: progs/perf: added fbobind.c test to test FBO binding speed --- progs/perf/Makefile | 1 + progs/perf/SConscript | 1 + progs/perf/fbobind.c | 151 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 153 insertions(+) create mode 100644 progs/perf/fbobind.c (limited to 'progs/perf/SConscript') diff --git a/progs/perf/Makefile b/progs/perf/Makefile index e8fe720eaa..afadcc1bdb 100644 --- a/progs/perf/Makefile +++ b/progs/perf/Makefile @@ -15,6 +15,7 @@ LDLIBS = $(LIBS) PROG_SOURCES = \ drawoverhead.c \ + fbobind.c \ fill.c \ swapbuffers.c \ teximage.c \ diff --git a/progs/perf/SConscript b/progs/perf/SConscript index fa43d73d96..b87b874663 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -9,6 +9,7 @@ env.Prepend(LIBS = ['$GLUT_LIB']) progs = [ 'drawoverhead', + 'fbobind', 'fill', 'teximage', 'swapbuffers', diff --git a/progs/perf/fbobind.c b/progs/perf/fbobind.c new file mode 100644 index 0000000000..99a56ef2f7 --- /dev/null +++ b/progs/perf/fbobind.c @@ -0,0 +1,151 @@ +/* + * 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 rate of binding/switching between FBO targets. + * Create two framebuffer objects for rendering to two textures. + * Ping pong between texturing from one and drawing into the other. + * + * Brian Paul + * 22 Sep 2009 + */ + +#include +#include "glmain.h" +#include "common.h" + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO; + +static GLuint FBO[2], Tex[2]; + +static const GLsizei TexSize = 512; + +static const GLboolean DrawPoint = 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) +{ + const GLenum filter = GL_LINEAR; + GLenum stat; + int i; + + if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) { + perf_printf("fboswitch: GL_EXT_framebuffer_object not supported\n"); + exit(0); + } + + /* setup VBO */ + 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); + + glGenFramebuffersEXT(2, FBO); + glGenTextures(2, Tex); + + for (i = 0; i < 2; i++) { + /* setup texture */ + glBindTexture(GL_TEXTURE_2D, Tex[i]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + + + /* setup fbo */ + glBindFramebufferEXT(GL_FRAMEBUFFER, FBO[i]); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_TEXTURE_2D, Tex[i], 0/*level*/); + stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) { + perf_printf("fboswitch: Error: incomplete FBO!\n"); + exit(1); + } + + /* clear the FBO */ + glClear(GL_COLOR_BUFFER_BIT); + } +} + + +static void +FBOBind(unsigned count) +{ + unsigned i; + for (i = 1; i < count; i++) { + const GLuint dst = i & 1; + const GLuint src = 1 - dst; + + /* bind src texture */ + glBindTexture(GL_TEXTURE_2D, Tex[src]); + + /* bind dst fbo */ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO[dst]); + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + + /* draw something */ + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +/** Called from test harness/main */ +void +PerfNextRound(void) +{ +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate; + + rate = PerfMeasureRate(FBOBind); + perf_printf(" FBO Binding: %1.f binds/sec\n", rate); + + exit(0); +} -- cgit v1.2.3 From d04fa73cec675f02261a69b02187f1df1e9ede5b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 22 Sep 2009 15:28:34 -0600 Subject: progs/perf: added glCopyTex[Sub]Image2D test --- progs/perf/Makefile | 1 + progs/perf/SConscript | 1 + progs/perf/copytex.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 progs/perf/copytex.c (limited to 'progs/perf/SConscript') diff --git a/progs/perf/Makefile b/progs/perf/Makefile index afadcc1bdb..f078082685 100644 --- a/progs/perf/Makefile +++ b/progs/perf/Makefile @@ -14,6 +14,7 @@ CFLAGS += -I$(INCDIR) LDLIBS = $(LIBS) PROG_SOURCES = \ + copytex.c \ drawoverhead.c \ fbobind.c \ fill.c \ diff --git a/progs/perf/SConscript b/progs/perf/SConscript index b87b874663..acd6564e14 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -8,6 +8,7 @@ env = env.Clone() env.Prepend(LIBS = ['$GLUT_LIB']) progs = [ + 'copytex', 'drawoverhead', 'fbobind', 'fill', diff --git a/progs/perf/copytex.c b/progs/perf/copytex.c new file mode 100644 index 0000000000..f7a6b8aec3 --- /dev/null +++ b/progs/perf/copytex.c @@ -0,0 +1,214 @@ +/* + * 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 glCopyTex[Sub]Image() rate. + * Create a large, off-screen framebuffer object for rendering and + * copying the texture data from it since we can't make really large + * on-screen windows. + * + * Brian Paul + * 22 Sep 2009 + */ + +#include +#include "glmain.h" +#include "common.h" + +int WinWidth = 100, WinHeight = 100; + +static GLuint VBO, FBO, RBO, Tex; + +const GLsizei MinSize = 16, MaxSize = 4096; +static GLsizei TexSize; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean TexSubImage4 = GL_FALSE; + +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) +{ + const GLenum filter = GL_LINEAR; + GLenum stat; + + if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) { + perf_printf("copytex: GL_EXT_framebuffer_object not supported\n"); + exit(0); + } + + /* setup VBO */ + 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); + + /* setup texture */ + glGenTextures(1, &Tex); + glBindTexture(GL_TEXTURE_2D, Tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); + glEnable(GL_TEXTURE_2D); + + /* setup rbo */ + glGenRenderbuffersEXT(1, &RBO); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBO); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, MaxSize, MaxSize); + + /* setup fbo */ + glGenFramebuffersEXT(1, &FBO); + glBindFramebufferEXT(GL_FRAMEBUFFER, FBO); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, + GL_COLOR_ATTACHMENT0_EXT, + GL_RENDERBUFFER_EXT, RBO); + + stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) { + perf_printf("fboswitch: Error: incomplete FBO!\n"); + exit(1); + } + + /* clear the FBO */ + glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT); + glViewport(0, 0, MaxSize, MaxSize); + glClear(GL_COLOR_BUFFER_BIT); +} + + +static void +CopyTexImage(unsigned count) +{ + unsigned i; + for (i = 1; i < count; i++) { + /* draw something */ + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + + /* copy whole texture */ + glCopyTexImage2D(GL_TEXTURE_2D, 0, + GL_RGBA, 0, 0, TexSize, TexSize, 0); + } + glFinish(); +} + + +static void +CopyTexSubImage(unsigned count) +{ + unsigned i; + for (i = 1; i < count; i++) { + /* draw something */ + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + + /* copy sub texture */ + if (TexSubImage4) { + /* four sub-copies */ + GLsizei half = TexSize / 2; + /* lower-left */ + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, 0, 0, half, half); + /* lower-right */ + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + half, 0, half, 0, half, half); + /* upper-left */ + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + 0, half, 0, half, half, half); + /* upper-right */ + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + half, half, half, half, half, half); + } + else { + /* one big copy */ + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, + 0, 0, 0, 0, TexSize, TexSize); + } + } + glFinish(); +} + + +/** Called from test harness/main */ +void +PerfNextRound(void) +{ +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate, mbPerSec; + GLint sub, maxTexSize; + + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize); + + /* loop over whole/sub tex copy */ + for (sub = 0; sub < 2; sub++) { + + /* loop over texture sizes */ + for (TexSize = MinSize; TexSize <= MaxSize; TexSize *= 4) { + + if (TexSize <= maxTexSize) { + GLint bytesPerImage = 4 * TexSize * TexSize; + + if (sub == 0) + rate = PerfMeasureRate(CopyTexImage); + else { + /* setup empty dest texture */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + TexSize, TexSize, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); + rate = PerfMeasureRate(CopyTexSubImage); + } + + mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0); + } + else { + rate = 0.0; + mbPerSec = 0.0; + } + + perf_printf(" glCopyTex%sImage(%d x %d): %.1f copies/sec, %.1f Mpixels/sec\n", + (sub ? "Sub" : ""), TexSize, TexSize, rate, mbPerSec); + } + } + + exit(0); +} -- cgit v1.2.3 From fa0816b17cffed1b72f81ad6dd8e87d9800e6d45 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 23 Sep 2009 14:04:38 -0600 Subject: progs/perf: added glReadPixels benchmark --- progs/perf/Makefile | 1 + progs/perf/SConscript | 3 +- progs/perf/readpixels.c | 169 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 172 insertions(+), 1 deletion(-) create mode 100644 progs/perf/readpixels.c (limited to 'progs/perf/SConscript') diff --git a/progs/perf/Makefile b/progs/perf/Makefile index f078082685..043e91d669 100644 --- a/progs/perf/Makefile +++ b/progs/perf/Makefile @@ -18,6 +18,7 @@ PROG_SOURCES = \ drawoverhead.c \ fbobind.c \ fill.c \ + readpixels.c \ swapbuffers.c \ teximage.c \ vbo.c \ diff --git a/progs/perf/SConscript b/progs/perf/SConscript index acd6564e14..224928bf98 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -12,8 +12,9 @@ progs = [ 'drawoverhead', 'fbobind', 'fill', - 'teximage', + "readpixels', 'swapbuffers', + 'teximage', 'vbo', 'vertexrate', ] diff --git a/progs/perf/readpixels.c b/progs/perf/readpixels.c new file mode 100644 index 0000000000..3772b2cf3e --- /dev/null +++ b/progs/perf/readpixels.c @@ -0,0 +1,169 @@ +/* + * 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 glReadPixels speed. + * XXX also read into a PBO? + * XXX also read from FBOs? + * + * Brian Paul + * 23 Sep 2009 + */ + +#include +#include +#include "glmain.h" +#include "common.h" + +int WinWidth = 1000, WinHeight = 1000; + +static GLuint VBO; + +static const GLboolean DrawPoint = GL_TRUE; +static const GLboolean BufferSubDataInHalves = GL_TRUE; + +static const GLfloat Vertex0[2] = { 0.0, 0.0 }; + +static GLenum HaveDepthStencil; + +static GLenum ReadFormat, ReadType; +static GLint ReadWidth, ReadHeight; +static GLvoid *ReadBuffer; + + +/** Called from test harness/main */ +void +PerfInit(void) +{ + /* setup VBO */ + glGenBuffersARB(1, &VBO); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vertex0), Vertex0, GL_STATIC_DRAW_ARB); + glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); + glEnableClientState(GL_VERTEX_ARRAY); + + glPixelStorei(GL_PACK_ALIGNMENT, 1); + + HaveDepthStencil = PerfExtensionSupported("GL_EXT_packed_depth_stencil"); + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + glEnable(GL_DEPTH_TEST); + glEnable(GL_STENCIL_TEST); +} + + +static void +ReadPixels(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + /* read from random pos */ + GLint x, y; + + x = WinWidth - ReadWidth; + y = WinHeight - ReadHeight; + if (x > 0) + x = rand() % x; + if (y > 0) + y = rand() % y; + + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + + glReadPixels(x, y, ReadWidth, ReadHeight, + ReadFormat, ReadType, ReadBuffer); + } + glFinish(); +} + + +static const GLsizei Sizes[] = { + 10, + 100, + 500, + 1000, + 0 +}; + + +static const struct { + GLenum format, type; + const char *name; + GLuint pixel_size; + GLboolean full_test; +} DstFormats[] = { + { GL_RGBA, GL_UNSIGNED_BYTE, "RGBA/ubyte", 4 }, + { GL_BGRA, GL_UNSIGNED_BYTE, "BGRA/ubyte", 4 }, + { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, "RGB/565", 2 }, + { GL_LUMINANCE, GL_UNSIGNED_BYTE, "L/ubyte", 1 }, + { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, "Z/uint", 4 }, + { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, "Z+S/uint", 4 }, + { 0, 0, NULL, 0, 0 } +}; + + + +/** Called from test harness/main */ +void +PerfNextRound(void) +{ +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + double rate, mbPerSec; + int fmt, sz; + + /* loop over formats */ + for (fmt = 0; DstFormats[fmt].format; fmt++) { + ReadFormat = DstFormats[fmt].format; + ReadType = DstFormats[fmt].type; + + /* loop over sizes */ + for (sz = 0; Sizes[sz]; sz++) { + int imgSize; + + ReadWidth = ReadHeight = Sizes[sz]; + imgSize = ReadWidth * ReadHeight * DstFormats[fmt].pixel_size; + ReadBuffer = malloc(imgSize); + + if (ReadFormat == GL_DEPTH_STENCIL_EXT && !HaveDepthStencil) { + rate = 0.0; + mbPerSec = 0.0; + } + else { + rate = PerfMeasureRate(ReadPixels); + mbPerSec = rate * imgSize / (1024.0 * 1024.0); + } + + perf_printf("glReadPixels(%d x %d, %s): %.1f images/sec, %.1f Mpixels/sec\n", + ReadWidth, ReadHeight, + DstFormats[fmt].name, rate, mbPerSec); + + free(ReadBuffer); + } + } + + exit(0); +} -- cgit v1.2.3 From d93f022936c9986323f69b61d788e08196e2a58a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Thu, 24 Sep 2009 16:50:27 +0100 Subject: progs/perf: fix typo in sconscript --- progs/perf/SConscript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'progs/perf/SConscript') diff --git a/progs/perf/SConscript b/progs/perf/SConscript index 224928bf98..84f1669e5e 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -12,7 +12,7 @@ progs = [ 'drawoverhead', 'fbobind', 'fill', - "readpixels', + 'readpixels', 'swapbuffers', 'teximage', 'vbo', -- cgit v1.2.3 From c9ddd6f810ce016cabf232c53ffca186ef885140 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 24 Sep 2009 19:36:37 -0600 Subject: progs/perf: glGenerateMipmap() test --- progs/perf/Makefile | 1 + progs/perf/SConscript | 1 + progs/perf/genmipmap.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 progs/perf/genmipmap.c (limited to 'progs/perf/SConscript') diff --git a/progs/perf/Makefile b/progs/perf/Makefile index 043e91d669..066eb8608e 100644 --- a/progs/perf/Makefile +++ b/progs/perf/Makefile @@ -18,6 +18,7 @@ PROG_SOURCES = \ drawoverhead.c \ fbobind.c \ fill.c \ + genmipmap.c \ readpixels.c \ swapbuffers.c \ teximage.c \ diff --git a/progs/perf/SConscript b/progs/perf/SConscript index 84f1669e5e..a5ec9a7c2a 100644 --- a/progs/perf/SConscript +++ b/progs/perf/SConscript @@ -12,6 +12,7 @@ progs = [ 'drawoverhead', 'fbobind', 'fill', + 'genmipmap', 'readpixels', 'swapbuffers', 'teximage', diff --git a/progs/perf/genmipmap.c b/progs/perf/genmipmap.c new file mode 100644 index 0000000000..4b7d6ad155 --- /dev/null +++ b/progs/perf/genmipmap.c @@ -0,0 +1,136 @@ +/* + * 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 glGenerateMipmap() speed. + * + * Brian Paul + * 24 Sep 2009 + */ + +#include +#include "glmain.h" +#include "common.h" + + +int WinWidth = 100, WinHeight = 100; + +static GLboolean DrawPoint = GL_TRUE; +static GLuint VBO; +static GLuint TexObj = 0; +static GLint BaseLevel, MaxLevel; + +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); + + 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 +GenMipmap(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + GLubyte texel[4]; + texel[0] = texel[1] = texel[2] = texel[3] = i & 0xff; + /* dirty the base image */ + glTexSubImage2D(GL_TEXTURE_2D, BaseLevel, + 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texel); + glGenerateMipmap(GL_TEXTURE_2D); + if (DrawPoint) + glDrawArrays(GL_POINTS, 0, 1); + } + glFinish(); +} + + +/** Called from test harness/main */ +void +PerfNextRound(void) +{ +} + + +/** Called from test harness/main */ +void +PerfDraw(void) +{ + const GLint NumLevels = 12; + const GLint TexWidth = 2048, TexHeight = 2048; + GLubyte *img; + double rate; + + /* Make 2K x 2K texture */ + img = (GLubyte *) malloc(TexWidth * TexHeight * 4); + memset(img, 128, TexWidth * TexHeight * 4); + glTexImage2D(GL_TEXTURE_2D, 0, + GL_RGBA, TexWidth, TexHeight, 0, + GL_RGBA, GL_UNSIGNED_BYTE, img); + free(img); + + perf_printf("Texture level[0] size: %d x %d, %d levels\n", + TexWidth, TexHeight, NumLevels); + + /* loop over base levels 0, 2, 4 */ + for (BaseLevel = 0; BaseLevel <= 4; BaseLevel += 2) { + + /* loop over max level */ + for (MaxLevel = NumLevels; MaxLevel > BaseLevel; MaxLevel--) { + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel); + + rate = PerfMeasureRate(GenMipmap); + + perf_printf(" glGenerateMipmap(levels %d..%d): %.2f gens/sec\n", + BaseLevel + 1, MaxLevel, rate); + } + } + + exit(0); +} -- cgit v1.2.3