Add more structure constructor tests.
[piglit/hramrach.git] / tests / texturing / texture-integer.c
blob58f01d96a42cf113cd61f59772c38bec858c9da8
1 /*
2 * Copyright (c) 2010 VMware, Inc.
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 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NON-INFRINGEMENT. IN NO EVENT SHALL VMWARE AND/OR THEIR SUPPLIERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
25 /**
26 * @file
27 * Tests GL_EXT_texture_integer texture formats (and GL_EXT_gpu_shader4).
30 #include "piglit-util.h"
32 int piglit_width = 100, piglit_height = 100;
33 int piglit_window_mode = GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE;
35 static const char *TestName = "texture-integer";
37 static GLint TexWidth = 16, TexHeight = 16;
38 static GLuint Texture;
40 static GLint BiasUniform = -1, TexUniform = -1;
42 struct format_info
44 const char *Name;
45 GLenum IntFormat, BaseFormat;
46 GLuint BitsPerChannel;
47 GLboolean Signed;
51 static const struct format_info Formats[] = {
52 /* { "GL_RGBA", GL_RGBA, GL_RGBA, 8, GL_FALSE },*/
53 { "GL_RGBA8I_EXT", GL_RGBA8I_EXT, GL_RGBA_INTEGER_EXT, 8, GL_TRUE },
54 { "GL_RGBA8UI_EXT", GL_RGBA8UI_EXT , GL_RGBA_INTEGER_EXT, 8, GL_FALSE },
55 { "GL_RGBA16I_EXT", GL_RGBA16I_EXT, GL_RGBA_INTEGER_EXT, 16, GL_TRUE },
56 { "GL_RGBA16UI_EXT", GL_RGBA16UI_EXT, GL_RGBA_INTEGER_EXT, 16, GL_FALSE },
57 { "GL_RGBA32I_EXT", GL_RGBA32I_EXT, GL_RGBA_INTEGER_EXT, 32, GL_TRUE },
58 { "GL_RGBA32UI_EXT", GL_RGBA32UI_EXT, GL_RGBA_INTEGER_EXT, 32, GL_FALSE },
60 { "GL_RGB8I_EXT", GL_RGB8I_EXT, GL_RGB_INTEGER_EXT, 8, GL_TRUE },
61 { "GL_RGB8UI_EXT", GL_RGB8UI_EXT , GL_RGB_INTEGER_EXT, 8, GL_FALSE },
62 { "GL_RGB16I_EXT", GL_RGB16I_EXT, GL_RGB_INTEGER_EXT, 16, GL_TRUE },
63 { "GL_RGB16UI_EXT", GL_RGB16UI_EXT, GL_RGB_INTEGER_EXT, 16, GL_FALSE },
64 { "GL_RGB32I_EXT", GL_RGB32I_EXT, GL_RGB_INTEGER_EXT, 32, GL_TRUE },
65 { "GL_RGB32UI_EXT", GL_RGB32UI_EXT, GL_RGB_INTEGER_EXT, 32, GL_FALSE },
67 { "GL_ALPHA8I_EXT", GL_ALPHA8I_EXT, GL_ALPHA_INTEGER_EXT, 8, GL_TRUE },
68 { "GL_ALPHA8UI_EXT", GL_ALPHA8UI_EXT , GL_ALPHA_INTEGER_EXT, 8, GL_FALSE },
69 { "GL_ALPHA16I_EXT", GL_ALPHA16I_EXT, GL_ALPHA_INTEGER_EXT, 16, GL_TRUE },
70 { "GL_ALPHA16UI_EXT", GL_ALPHA16UI_EXT, GL_ALPHA_INTEGER_EXT, 16, GL_FALSE },
71 { "GL_ALPHA32I_EXT", GL_ALPHA32I_EXT, GL_ALPHA_INTEGER_EXT, 32, GL_TRUE },
72 { "GL_ALPHA32UI_EXT", GL_ALPHA32UI_EXT, GL_ALPHA_INTEGER_EXT, 32, GL_FALSE },
74 { "GL_LUMINANCE8I_EXT", GL_LUMINANCE8I_EXT, GL_LUMINANCE_INTEGER_EXT, 8, GL_TRUE },
75 { "GL_LUMINANCE8UI_EXT", GL_LUMINANCE8UI_EXT , GL_LUMINANCE_INTEGER_EXT, 8, GL_FALSE },
76 { "GL_LUMINANCE16I_EXT", GL_LUMINANCE16I_EXT, GL_LUMINANCE_INTEGER_EXT, 16, GL_TRUE },
77 { "GL_LUMINANCE16UI_EXT", GL_LUMINANCE16UI_EXT, GL_LUMINANCE_INTEGER_EXT, 16, GL_FALSE },
78 { "GL_LUMINANCE32I_EXT", GL_LUMINANCE32I_EXT, GL_LUMINANCE_INTEGER_EXT, 32, GL_TRUE },
79 { "GL_LUMINANCE32UI_EXT", GL_LUMINANCE32UI_EXT, GL_LUMINANCE_INTEGER_EXT, 32, GL_FALSE },
81 { "GL_LUMINANCE_ALPHA8I_EXT", GL_LUMINANCE_ALPHA8I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 8, GL_TRUE },
82 { "GL_LUMINANCE_ALPHA8UI_EXT", GL_LUMINANCE_ALPHA8UI_EXT , GL_LUMINANCE_ALPHA_INTEGER_EXT, 8, GL_FALSE },
83 { "GL_LUMINANCE_ALPHA16I_EXT", GL_LUMINANCE_ALPHA16I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 16, GL_TRUE },
84 { "GL_LUMINANCE_ALPHA16UI_EXT", GL_LUMINANCE_ALPHA16UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 16, GL_FALSE },
85 { "GL_LUMINANCE_ALPHA32I_EXT", GL_LUMINANCE_ALPHA32I_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 32, GL_TRUE },
86 { "GL_LUMINANCE_ALPHA32UI_EXT", GL_LUMINANCE_ALPHA32UI_EXT, GL_LUMINANCE_ALPHA_INTEGER_EXT, 32, GL_FALSE },
88 { "GL_INTENSITY8I_EXT", GL_INTENSITY8I_EXT, GL_RED_INTEGER_EXT, 8, GL_TRUE },
89 { "GL_INTENSITY8UI_EXT", GL_INTENSITY8UI_EXT , GL_RED_INTEGER_EXT, 8, GL_FALSE },
90 { "GL_INTENSITY16I_EXT", GL_INTENSITY16I_EXT, GL_RED_INTEGER_EXT, 16, GL_TRUE },
91 { "GL_INTENSITY16UI_EXT", GL_INTENSITY16UI_EXT, GL_RED_INTEGER_EXT, 16, GL_FALSE },
92 { "GL_INTENSITY32I_EXT", GL_INTENSITY32I_EXT, GL_RED_INTEGER_EXT, 32, GL_TRUE },
93 { "GL_INTENSITY32UI_EXT", GL_INTENSITY32UI_EXT, GL_RED_INTEGER_EXT, 32, GL_FALSE },
97 #define NUM_FORMATS (sizeof(Formats) / sizeof(Formats[0]))
100 static const char *FragShaderText =
101 "#extension GL_EXT_gpu_shader4: enable \n"
102 "uniform vec4 bias; \n"
103 "#if GL_EXT_gpu_shader4 \n"
104 " uniform isampler2D tex; \n"
105 "#else \n"
106 " uniform sampler2D tex; \n"
107 "#endif \n"
108 "void main() \n"
109 "{ \n"
110 "#if GL_EXT_gpu_shader4 \n"
111 " vec4 t = vec4(texture2D(tex, gl_TexCoord[0].xy)); \n"
112 "#else \n"
113 " vec4 t = texture2D(tex, gl_TexCoord[0].xy); \n"
114 "#endif \n"
115 " gl_FragColor = t + bias; \n"
116 "} \n";
118 static GLuint FragShader, Program;
122 static int
123 get_max_val(const struct format_info *info)
125 int max;
127 switch (info->BitsPerChannel) {
128 case 8:
129 if (info->Signed)
130 max = 127;
131 else
132 max = 255;
133 break;
134 case 16:
135 if (info->Signed)
136 max = 32767;
137 else
138 max = 65535;
139 break;
140 case 32:
141 if (info->Signed)
142 max = 10*1000; /* don't use 0x8fffffff to avoid overflow issues */
143 else
144 max = 20*1000;
145 break;
146 default:
147 assert(0);
148 max = 0;
151 return max;
155 static int
156 num_components(GLenum format)
158 switch (format) {
159 case GL_RGBA:
160 case GL_RGBA_INTEGER_EXT:
161 return 4;
162 case GL_RGB_INTEGER_EXT:
163 return 3;
164 case GL_ALPHA_INTEGER_EXT:
165 return 1;
166 case GL_LUMINANCE_INTEGER_EXT:
167 return 1;
168 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
169 return 2;
170 case GL_RED_INTEGER_EXT:
171 return 1;
172 default:
173 assert(0);
174 return 0;
179 static void
180 fill_array(int comps, int texels, void *buf, int bpp, const int val[4])
182 int i, j;
184 switch (bpp) {
185 case 8:
187 GLubyte *b = (GLubyte *) buf;
188 for (i = 0; i < texels; i++) {
189 for (j = 0; j < comps; j++) {
190 b[i * comps + j] = val[j];
194 break;
195 case 16:
197 GLushort *b = (GLushort *) buf;
198 for (i = 0; i < texels; i++) {
199 for (j = 0; j < comps; j++) {
200 b[i * comps + j] = val[j];
204 break;
205 case 32:
207 GLuint *b = (GLuint *) buf;
208 for (i = 0; i < texels; i++) {
209 for (j = 0; j < comps; j++) {
210 b[i * comps + j] = val[j];
214 break;
215 default:
216 assert(0);
221 static GLenum
222 get_datatype(const struct format_info *info)
224 switch (info->BitsPerChannel) {
225 case 8:
226 return info->Signed ? GL_BYTE : GL_UNSIGNED_BYTE;
227 case 16:
228 return info->Signed ? GL_SHORT : GL_UNSIGNED_SHORT;
229 case 32:
230 return info->Signed ? GL_INT : GL_UNSIGNED_INT;
231 default:
232 assert(0);
233 return 0;
238 static GLboolean
239 check_error(const char *file, int line)
241 GLenum err = glGetError();
242 if (err) {
243 fprintf(stderr, "%s: error 0x%x at %s:%d\n", TestName, err, file, line);
244 return GL_TRUE;
246 return GL_FALSE;
250 /** \return GL_TRUE for pass, GL_FALSE for fail */
251 static GLboolean
252 test_format(const struct format_info *info)
254 const int max = get_max_val(info);
255 const int comps = num_components(info->BaseFormat);
256 const int texels = TexWidth * TexHeight;
257 const GLenum type = get_datatype(info);
258 const int w = piglit_width / 10;
259 const int h = piglit_height / 10;
260 const float error = 2.0 / 255.0; /* XXX fix */
261 GLfloat expected[4];
262 void *buf;
263 int value[4];
264 GLfloat result[4], bias[4];
265 GLint f;
267 /* pick random texture color */
268 value[0] = rand() % max;
269 value[1] = rand() % max;
270 value[2] = rand() % max;
271 value[3] = rand() % max;
273 /* alloc, fill texture image */
274 buf = malloc(comps * texels * info->BitsPerChannel / 8);
275 fill_array(comps, texels, buf, info->BitsPerChannel, value);
277 glTexImage2D(GL_TEXTURE_2D, 0, info->IntFormat, TexWidth, TexHeight, 0,
278 info->BaseFormat, type, buf);
280 if (check_error(__FILE__, __LINE__))
281 return GL_FALSE;
283 glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_INTERNAL_FORMAT, &f);
284 assert(f == info->IntFormat);
286 /* setup expected polygon color */
287 expected[0] = 0.25;
288 expected[1] = 0.50;
289 expected[2] = 0.75;
290 expected[3] = 1.00;
292 /* need to swizzle things depending on texture format */
293 switch (info->BaseFormat) {
294 case GL_RGBA_INTEGER_EXT:
295 /* nothing */
296 break;
297 case GL_RGB_INTEGER_EXT:
298 expected[3] = 0.0;
299 break;
300 case GL_ALPHA_INTEGER_EXT:
301 expected[0] = expected[1] = expected[2] = 0.0;
302 expected[3] = 0.25;
303 value[3] = value[0];
304 break;
305 case GL_LUMINANCE_INTEGER_EXT:
306 expected[0] = expected[1] = expected[2] = 0.25;
307 expected[3] = 1.0;
308 value[1] = value[2] = value[0];
309 value[3] = 1.0;
310 break;
311 case GL_LUMINANCE_ALPHA_INTEGER_EXT:
312 expected[0] = expected[1] = expected[2] = 0.25;
313 value[3] = value[1];
314 value[1] = value[2] = value[0];
315 break;
316 case GL_RED_INTEGER_EXT:
317 expected[0] = expected[1] = expected[2] = expected[3] = 0.25;
318 value[1] = value[2] = value[3] = value[0];
319 break;
320 default:
324 /* compute, set test bias */
325 bias[0] = expected[0] - value[0];
326 bias[1] = expected[1] - value[1];
327 bias[2] = expected[2] - value[2];
328 bias[3] = expected[3] - value[3];
329 glUniform4fv(BiasUniform, 1, bias);
331 /* draw */
332 glClearColor(0, 1, 1, 0);
333 glClear(GL_COLOR_BUFFER_BIT);
334 glBegin(GL_POLYGON);
335 glTexCoord2f(0, 0); glVertex2f(0, 0);
336 glTexCoord2f(1, 0); glVertex2f(w, 0);
337 glTexCoord2f(1, 1); glVertex2f(w, h);
338 glTexCoord2f(0, 1); glVertex2f(0, h);
339 glEnd();
341 if (check_error(__FILE__, __LINE__))
342 return GL_FALSE;
344 /* test */
345 glReadPixels(w/2, h/2, 1, 1, GL_RGBA, GL_FLOAT, result);
347 if (check_error(__FILE__, __LINE__))
348 return GL_FALSE;
350 if (fabsf(result[0] - expected[0]) > error ||
351 fabsf(result[1] - expected[1]) > error ||
352 fabsf(result[2] - expected[2]) > error ||
353 fabsf(result[3] - expected[3]) > error) {
354 fprintf(stderr, "%s: failure with format %s:\n", TestName, info->Name);
355 fprintf(stderr, " texture color = %d, %d, %d, %d\n",
356 value[0], value[1], value[2], value[3]);
357 fprintf(stderr, " expected color = %g, %g, %g, %g\n",
358 expected[0], expected[1], expected[2], expected[3]);
359 fprintf(stderr, " result color = %g, %g, %g, %g\n",
360 result[0], result[1], result[2], result[3]);
361 return GL_FALSE;
364 glutSwapBuffers();
366 free(buf);
368 return GL_TRUE;
372 enum piglit_result
373 piglit_display(void)
375 int f, i;
376 for (f = 0; f < NUM_FORMATS; f++) {
377 for (i = 0; i < 5; i++) {
378 GLboolean pass = test_format(&Formats[f]);
379 if (!pass)
380 return PIGLIT_FAILURE;
383 return PIGLIT_SUCCESS;
387 void
388 piglit_init(int argc, char **argv)
390 piglit_require_extension("GL_EXT_texture_integer");
391 piglit_require_extension("GL_EXT_gpu_shader4");
393 FragShader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, FragShaderText);
394 assert(FragShader);
396 Program = piglit_link_simple_program(0, FragShader);
398 glUseProgram(Program);
400 BiasUniform = glGetUniformLocation(Program, "bias");
401 TexUniform = glGetUniformLocation(Program, "tex");
403 glUniform1i(TexUniform, 0); /* tex unit zero */
405 (void) check_error(__FILE__, __LINE__);
407 glGenTextures(1, &Texture);
408 glBindTexture(GL_TEXTURE_2D, Texture);
409 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
410 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
412 (void) check_error(__FILE__, __LINE__);
414 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);