summaryrefslogtreecommitdiffstats
path: root/progs/perf
diff options
context:
space:
mode:
authorKeith Whitwell <[email protected]>2009-09-21 15:56:17 +0100
committerKeith Whitwell <[email protected]>2009-09-21 15:57:14 +0100
commit7ce0421fb712fd4e595f6c2ecede91c16fb3e133 (patch)
tree04b6c83f61f59f7dd680a671f3ebd6f2e00bcc0b /progs/perf
parent25a580c8416c7fdf6ddbf25b8121ee8774a2acd8 (diff)
progs/perf: a few more vbo upload modes
Some tests, eg small SubData are probably overwhelmed by the cost of performing the draw after each upload. Add a varient which does a lot of subdata uploads and then a single draw. Also try to avoid cache-artifacts in the upload timings.
Diffstat (limited to 'progs/perf')
-rw-r--r--progs/perf/vbo.c121
1 files changed, 97 insertions, 24 deletions
diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c
index d2630796ae2..4b6e3f18746 100644
--- a/progs/perf/vbo.c
+++ b/progs/perf/vbo.c
@@ -31,12 +31,16 @@
#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 GLsizei SubSize = 0;
static GLubyte *VBOData = NULL;
static const GLboolean DrawPoint = 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,42 @@ 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, the a 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();
}
@@ -109,28 +149,61 @@ PerfDraw(void)
{
double rate, mbPerSec;
int sub, sz;
+ int i;
+
+ VBOData = calloc(DATA_SIZE, 1);
+
+ for (i = 0; i < DATA_SIZE / sizeof(Vertex0); i++) {
+ memcpy(VBOData + i * sizeof(Vertex0),
+ Vertex0,
+ sizeof(Vertex0));
+ }
+
/* loop over whole/sub buffer upload */
- for (sub = 0; sub < 2; sub++) {
+ for (sub = 0; sub < 3; sub++) {
- /* loop over VBO sizes */
- for (sz = 0; Sizes[sz]; sz++) {
- VBOSize = Sizes[sz];
+ if (sub == 2) {
+ VBOSize = 1024 * 1024;
- VBOData = malloc(VBOSize);
- memcpy(VBOData, Vertex0, sizeof(Vertex0));
+ glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
- if (sub)
+ for (sz = 0; Sizes[sz] < VBOSize; sz++) {
+ SubSize = Sizes[sz];
rate = PerfMeasureRate(UploadSubVBO);
- else
- rate = PerfMeasureRate(UploadVBO);
- mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
+ mbPerSec = rate * SubSize / (1024.0 * 1024.0);
+
+ perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n",
+ SubSize, 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);
+ }
+ }
+ else {
+
+ /* loop over VBO sizes */
+ for (sz = 0; Sizes[sz]; sz++) {
+ SubSize = VBOSize = Sizes[sz];
+
+ if (sub == 1)
+ rate = PerfMeasureRate(UploadSubVBO);
+ else
+ rate = PerfMeasureRate(UploadVBO);
- perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n",
- (sub ? "Sub" : ""), VBOSize, mbPerSec);
+ mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
- free(VBOData);
+ perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n",
+ (sub ? "Sub" : ""), VBOSize, mbPerSec);
+ }
}
}