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