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.
28 * simpler test modified for GLSL1.30 by airlied
31 #include "piglit-util-gl.h"
33 PIGLIT_GL_TEST_CONFIG_BEGIN
35 config
.supports_gl_compat_version
= 10;
37 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
| PIGLIT_GL_VISUAL_DOUBLE
;
38 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
40 PIGLIT_GL_TEST_CONFIG_END
42 static const char *TestName
= "texture-integer";
44 static GLint TexWidth
= 16, TexHeight
= 16;
45 static GLuint Texture
;
47 static GLint BiasUniform
[4] = {-1, -1, -1, -1}, TexUniform
[4] = {-1, -1, -1, -1};
49 static bool has_glsl_130
;
50 static bool has_gpu_shader4
;
54 GLenum IntFormat
, BaseFormat
;
55 GLuint BitsPerChannel
;
59 static const struct format_info Formats
[] = {
60 /* { "GL_RGBA", GL_RGBA, GL_RGBA, 8, GL_FALSE },*/
61 { GL_RGBA8I_EXT
, GL_RGBA_INTEGER_EXT
, 8, GL_TRUE
},
62 { GL_RGBA8UI_EXT
, GL_RGBA_INTEGER_EXT
, 8, GL_FALSE
},
63 { GL_RGBA16I_EXT
, GL_RGBA_INTEGER_EXT
, 16, GL_TRUE
},
64 { GL_RGBA16UI_EXT
, GL_RGBA_INTEGER_EXT
, 16, GL_FALSE
},
65 { GL_RGBA32I_EXT
, GL_RGBA_INTEGER_EXT
, 32, GL_TRUE
},
66 { GL_RGBA32UI_EXT
, GL_RGBA_INTEGER_EXT
, 32, GL_FALSE
},
68 { GL_RGBA8I_EXT
, GL_BGRA_INTEGER_EXT
, 8, GL_TRUE
},
69 { GL_RGBA8UI_EXT
, GL_BGRA_INTEGER_EXT
, 8, GL_FALSE
},
70 { GL_RGBA16I_EXT
, GL_BGRA_INTEGER_EXT
, 16, GL_TRUE
},
71 { GL_RGBA16UI_EXT
, GL_BGRA_INTEGER_EXT
, 16, GL_FALSE
},
72 { GL_RGBA32I_EXT
, GL_BGRA_INTEGER_EXT
, 32, GL_TRUE
},
73 { GL_RGBA32UI_EXT
, GL_BGRA_INTEGER_EXT
, 32, GL_FALSE
},
75 { GL_RGB8I_EXT
, GL_RGB_INTEGER_EXT
, 8, GL_TRUE
},
76 { GL_RGB8UI_EXT
, GL_RGB_INTEGER_EXT
, 8, GL_FALSE
},
77 { GL_RGB16I_EXT
, GL_RGB_INTEGER_EXT
, 16, GL_TRUE
},
78 { GL_RGB16UI_EXT
, GL_RGB_INTEGER_EXT
, 16, GL_FALSE
},
79 { GL_RGB32I_EXT
, GL_RGB_INTEGER_EXT
, 32, GL_TRUE
},
80 { GL_RGB32UI_EXT
, GL_RGB_INTEGER_EXT
, 32, GL_FALSE
},
82 { GL_ALPHA8I_EXT
, GL_ALPHA_INTEGER_EXT
, 8, GL_TRUE
},
83 { GL_ALPHA8UI_EXT
, GL_ALPHA_INTEGER_EXT
, 8, GL_FALSE
},
84 { GL_ALPHA16I_EXT
, GL_ALPHA_INTEGER_EXT
, 16, GL_TRUE
},
85 { GL_ALPHA16UI_EXT
, GL_ALPHA_INTEGER_EXT
, 16, GL_FALSE
},
86 { GL_ALPHA32I_EXT
, GL_ALPHA_INTEGER_EXT
, 32, GL_TRUE
},
87 { GL_ALPHA32UI_EXT
, GL_ALPHA_INTEGER_EXT
, 32, GL_FALSE
},
89 { GL_LUMINANCE8I_EXT
, GL_LUMINANCE_INTEGER_EXT
, 8, GL_TRUE
},
90 { GL_LUMINANCE8UI_EXT
, GL_LUMINANCE_INTEGER_EXT
, 8, GL_FALSE
},
91 { GL_LUMINANCE16I_EXT
, GL_LUMINANCE_INTEGER_EXT
, 16, GL_TRUE
},
92 { GL_LUMINANCE16UI_EXT
, GL_LUMINANCE_INTEGER_EXT
, 16, GL_FALSE
},
93 { GL_LUMINANCE32I_EXT
, GL_LUMINANCE_INTEGER_EXT
, 32, GL_TRUE
},
94 { GL_LUMINANCE32UI_EXT
, GL_LUMINANCE_INTEGER_EXT
, 32, GL_FALSE
},
96 { GL_LUMINANCE_ALPHA8I_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 8, GL_TRUE
},
97 { GL_LUMINANCE_ALPHA8UI_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 8, GL_FALSE
},
98 { GL_LUMINANCE_ALPHA16I_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 16, GL_TRUE
},
99 { GL_LUMINANCE_ALPHA16UI_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 16, GL_FALSE
},
100 { GL_LUMINANCE_ALPHA32I_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 32, GL_TRUE
},
101 { GL_LUMINANCE_ALPHA32UI_EXT
, GL_LUMINANCE_ALPHA_INTEGER_EXT
, 32, GL_FALSE
},
103 { GL_INTENSITY8I_EXT
, GL_RED_INTEGER_EXT
, 8, GL_TRUE
},
104 { GL_INTENSITY8UI_EXT
, GL_RED_INTEGER_EXT
, 8, GL_FALSE
},
105 { GL_INTENSITY16I_EXT
, GL_RED_INTEGER_EXT
, 16, GL_TRUE
},
106 { GL_INTENSITY16UI_EXT
, GL_RED_INTEGER_EXT
, 16, GL_FALSE
},
107 { GL_INTENSITY32I_EXT
, GL_RED_INTEGER_EXT
, 32, GL_TRUE
},
108 { GL_INTENSITY32UI_EXT
, GL_RED_INTEGER_EXT
, 32, GL_FALSE
},
112 static const struct format_info rg_formats
[] = {
113 { GL_RG8I
, GL_RG_INTEGER
, 8, GL_TRUE
},
114 { GL_RG8UI
, GL_RG_INTEGER
, 8, GL_FALSE
},
115 { GL_RG16I
, GL_RG_INTEGER
, 16, GL_TRUE
},
116 { GL_RG16UI
, GL_RG_INTEGER
, 16, GL_FALSE
},
117 { GL_RG32I
, GL_RG_INTEGER
, 32, GL_TRUE
},
118 { GL_RG32UI
, GL_RG_INTEGER
, 32, GL_FALSE
},
119 { GL_R8I
, GL_RED_INTEGER
, 8, GL_TRUE
},
120 { GL_R8UI
, GL_RED_INTEGER
, 8, GL_FALSE
},
121 { GL_R16I
, GL_RED_INTEGER
, 16, GL_TRUE
},
122 { GL_R16UI
, GL_RED_INTEGER
, 16, GL_FALSE
},
123 { GL_R32I
, GL_RED_INTEGER
, 32, GL_TRUE
},
124 { GL_R32UI
, GL_RED_INTEGER
, 32, GL_FALSE
},
127 /* the rgb10 formats overload the Signed TRUE/FALSE member to test
128 * the _REV and non-REV component ordering.
130 static const struct format_info rgb10_formats
[] = {
131 { GL_RGB10_A2UI
, GL_RGBA_INTEGER_EXT
, 10, GL_FALSE
},
132 { GL_RGB10_A2UI
, GL_BGRA_INTEGER_EXT
, 10, GL_FALSE
},
133 { GL_RGB10_A2UI
, GL_RGBA_INTEGER_EXT
, 10, GL_TRUE
},
134 { GL_RGB10_A2UI
, GL_BGRA_INTEGER_EXT
, 10, GL_TRUE
},
137 /* The programs will be indexed by whether the texture is signed or not. */
138 static const char *FragShaderText
[4] = {
140 "uniform vec4 bias; \n"
141 "uniform usampler2D tex; \n"
144 " vec4 t = vec4(texture(tex, gl_TexCoord[0].xy)); \n"
145 " gl_FragColor = t + bias; \n"
149 "uniform vec4 bias; \n"
150 "uniform isampler2D tex; \n"
153 " vec4 t = vec4(texture(tex, gl_TexCoord[0].xy)); \n"
154 " gl_FragColor = t + bias; \n"
157 "#extension GL_EXT_gpu_shader4 : require\n"
158 "uniform vec4 bias; \n"
159 "uniform usampler2D tex; \n"
162 " vec4 t = vec4(texture2D(tex, gl_TexCoord[0].xy)); \n"
163 " gl_FragColor = t + bias; \n"
166 "#extension GL_EXT_gpu_shader4 : require\n"
167 "uniform vec4 bias; \n"
168 "uniform isampler2D tex; \n"
171 " vec4 t = vec4(texture2D(tex, gl_TexCoord[0].xy)); \n"
172 " gl_FragColor = t + bias; \n"
176 static GLuint Program
[4];
179 get_max_val(const struct format_info
*info
)
183 switch (info
->BitsPerChannel
) {
201 max
= 10*1000; /* don't use 0x8fffffff to avoid overflow issues */
215 num_components(GLenum format
)
219 case GL_RGBA_INTEGER_EXT
:
220 case GL_BGRA_INTEGER_EXT
:
222 case GL_RGB_INTEGER_EXT
:
226 case GL_ALPHA_INTEGER_EXT
:
228 case GL_LUMINANCE_INTEGER_EXT
:
230 case GL_LUMINANCE_ALPHA_INTEGER_EXT
:
232 case GL_RED_INTEGER_EXT
:
242 fill_array(int comps
, int texels
, void *buf
, int bpp
, const int val
[4])
249 GLubyte
*b
= (GLubyte
*) buf
;
250 for (i
= 0; i
< texels
; i
++) {
251 for (j
= 0; j
< comps
; j
++) {
252 b
[i
* comps
+ j
] = val
[j
];
259 GLushort
*b
= (GLushort
*) buf
;
260 for (i
= 0; i
< texels
; i
++) {
261 for (j
= 0; j
< comps
; j
++) {
262 b
[i
* comps
+ j
] = val
[j
];
269 GLuint
*b
= (GLuint
*) buf
;
270 for (i
= 0; i
< texels
; i
++) {
271 for (j
= 0; j
< comps
; j
++) {
272 b
[i
* comps
+ j
] = val
[j
];
283 fill_array_rgb10(int comps
, int texels
, void *buf
, int type
,
287 GLuint
*b
= (GLuint
*)buf
;
289 if (type
== GL_UNSIGNED_INT_2_10_10_10_REV
) {
290 for (i
= 0; i
< texels
; i
++) {
291 b
[i
] = (val
[0] & 0x3ff) << 0 |
292 (val
[1] & 0x3ff) << 10 |
293 (val
[2] & 0x3ff) << 20 |
294 (val
[3] & 0x3) << 30;
296 } else if (type
== GL_UNSIGNED_INT_10_10_10_2
) {
297 for (i
= 0; i
< texels
; i
++) {
298 b
[i
] = (val
[3] & 0x3) << 0 |
299 (val
[2] & 0x3ff) << 2 |
300 (val
[1] & 0x3ff) << 12 |
301 (val
[0] & 0x3ff) << 22;
307 get_datatype(const struct format_info
*info
)
309 switch (info
->BitsPerChannel
) {
311 return info
->Signed
? GL_BYTE
: GL_UNSIGNED_BYTE
;
313 return info
->Signed
? GL_UNSIGNED_INT_10_10_10_2
: GL_UNSIGNED_INT_2_10_10_10_REV
;
315 return info
->Signed
? GL_SHORT
: GL_UNSIGNED_SHORT
;
317 return info
->Signed
? GL_INT
: GL_UNSIGNED_INT
;
326 check_error(const char *file
, int line
)
328 GLenum err
= glGetError();
330 fprintf(stderr
, "%s: error 0x%x at %s:%d\n",
331 TestName
, err
, file
, line
);
338 /** \return GL_TRUE for pass, GL_FALSE for fail */
340 test_format(const struct format_info
*info
, int shader_base
)
342 const int max
= get_max_val(info
);
343 const int comps
= num_components(info
->BaseFormat
);
344 const int texels
= TexWidth
* TexHeight
;
345 const GLenum type
= get_datatype(info
);
346 const int w
= piglit_width
/ 10;
347 const int h
= piglit_height
/ 10;
348 const float error
= 2.0 / 255.0; /* XXX fix */
352 GLfloat result
[4], bias
[4];
358 if (info
->IntFormat
== GL_RGB10_A2UI
) {
359 if (info
->BaseFormat
== GL_BGRA_INTEGER
) {
361 suffix
= " (rev bgra)";
370 } else if (info
->BaseFormat
== GL_BGRA_INTEGER
)
374 asprintf(&name
, "%s%s:\n", piglit_get_gl_enum_name(info
->IntFormat
), suffix
);
376 /* pick random texture color */
377 value
[0] = rand() % max
;
378 value
[1] = rand() % max
;
379 value
[2] = rand() % max
;
380 value
[3] = rand() % max
;
382 /* alloc, fill texture image */
383 if (info
->BitsPerChannel
== 10) {
384 value
[3] = rand() % 3;
385 buf
= malloc(texels
* 4);
386 fill_array_rgb10(comps
, texels
, buf
, type
, value
);
388 buf
= malloc(comps
* texels
* info
->BitsPerChannel
/ 8);
389 fill_array(comps
, texels
, buf
, info
->BitsPerChannel
, value
);
392 glTexImage2D(GL_TEXTURE_2D
, 0, info
->IntFormat
, TexWidth
, TexHeight
, 0,
393 info
->BaseFormat
, type
, buf
);
395 if (check_error(__FILE__
, __LINE__
)) {
401 glGetTexLevelParameteriv(GL_TEXTURE_2D
, 0, GL_TEXTURE_INTERNAL_FORMAT
,
404 assert(f == info->IntFormat);
407 /* setup expected polygon color */
413 /* Need to swizzle things depending on texture format.
415 * Also, for texture formats with no storage for a particular
416 * channel, instead of reading the randomly-chosen value
417 * above, we need to expect to read a 0, (for Green or Blue
418 * channels), or a 1 (for Alpha).
420 * Note: The alpha value read is an integer 1, not a
421 * maximum-valued integer representing 1.0.
423 switch (info
->BaseFormat
) {
424 case GL_RGBA_INTEGER_EXT
:
427 case GL_BGRA_INTEGER_EXT
:
430 expected
[2] = expected
[0];
436 case GL_RGB_INTEGER_EXT
:
443 case GL_ALPHA_INTEGER_EXT
:
444 expected
[0] = expected
[1] = expected
[2] = 0.0;
448 case GL_LUMINANCE_INTEGER_EXT
:
449 expected
[0] = expected
[1] = expected
[2] = 0.25;
451 value
[1] = value
[2] = value
[0];
454 case GL_LUMINANCE_ALPHA_INTEGER_EXT
:
455 expected
[0] = expected
[1] = expected
[2] = 0.25;
457 value
[1] = value
[2] = value
[0];
459 case GL_RED_INTEGER_EXT
:
460 if (info
->IntFormat
== GL_INTENSITY8I_EXT
||
461 info
->IntFormat
== GL_INTENSITY8UI_EXT
||
462 info
->IntFormat
== GL_INTENSITY16I_EXT
||
463 info
->IntFormat
== GL_INTENSITY16UI_EXT
||
464 info
->IntFormat
== GL_INTENSITY32I_EXT
||
465 info
->IntFormat
== GL_INTENSITY32UI_EXT
) {
466 expected
[0] = expected
[1] = expected
[2] = expected
[3] = 0.25;
467 value
[1] = value
[2] = value
[3] = value
[0];
469 value
[1] = value
[2] = 0;
477 glUseProgram(Program
[shader_base
+ info
->Signed
]);
479 /* compute, set test bias */
480 bias
[0] = expected
[0] - value
[0];
481 bias
[1] = expected
[1] - value
[1];
482 bias
[2] = expected
[2] - value
[2];
483 bias
[3] = expected
[3] - value
[3];
484 glUniform4fv(BiasUniform
[shader_base
+ info
->Signed
], 1, bias
);
487 glClearColor(0, 1, 1, 0);
488 glClear(GL_COLOR_BUFFER_BIT
);
490 glTexCoord2f(0, 0); glVertex2f(0, 0);
491 glTexCoord2f(1, 0); glVertex2f(w
, 0);
492 glTexCoord2f(1, 1); glVertex2f(w
, h
);
493 glTexCoord2f(0, 1); glVertex2f(0, h
);
496 if (check_error(__FILE__
, __LINE__
)) {
503 glReadPixels(w
/2, h
/2, 1, 1, GL_RGBA
, GL_FLOAT
, result
);
505 if (check_error(__FILE__
, __LINE__
)) {
511 if (fabsf(result
[0] - expected
[0]) > error
||
512 fabsf(result
[1] - expected
[1]) > error
||
513 fabsf(result
[2] - expected
[2]) > error
||
514 fabsf(result
[3] - expected
[3]) > error
) {
515 fprintf(stderr
, "%s: failure with format %s:\n",
517 fprintf(stderr
, " texture color = %d, %d, %d, %d\n",
518 value
[0], value
[1], value
[2], value
[3]);
519 fprintf(stderr
, " expected color = %g, %g, %g, %g\n",
520 expected
[0], expected
[1], expected
[2], expected
[3]);
521 fprintf(stderr
, " result color = %g, %g, %g, %g\n",
522 result
[0], result
[1], result
[2], result
[3]);
528 piglit_present_results();
538 test_general_formats(int shader_base
)
542 for (f
= 0; f
< ARRAY_SIZE(Formats
); f
++) {
543 for (i
= 0; i
< 5; i
++) {
544 if (!test_format(&Formats
[f
], shader_base
))
549 if (piglit_is_extension_supported("GL_ARB_texture_rg")) {
550 for (f
= 0; f
< ARRAY_SIZE(rg_formats
); f
++) {
551 for (i
= 0; i
< 5; i
++) {
552 if (!test_format(&rg_formats
[f
], shader_base
))
558 if (piglit_is_extension_supported("GL_ARB_texture_rgb10_a2ui")) {
559 for (f
= 0; f
< ARRAY_SIZE(rgb10_formats
); f
++) {
560 for (i
= 0; i
< 5; i
++) {
561 if (!test_format(&rgb10_formats
[f
], shader_base
))
571 test_specific_formats(void)
573 /* These format combinations should all work */
575 GLenum intFormat
, srcFormat
, srcType
;
577 { GL_RGBA8UI_EXT
, GL_RGBA_INTEGER
, GL_UNSIGNED_BYTE
},
578 { GL_RGBA8UI_EXT
, GL_RGBA_INTEGER
, GL_SHORT
},
579 { GL_RGBA8UI_EXT
, GL_RGBA_INTEGER
, GL_UNSIGNED_INT_8_8_8_8
},
580 { GL_RGBA8UI_EXT
, GL_BGRA_INTEGER
, GL_UNSIGNED_INT_8_8_8_8
},
581 { GL_LUMINANCE8I_EXT
, GL_RGBA_INTEGER
, GL_UNSIGNED_INT_8_8_8_8
},
582 { GL_RGB16I_EXT
, GL_RGB_INTEGER
, GL_UNSIGNED_SHORT_5_6_5
},
583 { GL_RGB32I_EXT
, GL_RGB_INTEGER
, GL_UNSIGNED_SHORT_5_6_5
}
587 GLboolean pass
= GL_TRUE
;
589 while (glGetError() != GL_NO_ERROR
)
592 /* All of the packed formats require GL_ARB_texture_rgb10_a2ui.
594 if (!piglit_is_extension_supported("GL_ARB_texture_rgb10_a2ui")) {
598 for (i
= 0; i
< ARRAY_SIZE(formats
); i
++) {
599 glTexImage2D(GL_TEXTURE_2D
, 0, formats
[i
].intFormat
,
601 formats
[i
].srcFormat
, formats
[i
].srcType
, NULL
);
603 if (err
!= GL_NO_ERROR
) {
604 fprintf(stderr
, "%s failure: glTexImage2D(0x%x, 0x%x, 0x%x) generated"
605 " error 0x%x (case %d)\n",
606 TestName
, formats
[i
].intFormat
,
607 formats
[i
].srcFormat
, formats
[i
].srcType
, err
, i
);
619 if (!test_general_formats(0))
623 if (has_gpu_shader4
) {
624 if (!test_general_formats(2))
628 if (!test_specific_formats())
636 piglit_init(int argc
, char **argv
)
641 has_gpu_shader4
= piglit_is_extension_supported("GL_EXT_gpu_shader4");
642 piglit_get_glsl_version(NULL
, &major
, &minor
);
643 has_glsl_130
= (major
* 100 + minor
) >= 130;
644 /* Check if EXT_gpu_shader4 is supported */
645 if (!has_gpu_shader4
) {
646 /* If EXT_gpu_shader4 is not supported GL version must be 3.0 */
647 piglit_require_gl_version(30);
648 piglit_require_GLSL_version(130);
651 for (i
= 0; i
< 4; i
++) {
652 if ((i
== 0 || i
== 1) && !has_glsl_130
)
654 if ((i
== 2 || i
== 3) && !has_gpu_shader4
)
656 Program
[i
] = piglit_build_simple_program(NULL
,
658 BiasUniform
[i
] = glGetUniformLocation(Program
[i
], "bias");
659 TexUniform
[i
] = glGetUniformLocation(Program
[i
], "tex");
662 (void) check_error(__FILE__
, __LINE__
);
664 glGenTextures(1, &Texture
);
665 glBindTexture(GL_TEXTURE_2D
, Texture
);
666 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
667 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
669 (void) check_error(__FILE__
, __LINE__
);
671 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);