blob: 9e032ad0c9b43f58e51abc93d5772e576a5ed9b9 [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;
39static GLenum TexSrcFormat, TexSrcType;
40
41static const GLboolean DrawPoint = GL_TRUE;
42static const GLboolean TexSubImage4 = GL_TRUE;
43
44struct vertex
45{
46 GLfloat x, y, s, t;
47};
48
49static const struct vertex vertices[1] = {
50 { 0.0, 0.0, 0.5, 0.5 },
51};
52
Keith Whitwell2884c312009-09-17 12:09:16 +010053#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
Brian Paul83fbee62009-09-21 11:09:00 -060054
Keith Whitwell2884c312009-09-17 12:09:16 +010055
56/** Called from test harness/main */
57void
58PerfInit(void)
59{
60 /* setup VBO w/ vertex data */
61 glGenBuffersARB(1, &VBO);
62 glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
63 glBufferDataARB(GL_ARRAY_BUFFER_ARB,
64 sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
65 glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
66 glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
67 glEnableClientState(GL_VERTEX_ARRAY);
68 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
69
70 /* texture */
71 glGenTextures(1, &TexObj);
72 glBindTexture(GL_TEXTURE_2D, TexObj);
73 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
74 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
75 glEnable(GL_TEXTURE_2D);
76}
77
78
79static void
80UploadTexImage2D(unsigned count)
81{
82 unsigned i;
83 for (i = 0; i < count; i++) {
84 /* XXX is this equivalent to a glTexSubImage call since we're
85 * always specifying the same image size? That case isn't optimized
86 * in Mesa but may be optimized in other drivers. Note sure how
87 * much difference that might make.
88 */
89 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
90 TexSize, TexSize, 0,
91 TexSrcFormat, TexSrcType, TexImage);
92 if (DrawPoint)
93 glDrawArrays(GL_POINTS, 0, 1);
94 }
95 glFinish();
96}
97
98
99static void
100UploadTexSubImage2D(unsigned count)
101{
102 unsigned i;
103 for (i = 0; i < count; i++) {
104 if (TexSubImage4) {
105 GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
106 GLsizei halfPos = TexSize - halfSize;
107 /* do glTexSubImage2D in four pieces */
108 /* lower-left */
109 glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
110 glTexSubImage2D(GL_TEXTURE_2D, 0,
111 0, 0, halfSize, halfSize,
112 TexSrcFormat, TexSrcType, TexImage);
113 /* lower-right */
114 glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
115 glTexSubImage2D(GL_TEXTURE_2D, 0,
116 halfPos, 0, halfSize, halfSize,
117 TexSrcFormat, TexSrcType, TexImage);
118 /* upper-left */
119 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
120 glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
121 glTexSubImage2D(GL_TEXTURE_2D, 0,
122 0, halfPos, halfSize, halfSize,
123 TexSrcFormat, TexSrcType, TexImage);
124 /* upper-right */
125 glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
126 glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
127 glTexSubImage2D(GL_TEXTURE_2D, 0,
128 halfPos, halfPos, halfSize, halfSize,
129 TexSrcFormat, TexSrcType, TexImage);
130 /* reset the unpacking state */
131 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
132 glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
133 glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
Keith Whitwell89f27992009-09-22 11:58:09 +0100134 glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
135
Keith Whitwell2884c312009-09-17 12:09:16 +0100136 }
137 else {
138 /* replace whole texture image at once */
139 glTexSubImage2D(GL_TEXTURE_2D, 0,
140 0, 0, TexSize, TexSize,
141 TexSrcFormat, TexSrcType, TexImage);
142 }
143 if (DrawPoint)
144 glDrawArrays(GL_POINTS, 0, 1);
145 }
146 glFinish();
147}
148
149
150/* XXX any other formats to measure? */
151static const struct {
152 GLenum format, type;
153 const char *name;
154} SrcFormats[] = {
155 { GL_RGBA, GL_UNSIGNED_BYTE, "GL_RGBA/GLubyte" },
156 { GL_BGRA, GL_UNSIGNED_BYTE, "GL_BGRA/GLubyte" },
157 { 0, 0, NULL }
158};
159
Keith Whitwella7b26592009-09-21 16:55:12 +0100160void
161PerfNextRound(void)
162{
163}
Keith Whitwell2884c312009-09-17 12:09:16 +0100164
165
166/** Called from test harness/main */
167void
168PerfDraw(void)
169{
170 GLint maxSize;
171 double rate;
172 GLint fmt, subImage;
173
174 glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
175
176 /* loop over source data formats */
177 for (fmt = 0; SrcFormats[fmt].format; fmt++) {
178 TexSrcFormat = SrcFormats[fmt].format;
179 TexSrcType = SrcFormats[fmt].type;
180
181 /* loop over glTexImage, glTexSubImage */
182 for (subImage = 0; subImage < 2; subImage++) {
183
184 /* loop over texture sizes */
Keith Whitwell89f27992009-09-22 11:58:09 +0100185 for (TexSize = 16; TexSize <= maxSize; TexSize *= 4) {
Keith Whitwell2884c312009-09-17 12:09:16 +0100186 GLint bytesPerImage;
187 double mbPerSec;
188
189 bytesPerImage = TexSize * TexSize * 4;
190 TexImage = malloc(bytesPerImage);
191
192 if (subImage) {
193 /* create initial, empty texture */
194 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
195 TexSize, TexSize, 0,
196 TexSrcFormat, TexSrcType, NULL);
197 rate = PerfMeasureRate(UploadTexSubImage2D);
198 }
199 else {
200 rate = PerfMeasureRate(UploadTexImage2D);
201 }
202
203 mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
204
205 perf_printf(" glTex%sImage2D(%s %d x %d): "
206 "%.1f images/sec, %.1f MB/sec\n",
207 (subImage ? "Sub" : ""),
208 SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
209
210 free(TexImage);
211 }
212 }
213 }
214
215 exit(0);
216}