blob: 2ff2db1bd931bf0252aca6969d80fb74f92e8a2c [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 glTexSubImage2D rate
24 *
25 * Brian Paul
26 * 16 Sep 2009
27 */
28
29#include "glmain.h"
30#include "common.h"
31
32
33int WinWidth = 100, WinHeight = 100;
34
35static GLuint VBO;
36static GLuint TexObj = 0;
37static GLubyte *TexImage = NULL;
38static GLsizei TexSize;
Keith Whitwell0ec26cc2009-09-22 17:59:24 +010039static GLenum TexIntFormat, TexSrcFormat, TexSrcType;
Keith Whitwell2884c312009-09-17 12:09:16 +010040
41static const GLboolean DrawPoint = GL_TRUE;
42static const GLboolean TexSubImage4 = GL_TRUE;
43
Keith Whitwell0ec26cc2009-09-22 17:59:24 +010044enum {
45 MODE_CREATE_TEXIMAGE,
46 MODE_TEXIMAGE,
47 MODE_TEXSUBIMAGE
48};
49
50static const char *mode_name[] =
51{
52 "Create_TexImage",
53 "TexImage",
54 "TexSubImage"
55};
56
57
58
Keith Whitwell2884c312009-09-17 12:09:16 +010059struct vertex
60{
61 GLfloat x, y, s, t;
62};
63
64static const struct vertex vertices[1] = {
65 { 0.0, 0.0, 0.5, 0.5 },
66};
67
Keith Whitwell2884c312009-09-17 12:09:16 +010068#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
Brian Paul83fbee62009-09-21 11:09:00 -060069
Keith Whitwell2884c312009-09-17 12:09:16 +010070
71/** Called from test harness/main */
72void
73PerfInit(void)
74{
75 /* setup VBO w/ vertex data */
76 glGenBuffersARB(1, &VBO);
77 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
78 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
79 sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
80 glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
81 glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
82 glEnableClientState(GL_VERTEX_ARRAY);
83 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
84
85 /* texture */
86 glGenTextures(1, &TexObj);
87 glBindTexture(GL_TEXTURE_2D, TexObj);
88 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
89 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
90 glEnable(GL_TEXTURE_2D);
91}
92
93
Keith Whitwell0ec26cc2009-09-22 17:59:24 +010094
95
96static void
97CreateUploadTexImage2D(unsigned count)
98{
99 unsigned i;
100 for (i = 0; i < count; i++) {
101 if (TexObj)
102 glDeleteTextures(1, &TexObj);
103
104 glGenTextures(1, &TexObj);
105 glBindTexture(GL_TEXTURE_2D, TexObj);
106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
107 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
108
109 glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
110 TexSize, TexSize, 0,
111 TexSrcFormat, TexSrcType, TexImage);
112
113 if (DrawPoint)
114 glDrawArrays(GL_POINTS, 0, 1);
115 }
116 glFinish();
117}
118
119
Keith Whitwell2884c312009-09-17 12:09:16 +0100120static void
121UploadTexImage2D(unsigned count)
122{
123 unsigned i;
124 for (i = 0; i < count; i++) {
125 /* XXX is this equivalent to a glTexSubImage call since we're
126 * always specifying the same image size? That case isn't optimized
127 * in Mesa but may be optimized in other drivers. Note sure how
128 * much difference that might make.
129 */
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100130 glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
Keith Whitwell2884c312009-09-17 12:09:16 +0100131 TexSize, TexSize, 0,
132 TexSrcFormat, TexSrcType, TexImage);
133 if (DrawPoint)
134 glDrawArrays(GL_POINTS, 0, 1);
135 }
136 glFinish();
137}
138
139
140static void
141UploadTexSubImage2D(unsigned count)
142{
143 unsigned i;
144 for (i = 0; i < count; i++) {
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100145 if (0 && TexSubImage4) {
Keith Whitwell2884c312009-09-17 12:09:16 +0100146 GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
147 GLsizei halfPos = TexSize - halfSize;
148 /* do glTexSubImage2D in four pieces */
149 /* lower-left */
150 glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
151 glTexSubImage2D(GL_TEXTURE_2D, 0,
152 0, 0, halfSize, halfSize,
153 TexSrcFormat, TexSrcType, TexImage);
154 /* lower-right */
155 glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
156 glTexSubImage2D(GL_TEXTURE_2D, 0,
157 halfPos, 0, halfSize, halfSize,
158 TexSrcFormat, TexSrcType, TexImage);
159 /* upper-left */
160 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
161 glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
162 glTexSubImage2D(GL_TEXTURE_2D, 0,
163 0, halfPos, halfSize, halfSize,
164 TexSrcFormat, TexSrcType, TexImage);
165 /* upper-right */
166 glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
167 glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
168 glTexSubImage2D(GL_TEXTURE_2D, 0,
169 halfPos, halfPos, halfSize, halfSize,
170 TexSrcFormat, TexSrcType, TexImage);
171 /* reset the unpacking state */
172 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
173 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
174 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
Keith Whitwell89f27992009-09-22 11:58:09 +0100175 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
176
Keith Whitwell2884c312009-09-17 12:09:16 +0100177 }
178 else {
179 /* replace whole texture image at once */
180 glTexSubImage2D(GL_TEXTURE_2D, 0,
181 0, 0, TexSize, TexSize,
182 TexSrcFormat, TexSrcType, TexImage);
183 }
184 if (DrawPoint)
185 glDrawArrays(GL_POINTS, 0, 1);
186 }
187 glFinish();
188}
189
190
191/* XXX any other formats to measure? */
192static const struct {
193 GLenum format, type;
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100194 GLenum internal_format;
Keith Whitwell2884c312009-09-17 12:09:16 +0100195 const char *name;
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100196 GLuint texel_size;
197 GLboolean full_test;
Keith Whitwell2884c312009-09-17 12:09:16 +0100198} SrcFormats[] = {
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100199 { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, "RGBA/ubyte", 4, GL_TRUE },
200 { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, "RGB/ubyte", 3, GL_FALSE },
201 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, "RGB/565", 2, GL_FALSE },
202 { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, "BGRA/ubyte", 4, GL_FALSE },
203 { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, "L/ubyte", 1, GL_FALSE },
204 { 0, 0, 0, NULL, 0, 0 }
Keith Whitwell2884c312009-09-17 12:09:16 +0100205};
206
Keith Whitwella7b26592009-09-21 16:55:12 +0100207void
208PerfNextRound(void)
209{
210}
Keith Whitwell2884c312009-09-17 12:09:16 +0100211
212
213/** Called from test harness/main */
214void
215PerfDraw(void)
216{
217 GLint maxSize;
218 double rate;
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100219 GLint fmt, mode;
Keith Whitwell2884c312009-09-17 12:09:16 +0100220
221 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
222
223 /* loop over source data formats */
224 for (fmt = 0; SrcFormats[fmt].format; fmt++) {
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100225 TexIntFormat = SrcFormats[fmt].internal_format;
Keith Whitwell2884c312009-09-17 12:09:16 +0100226 TexSrcFormat = SrcFormats[fmt].format;
227 TexSrcType = SrcFormats[fmt].type;
228
229 /* loop over glTexImage, glTexSubImage */
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100230 for (mode = 0; mode < 3; mode++) {
231 GLuint minsz, maxsz;
232
233 if (SrcFormats[fmt].full_test) {
234 minsz = 16;
235 maxsz = 4096;
236 }
237 else {
238 minsz = maxsz = 256;
239 if (mode == MODE_CREATE_TEXIMAGE)
240 continue;
241 }
Keith Whitwell2884c312009-09-17 12:09:16 +0100242
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100243 /* loop over a defined range of texture sizes, test only the
244 * ones which are legal for this driver.
245 */
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100246 for (TexSize = minsz; TexSize <= maxsz; TexSize *= 4) {
Keith Whitwell2884c312009-09-17 12:09:16 +0100247 double mbPerSec;
248
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100249 if (TexSize <= maxSize) {
250 GLint bytesPerImage;
Keith Whitwell2884c312009-09-17 12:09:16 +0100251
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100252 bytesPerImage = TexSize * TexSize * SrcFormats[fmt].texel_size;
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100253 TexImage = malloc(bytesPerImage);
254
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100255 switch (mode) {
256 case MODE_TEXIMAGE:
257 rate = PerfMeasureRate(UploadTexImage2D);
258 break;
259
260 case MODE_CREATE_TEXIMAGE:
261 rate = PerfMeasureRate(CreateUploadTexImage2D);
262 break;
263
264 case MODE_TEXSUBIMAGE:
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100265 /* create initial, empty texture */
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100266 glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100267 TexSize, TexSize, 0,
268 TexSrcFormat, TexSrcType, NULL);
269 rate = PerfMeasureRate(UploadTexSubImage2D);
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100270 break;
271
272 default:
273 exit(1);
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100274 }
275
276 mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
277 free(TexImage);
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100278
279
280 {
281 unsigned err;
282 err = glGetError();
283 if (err) {
284 perf_printf("non-zero glGetError() %d\n", err);
285 exit(1);
286 }
287 }
288
Keith Whitwell2884c312009-09-17 12:09:16 +0100289 }
290 else {
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100291 rate = 0;
292 mbPerSec = 0;
Keith Whitwell2884c312009-09-17 12:09:16 +0100293 }
294
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100295 perf_printf(" %s(%s %d x %d): "
Keith Whitwell2884c312009-09-17 12:09:16 +0100296 "%.1f images/sec, %.1f MB/sec\n",
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100297 mode_name[mode],
Keith Whitwell2884c312009-09-17 12:09:16 +0100298 SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
Keith Whitwell2884c312009-09-17 12:09:16 +0100299 }
Keith Whitwell6a09c9d2009-09-22 12:35:56 +0100300
Keith Whitwell0ec26cc2009-09-22 17:59:24 +0100301 if (SrcFormats[fmt].full_test)
302 perf_printf("\n");
Keith Whitwell2884c312009-09-17 12:09:16 +0100303 }
304 }
305
306 exit(0);
307}