diff options
Diffstat (limited to 'progs/perf/vbo.c')
-rw-r--r-- | progs/perf/vbo.c | 166 |
1 files changed, 137 insertions, 29 deletions
diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c index dba7e4515b..b326c056ec 100644 --- a/progs/perf/vbo.c +++ b/progs/perf/vbo.c @@ -31,13 +31,17 @@ #include "glmain.h" #include "common.h" +/* Copy data out of a large array to avoid caching effects: + */ +#define DATA_SIZE (16*1024*1024) int WinWidth = 100, WinHeight = 100; static GLuint VBO; static GLsizei VBOSize = 0; -static GLubyte *VBOData = NULL; +static GLsizei SubSize = 0; +static GLubyte *VBOData = NULL; /* array[DATA_SIZE] */ static const GLboolean DrawPoint = GL_TRUE; static const GLboolean BufferSubDataInHalves = GL_TRUE; @@ -61,11 +65,23 @@ static void UploadVBO(unsigned count) { unsigned i; + unsigned total = 0; + unsigned src = 0; + for (i = 0; i < count; i++) { - glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); + glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData + src, GL_STREAM_DRAW_ARB); + glDrawArrays(GL_POINTS, 0, 1); + + /* Throw in an occasional flush to work around a driver crash: + */ + total += VBOSize; + if (total >= 16*1024*1024) { + glFlush(); + total = 0; + } - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); + src += VBOSize; + src %= DATA_SIZE; } glFinish(); } @@ -75,18 +91,69 @@ static void UploadSubVBO(unsigned count) { unsigned i; + unsigned src = 0; + 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); + unsigned offset = (i * SubSize) % VBOSize; + glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src); + + if (DrawPoint) { + glDrawArrays(GL_POINTS, offset / sizeof(Vertex0), 1); } - else { - glBufferSubDataARB(GL_ARRAY_BUFFER, 0, VBOSize, VBOData); + + src += SubSize; + src %= DATA_SIZE; + } + glFinish(); +} + + +/* Do multiple small SubData uploads, then call DrawArrays. This may be a + * fairer comparison to back-to-back BufferData calls: + */ +static void +BatchUploadSubVBO(unsigned count) +{ + unsigned i = 0, j; + unsigned period = VBOSize / SubSize; + unsigned src = 0; + + while (i < count) { + for (j = 0; j < period && i < count; j++, i++) { + unsigned offset = j * SubSize; + glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src); } - if (DrawPoint) - glDrawArrays(GL_POINTS, 0, 1); + glDrawArrays(GL_POINTS, 0, 1); + + src += SubSize; + src %= DATA_SIZE; + } + glFinish(); +} + + +/** + * Test the sequence: + * create/load VBO + * draw + * destroy VBO + */ +static void +CreateDrawDestroyVBO(unsigned count) +{ + unsigned i; + for (i = 0; i < count; i++) { + GLuint vbo; + /* create/load */ + glGenBuffersARB(1, &vbo); + glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo); + glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); + /* draw */ + glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0); + glDrawArrays(GL_POINTS, 0, 1); + /* destroy */ + glDeleteBuffersARB(1, &vbo); } glFinish(); } @@ -102,36 +169,77 @@ static const GLsizei Sizes[] = { 0 /* end of list */ }; +void +PerfNextRound(void) +{ +} /** Called from test harness/main */ void PerfDraw(void) { double rate, mbPerSec; - int sub, sz; + int i, sz; - /* loop over whole/sub buffer upload */ - for (sub = 0; sub < 2; sub++) { + /* Load VBOData buffer with duplicated Vertex0. + */ + VBOData = calloc(DATA_SIZE, 1); - /* loop over VBO sizes */ - for (sz = 0; Sizes[sz]; sz++) { - VBOSize = Sizes[sz]; + for (i = 0; i < DATA_SIZE / sizeof(Vertex0); i++) { + memcpy(VBOData + i * sizeof(Vertex0), + Vertex0, + sizeof(Vertex0)); + } - VBOData = malloc(VBOSize); - memcpy(VBOData, Vertex0, sizeof(Vertex0)); + /* glBufferDataARB() + */ + for (sz = 0; Sizes[sz]; sz++) { + SubSize = VBOSize = Sizes[sz]; + rate = PerfMeasureRate(UploadVBO); + mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + perf_printf(" glBufferDataARB(size = %d): %.1f MB/sec\n", + VBOSize, mbPerSec); + } - if (sub) - rate = PerfMeasureRate(UploadSubVBO); - else - rate = PerfMeasureRate(UploadVBO); + /* glBufferSubDataARB() + */ + for (sz = 0; Sizes[sz]; sz++) { + SubSize = VBOSize = Sizes[sz]; + rate = PerfMeasureRate(UploadSubVBO); + mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + perf_printf(" glBufferSubDataARB(size = %d): %.1f MB/sec\n", + VBOSize, mbPerSec); + } - mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + /* Batch upload + */ + VBOSize = 1024 * 1024; + glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB); + + for (sz = 0; Sizes[sz] < VBOSize; sz++) { + SubSize = Sizes[sz]; + rate = PerfMeasureRate(UploadSubVBO); + mbPerSec = rate * SubSize / (1024.0 * 1024.0); + perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n", + SubSize, VBOSize, mbPerSec); + } - printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n", - (sub ? "Sub" : ""), VBOSize, mbPerSec); + for (sz = 0; Sizes[sz] < VBOSize; sz++) { + SubSize = Sizes[sz]; + rate = PerfMeasureRate(BatchUploadSubVBO); + mbPerSec = rate * SubSize / (1024.0 * 1024.0); + perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d), batched: %.1f MB/sec\n", + SubSize, VBOSize, mbPerSec); + } - free(VBOData); - } + /* Create/Draw/Destroy + */ + for (sz = 0; Sizes[sz]; sz++) { + SubSize = VBOSize = Sizes[sz]; + rate = PerfMeasureRate(CreateDrawDestroyVBO); + mbPerSec = rate * VBOSize / (1024.0 * 1024.0); + perf_printf(" VBO Create/Draw/Destroy(size = %d): %.1f MB/sec, %.1f draws/sec\n", + VBOSize, mbPerSec, rate); } exit(0); |