1 /*
2 * Copyright (c) 2004 Brian Paul
3 * Copyright (c) 2011 VMware, Inc.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 */
24
25 /*
26 * Test packed pixel formats for textures. Try a bunch of combinations
27 * of various internal texture formats with combinations of packed user
28 * formats/types. Also test glPixelStore byte swapping.
29 *
30 * Based on mesa-demos/tests/packedpixels.c.
31 * Brian Paul
32 * June 2011
33 */
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <math.h>
39 #include <string.h>
40 #include "piglit-util-gl.h"
41
42 PIGLIT_GL_TEST_CONFIG_BEGIN
43
44 config.supports_gl_compat_version = 10;
45
46 config.window_width = 700;
47 config.window_height = 620;
48 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
49 config.khr_no_error_support = PIGLIT_NO_ERRORS;
50
51 PIGLIT_GL_TEST_CONFIG_END
52
53 struct pixel_format {
54 GLenum format;
55 GLenum type;
56 GLint bytes;
57 GLuint redTexel, greenTexel; /* with approx 51% alpha, when applicable */
58 };
59
60 static const struct pixel_format Formats[] = {
61
62 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, 4, 0xff000080, 0x00ff0080 },
63 { GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x800000ff, 0x8000ff00 },
64 { GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 4, 0xffc00002, 0x3ff002 },
65 { GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, 4, 0xc00003ff, 0xc00ffc00 },
66 { GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0xf008, 0x0f08 },
67 { GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x800f, 0x80f0 },
68 { GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0xf801, 0x7c1 },
69 { GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0x801f, 0x83e0 },
70
71 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8, 4, 0x0000ff80, 0x00ff0080 },
72 { GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 4, 0x80ff0000, 0x8000ff00 },
73 { GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4, 2, 0x00f8, 0x0f08 },
74 { GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 2, 0x8f00, 0x80f0 },
75 { GL_BGRA, GL_UNSIGNED_SHORT_5_5_5_1, 2, 0x3f, 0x7c1 },
76 { GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 2, 0xfc00, 0x83e0 },
77
78 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 2, 0xf800, 0x7e0 },
79 { GL_RGB, GL_UNSIGNED_SHORT_5_6_5_REV, 2, 0x1f, 0x7e0 },
80 { GL_RGB, GL_UNSIGNED_BYTE_3_3_2, 1, 0xe0, 0x1c },
81 { GL_RGB, GL_UNSIGNED_BYTE_2_3_3_REV, 1, 0x7, 0x38 }
82 };
83
84 #define NUM_FORMATS (sizeof(Formats) / sizeof(Formats[0]))
85
86 static const GLenum IntFormats[] = {
87 GL_RGBA,
88 GL_RGBA2,
89 GL_RGBA4,
90 GL_RGB5_A1,
91 GL_RGBA8,
92 GL_RGBA12,
93 GL_RGBA16,
94 GL_RGB10_A2,
95
96 GL_RGB,
97 GL_R3_G3_B2,
98 GL_RGB4,
99 GL_RGB5,
100 GL_RGB8,
101 GL_RGB10,
102 GL_RGB12,
103 GL_RGB16,
104
105 };
106
107 #define NUM_INT_FORMATS (sizeof(IntFormats) / sizeof(IntFormats[0]))
108
109 static void
MakeTexture(GLuint dims,const struct pixel_format * format,GLenum intFormat,GLboolean swap)110 MakeTexture(GLuint dims, const struct pixel_format *format,
111 GLenum intFormat, GLboolean swap)
112 {
113 GLubyte texBuffer[1000];
114 int i;
115
116 assert(dims == 2 || dims == 3);
117
118 glPixelStorei(GL_UNPACK_SWAP_BYTES, swap);
119
120 if (format->bytes == 1) {
121 for (i = 0; i < 8; i++) {
122 texBuffer[i] = format->redTexel;
123 }
124 for (i = 8; i < 16; i++) {
125 texBuffer[i] = format->greenTexel;
126 }
127 }
128 else if (format->bytes == 2) {
129 GLushort *us = (GLushort *) texBuffer;
130 for (i = 0; i < 8; i++) {
131 us[i] = format->redTexel;
132 }
133 for (i = 8; i < 16; i++) {
134 us[i] = format->greenTexel;
135 }
136 if (swap) {
137 for (i = 0; i < 16; i++)
138 us[i] = (us[i] << 8) | (us[i] >> 8);
139 }
140 }
141 else if (format->bytes == 4) {
142 GLuint *ui = (GLuint *) texBuffer;
143 for (i = 0; i < 8; i++) {
144 ui[i] = format->redTexel;
145 }
146 for (i = 8; i < 16; i++) {
147 ui[i] = format->greenTexel;
148 }
149 if (swap) {
150 for (i = 0; i < 16; i++) {
151 GLuint b = ui[i];
152 ui[i] = (b >> 24)
153 | ((b >> 8) & 0xff00)
154 | ((b << 8) & 0xff0000)
155 | ((b << 24) & 0xff000000);
156 }
157 }
158 }
159 else {
160 abort();
161 }
162
163 if (dims == 3) {
164 /* 4 x 4 x 4 texture, undefined data */
165 glTexImage3D(GL_TEXTURE_3D, 0, intFormat, 4, 4, 4, 0,
166 format->format, format->type, NULL);
167 /* fill in Z=1 and Z=2 slices with the real texture data */
168 glTexSubImage3D(GL_TEXTURE_3D, 0,
169 0, 0, 1, /* offset */
170 4, 4, 1, /* size */
171 format->format, format->type, texBuffer);
172 glTexSubImage3D(GL_TEXTURE_3D, 0,
173 0, 0, 2, /* offset */
174 4, 4, 1, /* size */
175 format->format, format->type, texBuffer);
176 }
177 else {
178 glTexImage2D(GL_TEXTURE_2D, 0, intFormat, 4, 4, 0,
179 format->format, format->type, texBuffer);
180 }
181
182 if (0) {
183 GLint r, g, b, a, l, i;
184 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_RED_SIZE, &r);
185 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_GREEN_SIZE, &g);
186 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_BLUE_SIZE, &b);
187 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_ALPHA_SIZE, &a);
188 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_LUMINANCE_SIZE, &l);
189 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTENSITY_SIZE, &i);
190 printf("IntFormat: 0x%x R %d G %d B %d A %d L %d I %d\n",
191 intFormat, r, g, b, a, l, i);
192 glGetError();
193 }
194 }
195
196 /**
197 * Test a particular internal texture format. 2D or 3D texture.
198 */
199 static GLboolean
Test(GLuint intFmt,GLuint dims)200 Test(GLuint intFmt, GLuint dims)
201 {
202 static const float red[4] = {1, 0, 0, 1};
203 static const float green[4] = {0, 1, 0, 1};
204 int w = 4, h = 4;
205 int i, swap;
206 GLboolean pass = GL_TRUE;
207
208 piglit_ortho_projection(piglit_width, piglit_height, false);
209 assert(NUM_FORMATS * 5 < piglit_height);
210
211 glClear(GL_COLOR_BUFFER_BIT);
212
213 if (dims == 3)
214 glEnable(GL_TEXTURE_3D);
215 else
216 glEnable(GL_TEXTURE_2D);
217
218 /* Loop over byteswapping */
219 for (swap = 0; swap < 2; swap++) {
220 /* Loop over texture formats */
221 for (i = 0; i < NUM_FORMATS; i++) {
222 int x = 5 * swap;
223 int y = 5 * i;
224
225 MakeTexture(dims, Formats + i, IntFormats[intFmt],
226 swap);
227
228 if (glGetError()) {
229 printf("Unexpected GL Error for %s\n",
230 piglit_get_gl_enum_name(
231 IntFormats[intFmt]));
232 return GL_FALSE;
233 }
234
235 glBegin(GL_POLYGON);
236 glTexCoord3f(0, 0, 0.5); glVertex2f(x + 0, y + 0);
237 glTexCoord3f(1, 0, 0.5); glVertex2f(x + w, y + 0);
238 glTexCoord3f(1, 1, 0.5); glVertex2f(x + w, y + h);
239 glTexCoord3f(0, 1, 0.5); glVertex2f(x + 0, y + h);
240 glEnd();
241 }
242 }
243
244 if (dims == 3)
245 glDisable(GL_TEXTURE_3D);
246 else
247 glDisable(GL_TEXTURE_2D);
248
249 /* Loop over byteswapping */
250 for (swap = 0; swap < 2; swap++) {
251 /* Loop over texture formats */
252 for (i = 0; i < NUM_FORMATS; i++) {
253 int x = 5 * swap;
254 int y = 5 * i;
255 char *name;
256 asprintf(&name, "%s/%s",
257 piglit_get_gl_enum_name(Formats[i].format),
258 piglit_get_gl_enum_name(Formats[i].type));
259 /* test rendering */
260 if (!piglit_probe_rect_rgb(x, y, w, 2, red)) {
261 printf("Failure for format=%s, swap=%u, "
262 "textureDims=%u\n",
263 name, swap, dims);
264 pass = GL_FALSE;
265 }
266
267 if (!piglit_probe_rect_rgb(x, y + 2, w, 2, green)) {
268 printf("Failure for format=%s, swap=%u, "
269 "textureDims=%u\n",
270 name, swap, dims);
271 pass = GL_FALSE;
272 }
273 free(name);
274 }
275 }
276
277 piglit_present_results();
278
279 return pass;
280 }
281
282 enum piglit_result
piglit_display(void)283 piglit_display(void)
284 {
285 GLboolean pass = 1;
286 int i;
287
288 /* 2D texture */
289 for (i = 0; i < NUM_INT_FORMATS; i++) {
290 pass = Test(i, 2) && pass;
291 if (!pass && !piglit_automatic)
292 break;
293 }
294
295 /* 3D texture */
296 for (i = 0; i < NUM_INT_FORMATS; i++) {
297 pass = Test(i, 3) && pass;
298 if (!pass && !piglit_automatic)
299 break;
300 }
301
302 return pass ? PIGLIT_PASS : PIGLIT_FAIL;
303 }
304
305
306 void
piglit_init(int argc,char ** argv)307 piglit_init(int argc, char **argv)
308 {
309 if (0) {
310 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
311 printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
312 }
313 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
314 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
315 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
316 glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
317 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
318 }
319
320