diff options
| -rw-r--r-- | progs/perf/vbo.c | 121 | 
1 files changed, 97 insertions, 24 deletions
diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c index d2630796ae..4b6e3f1874 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); +         }        }     }  | 
