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
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
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;
45 GLenum IntFormat
, BaseFormat
;
46 GLuint BitsPerChannel
;
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"
106 " uniform sampler2D tex; \n"
110 "#if GL_EXT_gpu_shader4 \n"
111 " vec4 t = vec4(texture2D(tex, gl_TexCoord[0].xy)); \n"
113 " vec4 t = texture2D(tex, gl_TexCoord[0].xy); \n"
115 " gl_FragColor = t + bias; \n"
118 static GLuint FragShader
, Program
;
123 get_max_val(const struct format_info
*info
)
127 switch (info
->BitsPerChannel
) {
142 max
= 10*1000; /* don't use 0x8fffffff to avoid overflow issues */
156 num_components(GLenum format
)
160 case GL_RGBA_INTEGER_EXT
:
162 case GL_RGB_INTEGER_EXT
:
164 case GL_ALPHA_INTEGER_EXT
:
166 case GL_LUMINANCE_INTEGER_EXT
:
168 case GL_LUMINANCE_ALPHA_INTEGER_EXT
:
170 case GL_RED_INTEGER_EXT
:
180 fill_array(int comps
, int texels
, void *buf
, int bpp
, const int val
[4])
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
];
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
];
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
];
222 get_datatype(const struct format_info
*info
)
224 switch (info
->BitsPerChannel
) {
226 return info
->Signed
? GL_BYTE
: GL_UNSIGNED_BYTE
;
228 return info
->Signed
? GL_SHORT
: GL_UNSIGNED_SHORT
;
230 return info
->Signed
? GL_INT
: GL_UNSIGNED_INT
;
239 check_error(const char *file
, int line
)
241 GLenum err
= glGetError();
243 fprintf(stderr
, "%s: error 0x%x at %s:%d\n", TestName
, err
, file
, line
);
250 /** \return GL_TRUE for pass, GL_FALSE for fail */
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 */
264 GLfloat result
[4], bias
[4];
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__
))
283 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_INTERNAL_FORMAT
, &f
);
284 assert(f
== info
->IntFormat
);
286 /* setup expected polygon color */
292 /* need to swizzle things depending on texture format */
293 switch (info
->BaseFormat
) {
294 case GL_RGBA_INTEGER_EXT
:
297 case GL_RGB_INTEGER_EXT
:
300 case GL_ALPHA_INTEGER_EXT
:
301 expected
[0] = expected
[1] = expected
[2] = 0.0;
305 case GL_LUMINANCE_INTEGER_EXT
:
306 expected
[0] = expected
[1] = expected
[2] = 0.25;
308 value
[1] = value
[2] = value
[0];
311 case GL_LUMINANCE_ALPHA_INTEGER_EXT
:
312 expected
[0] = expected
[1] = expected
[2] = 0.25;
314 value
[1] = value
[2] = value
[0];
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];
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
);
332 glClearColor(0, 1, 1, 0);
333 glClear(GL_COLOR_BUFFER_BIT
);
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
);
341 if (check_error(__FILE__
, __LINE__
))
345 glReadPixels(w
/2, h
/2, 1, 1, GL_RGBA
, GL_FLOAT
, result
);
347 if (check_error(__FILE__
, __LINE__
))
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]);
376 for (f
= 0; f
< NUM_FORMATS
; f
++) {
377 for (i
= 0; i
< 5; i
++) {
378 GLboolean pass
= test_format(&Formats
[f
]);
380 return PIGLIT_FAILURE
;
383 return PIGLIT_SUCCESS
;
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
);
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
);