blob: 03c896321b5329a68b3bbcdd0f14d13f26ec2e7f [file] [log] [blame]
Keith Whitwell2884c312009-09-17 12:09:16 +01001/*
2 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
3 *
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:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
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.
20 */
21
22/**
23 * Measure VBO upload speed.
24 * That is, measure glBufferDataARB() and glBufferSubDataARB().
25 *
26 * Brian Paul
27 * 16 Sep 2009
28 */
29
30#include <string.h>
31#include "glmain.h"
32#include "common.h"
33
Keith Whitwell7ce04212009-09-21 15:56:17 +010034/* Copy data out of a large array to avoid caching effects:
35 */
36#define DATA_SIZE (16*1024*1024)
Keith Whitwell2884c312009-09-17 12:09:16 +010037
38int WinWidth = 100, WinHeight = 100;
39
40static GLuint VBO;
41
42static GLsizei VBOSize = 0;
Keith Whitwell7ce04212009-09-21 15:56:17 +010043static GLsizei SubSize = 0;
Keith Whitwell2884c312009-09-17 12:09:16 +010044static GLubyte *VBOData = NULL;
45
46static const GLboolean DrawPoint = GL_TRUE;
47static const GLboolean BufferSubDataInHalves = GL_TRUE;
48
49static const GLfloat Vertex0[2] = { 0.0, 0.0 };
50
51
52/** Called from test harness/main */
53void
54PerfInit(void)
55{
56 /* setup VBO */
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);
61}
62
63
64static void
65UploadVBO(unsigned count)
66{
67 unsigned i;
Keith Whitwell7ce04212009-09-21 15:56:17 +010068 unsigned total = 0;
69 unsigned src = 0;
Keith Whitwell2884c312009-09-17 12:09:16 +010070
Keith Whitwell7ce04212009-09-21 15:56:17 +010071 for (i = 0; i < count; i++) {
72 glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData + src, GL_STREAM_DRAW_ARB);
73 glDrawArrays(GL_POINTS, 0, 1);
74
75 /* Throw in an occasional flush to work around a driver crash:
76 */
77 total += VBOSize;
78 if (total >= 16*1024*1024) {
79 glFlush();
80 total = 0;
81 }
82
83 src += VBOSize;
84 src %= DATA_SIZE;
Keith Whitwell2884c312009-09-17 12:09:16 +010085 }
86 glFinish();
87}
88
89
90static void
91UploadSubVBO(unsigned count)
92{
93 unsigned i;
Keith Whitwell7ce04212009-09-21 15:56:17 +010094 unsigned src = 0;
95
Keith Whitwell2884c312009-09-17 12:09:16 +010096 for (i = 0; i < count; i++) {
Keith Whitwell7ce04212009-09-21 15:56:17 +010097 unsigned offset = (i * SubSize) % VBOSize;
98 glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
99
100 if (DrawPoint) {
101 glDrawArrays(GL_POINTS, offset / sizeof(Vertex0), 1);
Keith Whitwell2884c312009-09-17 12:09:16 +0100102 }
103
Keith Whitwell7ce04212009-09-21 15:56:17 +0100104 src += SubSize;
105 src %= DATA_SIZE;
106 }
107 glFinish();
108}
109
110/* Do multiple small SubData uploads, the a DrawArrays. This may be a
111 * fairer comparison to back-to-back BufferData calls:
112 */
113static void
114BatchUploadSubVBO(unsigned count)
115{
116 unsigned i = 0, j;
117 unsigned period = VBOSize / SubSize;
118 unsigned src = 0;
119
120 while (i < count) {
121 for (j = 0; j < period && i < count; j++, i++) {
122 unsigned offset = j * SubSize;
123 glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
124 }
125
126 glDrawArrays(GL_POINTS, 0, 1);
127
128 src += SubSize;
129 src %= DATA_SIZE;
Keith Whitwell2884c312009-09-17 12:09:16 +0100130 }
131 glFinish();
132}
133
134
135static const GLsizei Sizes[] = {
136 64,
137 1024,
138 16*1024,
139 256*1024,
140 1024*1024,
141 16*1024*1024,
142 0 /* end of list */
143};
144
Keith Whitwella7b26592009-09-21 16:55:12 +0100145void
146PerfNextRound(void)
147{
148}
Keith Whitwell2884c312009-09-17 12:09:16 +0100149
150/** Called from test harness/main */
151void
152PerfDraw(void)
153{
154 double rate, mbPerSec;
155 int sub, sz;
Keith Whitwell7ce04212009-09-21 15:56:17 +0100156 int i;
157
158 VBOData = calloc(DATA_SIZE, 1);
159
160 for (i = 0; i < DATA_SIZE / sizeof(Vertex0); i++) {
161 memcpy(VBOData + i * sizeof(Vertex0),
162 Vertex0,
163 sizeof(Vertex0));
164 }
165
Keith Whitwell2884c312009-09-17 12:09:16 +0100166
167 /* loop over whole/sub buffer upload */
Keith Whitwell7ce04212009-09-21 15:56:17 +0100168 for (sub = 0; sub < 3; sub++) {
Keith Whitwell2884c312009-09-17 12:09:16 +0100169
Keith Whitwell7ce04212009-09-21 15:56:17 +0100170 if (sub == 2) {
171 VBOSize = 1024 * 1024;
Keith Whitwell2884c312009-09-17 12:09:16 +0100172
Keith Whitwell7ce04212009-09-21 15:56:17 +0100173 glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
Keith Whitwell2884c312009-09-17 12:09:16 +0100174
Keith Whitwell7ce04212009-09-21 15:56:17 +0100175 for (sz = 0; Sizes[sz] < VBOSize; sz++) {
176 SubSize = Sizes[sz];
Keith Whitwell2884c312009-09-17 12:09:16 +0100177 rate = PerfMeasureRate(UploadSubVBO);
Keith Whitwell2884c312009-09-17 12:09:16 +0100178
Keith Whitwell7ce04212009-09-21 15:56:17 +0100179 mbPerSec = rate * SubSize / (1024.0 * 1024.0);
180
181 perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n",
182 SubSize, VBOSize, mbPerSec);
183 }
Keith Whitwell2884c312009-09-17 12:09:16 +0100184
Keith Whitwell7ce04212009-09-21 15:56:17 +0100185 for (sz = 0; Sizes[sz] < VBOSize; sz++) {
186 SubSize = Sizes[sz];
187 rate = PerfMeasureRate(BatchUploadSubVBO);
Keith Whitwell2884c312009-09-17 12:09:16 +0100188
Keith Whitwell7ce04212009-09-21 15:56:17 +0100189 mbPerSec = rate * SubSize / (1024.0 * 1024.0);
190
191 perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d), batched: %.1f MB/sec\n",
192 SubSize, VBOSize, mbPerSec);
193 }
194 }
195 else {
196
197 /* loop over VBO sizes */
198 for (sz = 0; Sizes[sz]; sz++) {
199 SubSize = VBOSize = Sizes[sz];
200
201 if (sub == 1)
202 rate = PerfMeasureRate(UploadSubVBO);
203 else
204 rate = PerfMeasureRate(UploadVBO);
205
206 mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
207
208 perf_printf(" glBuffer%sDataARB(size = %d): %.1f MB/sec\n",
209 (sub ? "Sub" : ""), VBOSize, mbPerSec);
210 }
Keith Whitwell2884c312009-09-17 12:09:16 +0100211 }
212 }
213
214 exit(0);
215}