2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 * Measure VBO upload speed.
24 * That is, measure glBufferDataARB() and glBufferSubDataARB().
34 /* Copy data out of a large array to avoid caching effects:
36 #define DATA_SIZE (16*1024*1024)
38 int WinWidth
= 100, WinHeight
= 100;
42 static GLsizei VBOSize
= 0;
43 static GLsizei SubSize
= 0;
44 static GLubyte
*VBOData
= NULL
; /* array[DATA_SIZE] */
46 static const GLboolean DrawPoint
= GL_TRUE
;
47 static const GLboolean BufferSubDataInHalves
= GL_TRUE
;
49 static const GLfloat Vertex0
[2] = { 0.0, 0.0 };
52 /** Called from test harness/main */
57 glGenBuffersARB(1, &VBO
);
58 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, VBO
);
59 glVertexPointer(2, GL_FLOAT
, sizeof(Vertex0
), (void *) 0);
60 glEnableClientState(GL_VERTEX_ARRAY
);
65 UploadVBO(unsigned count
)
71 for (i
= 0; i
< count
; i
++) {
72 glBufferDataARB(GL_ARRAY_BUFFER
, VBOSize
, VBOData
+ src
, GL_STREAM_DRAW_ARB
);
73 glDrawArrays(GL_POINTS
, 0, 1);
75 /* Throw in an occasional flush to work around a driver crash:
78 if (total
>= 16*1024*1024) {
91 UploadSubVBO(unsigned count
)
96 for (i
= 0; i
< count
; i
++) {
97 unsigned offset
= (i
* SubSize
) % VBOSize
;
98 glBufferSubDataARB(GL_ARRAY_BUFFER
, offset
, SubSize
, VBOData
+ src
);
101 glDrawArrays(GL_POINTS
, offset
/ sizeof(Vertex0
), 1);
111 /* Do multiple small SubData uploads, then call DrawArrays. This may be a
112 * fairer comparison to back-to-back BufferData calls:
115 BatchUploadSubVBO(unsigned count
)
118 unsigned period
= VBOSize
/ SubSize
;
122 for (j
= 0; j
< period
&& i
< count
; j
++, i
++) {
123 unsigned offset
= j
* SubSize
;
124 glBufferSubDataARB(GL_ARRAY_BUFFER
, offset
, SubSize
, VBOData
+ src
);
127 glDrawArrays(GL_POINTS
, 0, 1);
143 CreateDrawDestroyVBO(unsigned count
)
146 for (i
= 0; i
< count
; i
++) {
149 glGenBuffersARB(1, &vbo
);
150 glBindBufferARB(GL_ARRAY_BUFFER_ARB
, vbo
);
151 glBufferDataARB(GL_ARRAY_BUFFER
, VBOSize
, VBOData
, GL_STREAM_DRAW_ARB
);
153 glVertexPointer(2, GL_FLOAT
, sizeof(Vertex0
), (void *) 0);
154 glDrawArrays(GL_POINTS
, 0, 1);
156 glDeleteBuffersARB(1, &vbo
);
162 static const GLsizei Sizes
[] = {
177 /** Called from test harness/main */
181 double rate
, mbPerSec
;
184 /* Load VBOData buffer with duplicated Vertex0.
186 VBOData
= calloc(DATA_SIZE
, 1);
188 for (i
= 0; i
< DATA_SIZE
/ sizeof(Vertex0
); i
++) {
189 memcpy(VBOData
+ i
* sizeof(Vertex0
),
196 for (sz
= 0; Sizes
[sz
]; sz
++) {
197 SubSize
= VBOSize
= Sizes
[sz
];
198 rate
= PerfMeasureRate(UploadVBO
);
199 mbPerSec
= rate
* VBOSize
/ (1024.0 * 1024.0);
200 perf_printf(" glBufferDataARB(size = %d): %.1f MB/sec\n",
204 /* glBufferSubDataARB()
206 for (sz
= 0; Sizes
[sz
]; sz
++) {
207 SubSize
= VBOSize
= Sizes
[sz
];
208 rate
= PerfMeasureRate(UploadSubVBO
);
209 mbPerSec
= rate
* VBOSize
/ (1024.0 * 1024.0);
210 perf_printf(" glBufferSubDataARB(size = %d): %.1f MB/sec\n",
216 VBOSize
= 1024 * 1024;
217 glBufferDataARB(GL_ARRAY_BUFFER
, VBOSize
, VBOData
, GL_STREAM_DRAW_ARB
);
219 for (sz
= 0; Sizes
[sz
] < VBOSize
; sz
++) {
221 rate
= PerfMeasureRate(UploadSubVBO
);
222 mbPerSec
= rate
* SubSize
/ (1024.0 * 1024.0);
223 perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n",
224 SubSize
, VBOSize
, mbPerSec
);
227 for (sz
= 0; Sizes
[sz
] < VBOSize
; sz
++) {
229 rate
= PerfMeasureRate(BatchUploadSubVBO
);
230 mbPerSec
= rate
* SubSize
/ (1024.0 * 1024.0);
231 perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d), batched: %.1f MB/sec\n",
232 SubSize
, VBOSize
, mbPerSec
);
235 /* Create/Draw/Destroy
237 for (sz
= 0; Sizes
[sz
]; sz
++) {
238 SubSize
= VBOSize
= Sizes
[sz
];
239 rate
= PerfMeasureRate(CreateDrawDestroyVBO
);
240 mbPerSec
= rate
* VBOSize
/ (1024.0 * 1024.0);
241 perf_printf(" VBO Create/Draw/Destroy(size = %d): %.1f MB/sec, %.1f draws/sec\n",
242 VBOSize
, mbPerSec
, rate
);