From d9b7d7875b0c114d2fa4956b2bffbe809e5b5a44 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 1 Sep 2009 08:53:31 -0600 Subject: progs/tests: re-enable exit() call See bug 21267. --- progs/tests/fbotest1.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'progs') diff --git a/progs/tests/fbotest1.c b/progs/tests/fbotest1.c index 8dac21494e..0cd7f95c35 100644 --- a/progs/tests/fbotest1.c +++ b/progs/tests/fbotest1.c @@ -127,7 +127,7 @@ Init( void ) if (!glutExtensionSupported("GL_EXT_framebuffer_object")) { printf("GL_EXT_framebuffer_object not found!\n"); - /*exit(0);*/ + exit(0); } printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER)); -- cgit v1.2.3 From bf19638a003f0915d3d5419b737c2006a8f24a31 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 7 Sep 2009 10:49:31 +1000 Subject: prog/glsl: fix Makefile for samplers_array. The rule added in 488b3c4d1bc3d830477180759a42dbaf8f5801b0 does not use the right INCDIR, breaking the build when GL isn't installed in the default include paths. 7.5 branch only fix, already fixed in master by rewriting the Makefile (ceb9459ed5e63207defa5d715958c2757933272f) Signed-off-by: Peter Hutterer --- progs/glsl/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'progs') diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 6af7a665cf..37ccf8a9ea 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -190,7 +190,7 @@ samplers: samplers.o $(UTIL_OBJS) samplers_array.o: samplers.c $(UTIL_HEADERS) - $(APP_CC) $(CFLAGS) -DSAMPLERS_ARRAY $< -c -o $@ + $(APP_CC) -I$(INCDIR) $(CFLAGS) -DSAMPLERS_ARRAY $< -c -o $@ samplers_array: samplers_array.o $(UTIL_OBJS) -- cgit v1.2.3 From 079ae4c38cf8155f7aa039f6f4374fe5d351ef4f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 8 Sep 2009 16:45:07 -0600 Subject: progs/demos: added RGB invert option --- progs/demos/copypix.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'progs') diff --git a/progs/demos/copypix.c b/progs/demos/copypix.c index 51435acfa0..a13339ea62 100644 --- a/progs/demos/copypix.c +++ b/progs/demos/copypix.c @@ -26,6 +26,7 @@ static int Scissor = 0; static float Xzoom, Yzoom; static GLboolean DrawFront = GL_FALSE; static GLboolean Dither = GL_TRUE; +static GLboolean Invert = GL_FALSE; static void Reset( void ) @@ -59,6 +60,15 @@ static void Display( void ) if (Scissor) glEnable(GL_SCISSOR_TEST); + if (Invert) { + glPixelTransferf(GL_RED_SCALE, -1.0); + glPixelTransferf(GL_GREEN_SCALE, -1.0); + glPixelTransferf(GL_BLUE_SCALE, -1.0); + glPixelTransferf(GL_RED_BIAS, 1.0); + glPixelTransferf(GL_GREEN_BIAS, 1.0); + glPixelTransferf(GL_BLUE_BIAS, 1.0); + } + /* draw copy */ glPixelZoom(Xzoom, Yzoom); glWindowPos2iARB(Xpos, Ypos); @@ -67,6 +77,15 @@ static void Display( void ) glDisable(GL_SCISSOR_TEST); + if (Invert) { + glPixelTransferf(GL_RED_SCALE, 1.0); + glPixelTransferf(GL_GREEN_SCALE, 1.0); + glPixelTransferf(GL_BLUE_SCALE, 1.0); + glPixelTransferf(GL_RED_BIAS, 0.0); + glPixelTransferf(GL_GREEN_BIAS, 0.0); + glPixelTransferf(GL_BLUE_BIAS, 0.0); + } + if (DrawFront) glFinish(); else @@ -105,6 +124,9 @@ static void Key( unsigned char key, int x, int y ) else glDisable(GL_DITHER); break; + case 'i': + Invert = !Invert; + break; case 's': Scissor = !Scissor; break; -- cgit v1.2.3 From 8947cf67288ab9a8bf87e9029d3fc1d4073cc88b Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 8 Sep 2009 16:47:30 -0600 Subject: progs/tests: added Z invert option --- progs/tests/zreaddraw.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'progs') diff --git a/progs/tests/zreaddraw.c b/progs/tests/zreaddraw.c index 8839e10836..0821d5fb35 100644 --- a/progs/tests/zreaddraw.c +++ b/progs/tests/zreaddraw.c @@ -12,6 +12,7 @@ #include static GLint WinWidth = 500, WinHeight = 500; +static GLboolean Invert = GL_FALSE; static void Display(void) @@ -50,7 +51,15 @@ static void Display(void) glPixelZoom(4.0, 4.0); glColor4f(1, 0, 0, 0); glWindowPos2i(100, 0); + if (Invert) { + glPixelTransferf(GL_DEPTH_SCALE, -1.0); + glPixelTransferf(GL_DEPTH_BIAS, 1.0); + } glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); + if (Invert) { + glPixelTransferf(GL_DEPTH_SCALE, 1.0); + glPixelTransferf(GL_DEPTH_BIAS, 0.0); + } glDisable(GL_DEPTH_TEST); @@ -77,6 +86,9 @@ static void Key(unsigned char key, int x, int y) (void) x; (void) y; switch (key) { + case 'i': + Invert = !Invert; + break; case 27: exit(0); break; -- cgit v1.2.3 From 18e5f1cee4cadc6306ebc2e2ba047172ff42556a Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sat, 12 Sep 2009 18:33:46 -0700 Subject: tgsi: implement saturation Fix recent performance regression. --- progs/fp/add-sat.txt | 6 +++++ src/gallium/auxiliary/tgsi/tgsi_sse2.c | 43 ++++++++++++++++++++-------------- 2 files changed, 32 insertions(+), 17 deletions(-) create mode 100644 progs/fp/add-sat.txt (limited to 'progs') diff --git a/progs/fp/add-sat.txt b/progs/fp/add-sat.txt new file mode 100644 index 0000000000..2253efb085 --- /dev/null +++ b/progs/fp/add-sat.txt @@ -0,0 +1,6 @@ +!!ARBfp1.0 +TEMP R0; +MOV R0, fragment.color; +ADD_SAT R0, R0, R0; +MUL result.color, {0.5}.x, R0; +END diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 3cdf8b9f35..53e3f746ee 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -1360,6 +1360,32 @@ emit_store( const struct tgsi_full_instruction *inst, unsigned chan_index ) { + switch( inst->Instruction.Saturate ) { + case TGSI_SAT_NONE: + break; + + case TGSI_SAT_ZERO_ONE: + sse_maxps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_00000000_I, + TGSI_EXEC_TEMP_00000000_C ) ); + + sse_minps( + func, + make_xmm( xmm ), + get_temp( + TGSI_EXEC_TEMP_ONE_I, + TGSI_EXEC_TEMP_ONE_C ) ); + break; + + case TGSI_SAT_MINUS_PLUS_ONE: + assert( 0 ); + break; + } + + switch( reg->DstRegister.File ) { case TGSI_FILE_OUTPUT: emit_output( @@ -1388,19 +1414,6 @@ emit_store( default: assert( 0 ); } - - switch( inst->Instruction.Saturate ) { - case TGSI_SAT_NONE: - break; - - case TGSI_SAT_ZERO_ONE: - /* assert( 0 ); */ - break; - - case TGSI_SAT_MINUS_PLUS_ONE: - assert( 0 ); - break; - } } #define STORE( FUNC, INST, XMM, INDEX, CHAN )\ @@ -1747,10 +1760,6 @@ emit_instruction( if (indirect_temp_reference(inst)) return FALSE; - /* we don't handle saturation/clamping yet */ - if (inst->Instruction.Saturate != TGSI_SAT_NONE) - return FALSE; - /* need to use extra temps to fix SOA dependencies : */ if (tgsi_check_soa_dependencies(inst)) return FALSE; -- cgit v1.2.3 From 66a7eedaa2f66e5e941cea0303c5ec348e9cc641 Mon Sep 17 00:00:00 2001 From: Keith Whitwell Date: Sun, 13 Sep 2009 11:59:24 -0700 Subject: tgsi: handle some src/dst aliasing in tgsi_sse2.c Src/Dst aliasing (aka SOA dependencies) requires some care to ensure intermediate results do not overwrite yet-to-be read source registers. This change ensures that MOV/SWZ handle this correctly, which is poor but no worse than the current tgsi_exec.c path. Remove the fallback as there is nothing to be gained correctness-wise between the two implementations now. Fixing this properly looks like a bit of work in this code, but might be easily achieved by sending destination writes to temporary storage. --- progs/fp/mov-alias.txt | 6 ++++++ progs/fp/mul-alias.txt | 6 ++++++ src/gallium/auxiliary/tgsi/tgsi_sse2.c | 31 +++++++++++++++++++++++-------- 3 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 progs/fp/mov-alias.txt create mode 100644 progs/fp/mul-alias.txt (limited to 'progs') diff --git a/progs/fp/mov-alias.txt b/progs/fp/mov-alias.txt new file mode 100644 index 0000000000..5f04e9c76e --- /dev/null +++ b/progs/fp/mov-alias.txt @@ -0,0 +1,6 @@ +!!ARBfp1.0 +TEMP R0; +MOV R0, fragment.color; +MOV R0, R0.zyxw; +MOV result.color, R0; +END diff --git a/progs/fp/mul-alias.txt b/progs/fp/mul-alias.txt new file mode 100644 index 0000000000..cf7d359e78 --- /dev/null +++ b/progs/fp/mul-alias.txt @@ -0,0 +1,6 @@ +!!ARBfp1.0 +TEMP R0; +MOV R0, fragment.color; +MUL R0, R0.zyxw, fragment.color; +MOV result.color, R0; +END diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c index 53e3f746ee..501fc05e72 100644 --- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c +++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c @@ -39,8 +39,9 @@ #include "tgsi/tgsi_info.h" #include "tgsi/tgsi_parse.h" #include "tgsi/tgsi_util.h" -#include "tgsi_exec.h" -#include "tgsi_sse2.h" +#include "tgsi/tgsi_dump.h" +#include "tgsi/tgsi_exec.h" +#include "tgsi/tgsi_sse2.h" #include "rtasm/rtasm_x86sse.h" @@ -1760,10 +1761,6 @@ emit_instruction( if (indirect_temp_reference(inst)) return FALSE; - /* need to use extra temps to fix SOA dependencies : */ - if (tgsi_check_soa_dependencies(inst)) - return FALSE; - switch (inst->Instruction.Opcode) { case TGSI_OPCODE_ARL: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { @@ -1777,8 +1774,10 @@ emit_instruction( case TGSI_OPCODE_MOV: case TGSI_OPCODE_SWZ: FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { - FETCH( func, *inst, 0, 0, chan_index ); - STORE( func, *inst, 0, 0, chan_index ); + FETCH( func, *inst, 4 + chan_index, 0, chan_index ); + } + FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) { + STORE( func, *inst, 4 + chan_index, 0, chan_index ); } break; @@ -2938,6 +2937,22 @@ tgsi_emit_sse2( parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ? "vertex shader" : "fragment shader"); } + + if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) { + uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode; + + /* XXX: we only handle src/dst aliasing in a few opcodes + * currently. Need to use an additional temporay to hold + * the result in the cases where the code is too opaque to + * fix. + */ + if (opcode != TGSI_OPCODE_MOV && + opcode != TGSI_OPCODE_SWZ) { + debug_printf("Warning: src/dst aliasing in instruction" + " is not handled:\n"); + tgsi_dump_instruction(&parse.FullToken.FullInstruction, 1); + } + } break; case TGSI_TOKEN_TYPE_IMMEDIATE: -- cgit v1.2.3 From 284d3b2d9cf0bb6a112e74bb19cf38f5d3a5001d Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 11 Sep 2009 11:14:12 -0600 Subject: progs/tests: exercise display lists and pixelstore --- progs/tests/zreaddraw.c | 67 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 13 deletions(-) (limited to 'progs') diff --git a/progs/tests/zreaddraw.c b/progs/tests/zreaddraw.c index 0821d5fb35..7dfed20cfb 100644 --- a/progs/tests/zreaddraw.c +++ b/progs/tests/zreaddraw.c @@ -13,14 +13,16 @@ static GLint WinWidth = 500, WinHeight = 500; static GLboolean Invert = GL_FALSE; +static GLboolean TestPacking = GL_FALSE; +static GLboolean TestList = GL_FALSE; static void Display(void) { - GLfloat depth[100 * 100]; - GLfloat depth2[400 * 400]; - GLfloat min, max; - int i; + GLfloat depth[100 * 100 * 2]; + GLfloat depth2[400 * 400]; /* *2 to test pixelstore stuff */ + GLuint list; + GLenum depthType = GL_FLOAT; glClearColor(0.5, 0.5, 0.5, 1.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -36,16 +38,32 @@ static void Display(void) glLoadIdentity(); glutSolidSphere(1.0, 20, 10); + if (TestPacking) { + glPixelStorei(GL_PACK_ROW_LENGTH, 120); + glPixelStorei(GL_PACK_SKIP_PIXELS, 5); + } + /* read the depth image */ - glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); - min = max = depth[0]; - for (i = 1; i < 100 * 100; i++) { - if (depth[i] < min) - min = depth[i]; - if (depth[i] > max) - max = depth[i]; + glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, depthType, depth); + if (depthType == GL_FLOAT) { + GLfloat min, max; + int i; + min = max = depth[0]; + for (i = 1; i < 100 * 100; i++) { + if (depth[i] < min) + min = depth[i]; + if (depth[i] > max) + max = depth[i]; + } + printf("Depth value range: [%f, %f]\n", min, max); + } + + if (TestPacking) { + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + glPixelStorei(GL_PACK_SKIP_PIXELS, 0); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 120); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 5); } - printf("Depth value range: [%f, %f]\n", min, max); /* draw depth image with scaling (into z buffer) */ glPixelZoom(4.0, 4.0); @@ -55,12 +73,27 @@ static void Display(void) glPixelTransferf(GL_DEPTH_SCALE, -1.0); glPixelTransferf(GL_DEPTH_BIAS, 1.0); } - glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth); + if (TestList) { + list = glGenLists(1); + glNewList(list, GL_COMPILE); + glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth); + glEndList(); + glCallList(list); + glDeleteLists(list, 1); + } + else { + glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth); + } if (Invert) { glPixelTransferf(GL_DEPTH_SCALE, 1.0); glPixelTransferf(GL_DEPTH_BIAS, 0.0); } + if (TestPacking) { + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0); + } + glDisable(GL_DEPTH_TEST); /* read back scaled depth image */ @@ -89,6 +122,14 @@ static void Key(unsigned char key, int x, int y) case 'i': Invert = !Invert; break; + case 'p': + TestPacking = !TestPacking; + printf("Test pixel pack/unpack: %d\n", TestPacking); + break; + case 'l': + TestList = !TestList; + printf("Test dlist: %d\n", TestList); + break; case 27: exit(0); break; -- cgit v1.2.3 From 799631acb18be93afab29e27241cde3780672e98 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Mon, 14 Sep 2009 17:48:17 -0600 Subject: progs/vp: print program and error info when program does not compile --- progs/vp/vp-tris.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'progs') diff --git a/progs/vp/vp-tris.c b/progs/vp/vp-tris.c index 97995accdd..1356242d97 100644 --- a/progs/vp/vp-tris.c +++ b/progs/vp/vp-tris.c @@ -119,6 +119,12 @@ static void Init( void ) glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum); glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, sz, (const GLubyte *) buf); + if (glGetError()) { + printf("Program failed to compile:\n%s\n", buf); + printf("Error: %s\n", + (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB)); + exit(1); + } assert(glIsProgramARB(prognum)); } -- cgit v1.2.3 From 7f86da6c609191dbad1887fe5683dfee087fa909 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 15 Sep 2009 17:08:33 -0600 Subject: progs/demos: create a texture object in lodbias.c Before, we were using the default texture object (name=0). This caused the intel_generate_mipmap() path to fail since passing texture=0 to glFramebufferTexture2DEXT() causes us to _unbind_ the texture if present. --- progs/demos/lodbias.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'progs') diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c index 30b1ed13d5..8d39bd605a 100644 --- a/progs/demos/lodbias.c +++ b/progs/demos/lodbias.c @@ -43,6 +43,7 @@ static GLboolean Anim = GL_TRUE; static GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */ static GLint BiasMin = -400, BiasMax = 400; static int win = 0; +static GLuint TexObj = 0; static void @@ -214,6 +215,9 @@ static void Init( void ) glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_2D, TexObj); + if (glutExtensionSupported("GL_SGIS_generate_mipmap")) { /* test auto mipmap generation */ GLint width, height, i; -- cgit v1.2.3 From 0b0fc4072f9d7fa72cbe842a2e1cabfe0d9eb3b4 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Tue, 15 Sep 2009 17:13:49 -0600 Subject: progs/demos: use non-default texobj in cubemap.c --- progs/demos/cubemap.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'progs') diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c index 0df5ff09c3..015d50d86b 100644 --- a/progs/demos/cubemap.c +++ b/progs/demos/cubemap.c @@ -58,6 +58,7 @@ static GLint ClampIndex = 0; static GLboolean supportFBO = GL_FALSE; static GLboolean supportSeamless = GL_FALSE; static GLboolean seamless = GL_FALSE; +static GLuint TexObj = 0; static struct { @@ -543,6 +544,10 @@ static void init( GLboolean useImageFiles ) printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER)); + + glGenTextures(1, &TexObj); + glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, TexObj); + if (useImageFiles) { load_envmaps(); } -- cgit v1.2.3 From 4df2f7af5e9b2c00ead92fe0ae49ed8491aef1d0 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Wed, 16 Sep 2009 15:49:33 -0600 Subject: progs/glsl: minor Makefile clean-ups --- progs/glsl/Makefile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'progs') diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile index 8103a5cbca..a8e4cf3e66 100644 --- a/progs/glsl/Makefile +++ b/progs/glsl/Makefile @@ -10,16 +10,15 @@ LIB_DEP = \ $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) \ $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) -LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) - -INCLUDE_DIRS = -I$(TOP)/progs/util +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) +CC := $(APP_CC) CFLAGS += -I$(INCDIR) -LDLIBS=$(LIBS) +LDLIBS = $(LIBS) -DEMO_SOURCES = \ +PROG_SOURCES = \ array.c \ bitmap.c \ brick.c \ @@ -59,8 +58,8 @@ UTIL_SOURCES = \ readtex.c UTIL_OBJS = $(UTIL_SOURCES:.c=.o) -PROG_OBJS = $(DEMO_SOURCES:.c=.o) -PROGS = $(DEMO_SOURCES:%.c=%) +PROG_OBJS = $(PROG_SOURCES:.c=.o) +PROGS = $(PROG_SOURCES:%.c=%) ##### TARGETS ##### -- cgit v1.2.3 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') 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') 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') 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