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 glTexSubImage2D rate
33 int WinWidth
= 100, WinHeight
= 100;
36 static GLuint TexObj
= 0;
37 static GLubyte
*TexImage
= NULL
;
38 static GLsizei TexSize
;
39 static GLenum TexSrcFormat
, TexSrcType
;
41 static const GLboolean DrawPoint
= GL_TRUE
;
42 static const GLboolean TexSubImage4
= GL_TRUE
;
49 static const struct vertex vertices
[1] = {
50 { 0.0, 0.0, 0.5, 0.5 },
54 #define VOFFSET(F) ((void *) offsetof(struct vertex, F))
56 #define VOFFSET(F) ((void *) &((struct vertex *)NULL)->F)
59 /** Called from test harness/main */
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
);
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
);
83 UploadTexImage2D(unsigned count
)
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.
92 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
,
94 TexSrcFormat
, TexSrcType
, TexImage
);
96 glDrawArrays(GL_POINTS
, 0, 1);
103 UploadTexSubImage2D(unsigned count
)
106 for (i
= 0; i
< count
; i
++) {
108 GLsizei halfSize
= (TexSize
== 1) ? 1 : TexSize
/ 2;
109 GLsizei halfPos
= TexSize
- halfSize
;
110 /* do glTexSubImage2D in four pieces */
112 glPixelStorei(GL_UNPACK_ROW_LENGTH
, TexSize
);
113 glTexSubImage2D(GL_TEXTURE_2D
, 0,
114 0, 0, halfSize
, halfSize
,
115 TexSrcFormat
, TexSrcType
, TexImage
);
117 glPixelStorei(GL_UNPACK_SKIP_PIXELS
, halfPos
);
118 glTexSubImage2D(GL_TEXTURE_2D
, 0,
119 halfPos
, 0, halfSize
, halfSize
,
120 TexSrcFormat
, TexSrcType
, TexImage
);
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
);
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);
139 /* replace whole texture image at once */
140 glTexSubImage2D(GL_TEXTURE_2D
, 0,
141 0, 0, TexSize
, TexSize
,
142 TexSrcFormat
, TexSrcType
, TexImage
);
145 glDrawArrays(GL_POINTS
, 0, 1);
151 /* XXX any other formats to measure? */
152 static const struct {
156 { GL_RGBA
, GL_UNSIGNED_BYTE
, "GL_RGBA/GLubyte" },
157 { GL_BGRA
, GL_UNSIGNED_BYTE
, "GL_BGRA/GLubyte" },
163 /** Called from test harness/main */
171 glGetIntegerv(GL_MAX_TEXTURE_SIZE
, &maxSize
);
173 /* loop over source data formats */
174 for (fmt
= 0; SrcFormats
[fmt
].format
; fmt
++) {
175 TexSrcFormat
= SrcFormats
[fmt
].format
;
176 TexSrcType
= SrcFormats
[fmt
].type
;
178 /* loop over glTexImage, glTexSubImage */
179 for (subImage
= 0; subImage
< 2; subImage
++) {
181 /* loop over texture sizes */
182 for (TexSize
= 16; TexSize
<= maxSize
; TexSize
*= 2) {
186 bytesPerImage
= TexSize
* TexSize
* 4;
187 TexImage
= malloc(bytesPerImage
);
190 /* create initial, empty texture */
191 glTexImage2D(GL_TEXTURE_2D
, 0, GL_RGBA
,
193 TexSrcFormat
, TexSrcType
, NULL
);
194 rate
= PerfMeasureRate(UploadTexSubImage2D
);
197 rate
= PerfMeasureRate(UploadTexImage2D
);
200 mbPerSec
= rate
* bytesPerImage
/ (1024.0 * 1024.0);
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
);