2 * Copyright (c) The Piglit project 2007
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, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 #include "piglit-util-gl.h"
27 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
30 * An array of pointers to extension strings.
32 * Each extension is pointed to by a separate entry in the array.
34 * The end of the array is indicated by a NULL pointer.
36 static const char **gl_extensions
= NULL
;
38 static const float color_wheel
[4][4] = {
39 {1, 0, 0, 1}, /* red */
40 {0, 1, 0, 1}, /* green */
41 {0, 0, 1, 1}, /* blue */
42 {1, 1, 1, 1}, /* white */
45 bool piglit_is_core_profile
;
47 bool piglit_is_gles(void)
49 const char *version_string
= (const char *) glGetString(GL_VERSION
);
50 return strncmp("OpenGL ES", version_string
, 9) == 0;
53 bool piglit_is_gles3(void)
55 const char *version_string
= (const char *) glGetString(GL_VERSION
);
56 return strncmp("OpenGL ES 3", version_string
, 11) == 0;
59 int piglit_get_gl_version(void)
61 const char *version_string
= (const char *) glGetString(GL_VERSION
);
66 /* skip to version number */
67 while (!isdigit(*version_string
) && *version_string
!= '\0')
70 /* Interpret version number */
71 scanf_count
= sscanf(version_string
, "%i.%i", &major
, &minor
);
72 if (scanf_count
!= 2) {
73 printf("Unable to interpret GL_VERSION string: %s\n",
75 piglit_report_result(PIGLIT_FAIL
);
77 return 10*major
+minor
;
80 static const char** gl_extension_array_from_getstring()
82 const char *gl_extensions_string
;
83 gl_extensions_string
= (const char *) glGetString(GL_EXTENSIONS
);
84 return piglit_split_string_to_array(gl_extensions_string
, " ");
87 static const char** gl_extension_array_from_getstringi()
90 int loop
, num_extensions
;
92 glGetIntegerv(GL_NUM_EXTENSIONS
, &num_extensions
);
93 strings
= malloc (sizeof(char*) * (num_extensions
+ 1));
94 assert (strings
!= NULL
);
96 for (loop
= 0; loop
< num_extensions
; loop
++) {
97 strings
[loop
] = (const char*) glGetStringi(GL_EXTENSIONS
, loop
);
100 strings
[loop
] = NULL
;
102 return (const char**) strings
;
105 static void initialize_piglit_extension_support(void)
107 if (gl_extensions
!= NULL
) {
111 if (piglit_get_gl_version() < 30) {
112 gl_extensions
= gl_extension_array_from_getstring();
114 gl_extensions
= gl_extension_array_from_getstringi();
118 void piglit_gl_invalidate_extensions()
120 if (gl_extensions
!= NULL
) {
122 gl_extensions
= NULL
;
126 bool piglit_is_extension_supported(const char *name
)
128 initialize_piglit_extension_support();
129 return piglit_is_extension_in_array(gl_extensions
, name
);
132 void piglit_require_gl_version(int required_version_times_10
)
134 if (piglit_is_gles() ||
135 piglit_get_gl_version() < required_version_times_10
) {
136 printf("Test requires GL version %g\n",
137 required_version_times_10
/ 10.0);
138 piglit_report_result(PIGLIT_SKIP
);
142 void piglit_require_extension(const char *name
)
144 if (!piglit_is_extension_supported(name
)) {
145 printf("Test requires %s\n", name
);
146 piglit_report_result(PIGLIT_SKIP
);
150 void piglit_require_not_extension(const char *name
)
152 if (piglit_is_extension_supported(name
)) {
153 piglit_report_result(PIGLIT_SKIP
);
157 void piglit_require_draw_buffers(int count
)
160 glGetIntegerv(GL_MAX_DRAW_BUFFERS
, &max_targets
);
161 if (max_targets
< 2) {
162 printf("Test requires GL_MAX_DRAW_BUFFERS >= %d\n", count
);
163 piglit_report_result(PIGLIT_SKIP
);
167 const char* piglit_get_gl_error_name(GLenum error
)
169 #define CASE(x) case x: return #x;
171 CASE(GL_INVALID_ENUM
)
172 CASE(GL_INVALID_OPERATION
)
173 CASE(GL_INVALID_VALUE
)
175 CASE(GL_OUT_OF_MEMORY
)
176 CASE(GL_STACK_OVERFLOW
)
177 CASE(GL_STACK_UNDERFLOW
)
178 CASE(GL_INVALID_FRAMEBUFFER_OPERATION
)
180 return "(unrecognized error)";
186 piglit_check_gl_error_(GLenum expected_error
, const char *file
, unsigned line
)
190 actual_error
= glGetError();
191 if (actual_error
== expected_error
) {
196 * If the lookup of the error's name is successful, then print
197 * Unexpected GL error: NAME 0xHEX
199 * Unexpected GL error: 0xHEX
201 printf("Unexpected GL error: %s 0x%x\n",
202 piglit_get_gl_error_name(actual_error
), actual_error
);
203 printf("(Error at %s:%u)\n", file
, line
);
205 /* Print the expected error, but only if an error was really expected. */
206 if (expected_error
!= GL_NO_ERROR
) {
207 printf("Expected GL error: %s 0x%x\n",
208 piglit_get_gl_error_name(expected_error
), expected_error
);
214 void piglit_reset_gl_error(void)
216 while (glGetError() != GL_NO_ERROR
) {
221 /* These texture coordinates should have 1 or -1 in the major axis selecting
222 * the face, and a nearly-1-or-negative-1 value in the other two coordinates
223 * which will be used to produce the s,t values used to sample that face's
226 GLfloat cube_face_texcoords
[6][4][3] = {
227 { /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
233 { /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
237 {-1.0, -0.99, -0.99},
239 { /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
245 { /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
247 {-0.99, -1.0, -0.99},
248 { 0.99, -1.0, -0.99},
251 { /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
257 { /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
260 {-0.99, -0.99, -1.0},
261 { 0.99, -0.99, -1.0},
265 const char *cube_face_names
[6] = {
274 const GLenum cube_face_targets
[6] = {
275 GL_TEXTURE_CUBE_MAP_POSITIVE_X
,
276 GL_TEXTURE_CUBE_MAP_NEGATIVE_X
,
277 GL_TEXTURE_CUBE_MAP_POSITIVE_Y
,
278 GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
,
279 GL_TEXTURE_CUBE_MAP_POSITIVE_Z
,
280 GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
,
283 float piglit_tolerance
[4] = { 0.01, 0.01, 0.01, 0.01 };
286 piglit_set_tolerance_for_bits(int rbits
, int gbits
, int bbits
, int abits
)
288 int bits
[4] = {rbits
, gbits
, bbits
, abits
};
291 for (i
= 0; i
< 4; i
++) {
293 /* With 0 bits of storage, we still want to
294 * validate expected results, (such as
295 * alpha==1.0 when targeting storage with no
297 piglit_tolerance
[i
] = 3.0 / (1 << 8);
298 } else if (bits
[i
] == 1) {
299 /* Don't try to validate channels when there's only 1
302 piglit_tolerance
[i
] = 1.0;
304 piglit_tolerance
[i
] = 3.0 / (1 << bits
[i
]);
309 typedef union { GLfloat f
; GLint i
; } fi_type
;
312 * Convert a 4-byte float to a 2-byte half float.
313 * Based on code from:
314 * http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/008786.html
316 * Taken over from Mesa.
319 piglit_half_from_float(float val
)
321 const fi_type fi
= {val
};
322 const int flt_m
= fi
.i
& 0x7fffff;
323 const int flt_e
= (fi
.i
>> 23) & 0xff;
324 const int flt_s
= (fi
.i
>> 31) & 0x1;
326 unsigned short result
;
331 /* handle special cases */
332 if ((flt_e
== 0) && (flt_m
== 0)) {
334 /* m = 0; - already set */
337 else if ((flt_e
== 0) && (flt_m
!= 0)) {
338 /* denorm -- denorm float maps to 0 half */
339 /* m = 0; - already set */
342 else if ((flt_e
== 0xff) && (flt_m
== 0)) {
344 /* m = 0; - already set */
347 else if ((flt_e
== 0xff) && (flt_m
!= 0)) {
354 const int new_exp
= flt_e
- 127;
357 /* m = 0; - already set */
360 else if (new_exp
< -14) {
361 /* this maps to a denorm */
363 unsigned int exp_val
= (unsigned int) (-14 - new_exp
);
368 /* m = 0; - already set */
370 case 1: m
= 512 + (flt_m
>> 14); break;
371 case 2: m
= 256 + (flt_m
>> 15); break;
372 case 3: m
= 128 + (flt_m
>> 16); break;
373 case 4: m
= 64 + (flt_m
>> 17); break;
374 case 5: m
= 32 + (flt_m
>> 18); break;
375 case 6: m
= 16 + (flt_m
>> 19); break;
376 case 7: m
= 8 + (flt_m
>> 20); break;
377 case 8: m
= 4 + (flt_m
>> 21); break;
378 case 9: m
= 2 + (flt_m
>> 22); break;
379 case 10: m
= 1; break;
382 else if (new_exp
> 15) {
383 /* map this value to infinity */
384 /* m = 0; - already set */
394 result
= (s
<< 15) | (e
<< 10) | m
;
400 * Return block size info for a specific texture compression format.
401 * \param bw returns the block width, in pixels
402 * \param bh returns the block height, in pixels
403 * \param return number of bytes per block
404 * \return true if format is a known compressed format, false otherwise
407 piglit_get_compressed_block_size(GLenum format
,
408 unsigned *bw
, unsigned *bh
, unsigned *bytes
)
411 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
412 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
416 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
417 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
418 case GL_COMPRESSED_RED
:
419 case GL_COMPRESSED_RED_RGTC1
:
420 case GL_COMPRESSED_SIGNED_RED_RGTC1
:
421 case GL_COMPRESSED_LUMINANCE_LATC1_EXT
:
422 case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT
:
423 case GL_COMPRESSED_RGB8_ETC2
:
424 case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
:
425 case GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2
:
426 case GL_COMPRESSED_R11_EAC
:
427 case GL_COMPRESSED_SIGNED_R11_EAC
:
428 case GL_COMPRESSED_SRGB8_ETC2
:
432 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
433 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
434 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
435 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
436 case GL_COMPRESSED_RG
:
437 case GL_COMPRESSED_RG_RGTC2
:
438 case GL_COMPRESSED_SIGNED_RG_RGTC2
:
439 case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT
:
440 case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT
:
441 case GL_COMPRESSED_RGBA_BPTC_UNORM
:
442 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM
:
443 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT
:
444 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
:
445 case GL_COMPRESSED_RGBA8_ETC2_EAC
:
446 case GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC
:
447 case GL_COMPRESSED_RG11_EAC
:
448 case GL_COMPRESSED_SIGNED_RG11_EAC
:
452 case GL_COMPRESSED_RGB_FXT1_3DFX
:
453 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
459 /* return something rather than uninitialized values */
460 *bw
= *bh
= *bytes
= 1;
467 * Compute size (in bytes) needed to store an image in the given compressed
471 piglit_compressed_image_size(GLenum format
, unsigned width
, unsigned height
)
473 unsigned bw
, bh
, bytes
;
474 bool b
= piglit_get_compressed_block_size(format
, &bw
, &bh
, &bytes
);
478 return ((width
+ bw
- 1) / bw
) * ((height
+ bh
- 1) / bh
) * bytes
;
483 * Return offset (in bytes) to the given texel in a compressed image.
484 * Note the x and y must be multiples of the compressed block size.
487 piglit_compressed_pixel_offset(GLenum format
, unsigned width
,
488 unsigned x
, unsigned y
)
490 unsigned bw
, bh
, bytes
, offset
;
491 bool b
= piglit_get_compressed_block_size(format
, &bw
, &bh
, &bytes
);
498 assert(width
% bw
== 0);
500 offset
= (width
/ bw
* bytes
* y
/ bh
) + (x
/ bw
* bytes
);
506 piglit_escape_exit_key(unsigned char key
, int x
, int y
)
515 if (!piglit_is_gles())
516 piglit_post_redisplay();
520 * Convenience function to configure an abitrary orthogonal projection matrix
523 piglit_gen_ortho_projection(double left
, double right
, double bottom
,
524 double top
, double near_val
, double far_val
,
527 glMatrixMode(GL_PROJECTION
);
532 if (piglit_is_gles())
533 glOrthof(left
, right
, bottom
, top
, near_val
, far_val
);
535 glOrtho(left
, right
, bottom
, top
, near_val
, far_val
);
537 glMatrixMode(GL_MODELVIEW
);
544 * Convenience function to configure projection matrix for window coordinates
547 piglit_ortho_projection(int w
, int h
, GLboolean push
)
549 /* Set up projection matrix so we can just draw using window
552 piglit_gen_ortho_projection(0, w
, 0, h
, -1, 1, push
);
556 * Convenience function to configure frustum projection.
559 piglit_frustum_projection(GLboolean push
, double l
, double r
, double b
,
560 double t
, double n
, double f
)
562 glMatrixMode(GL_PROJECTION
);
567 if (piglit_is_gles())
568 glFrustumf(l
, r
, b
, t
, n
, f
);
570 glFrustum(l
, r
, b
, t
, n
, f
);
572 glMatrixMode(GL_MODELVIEW
);
579 * Convenience function to configure a shader uniform variable as an
580 * arbitrary orthogonal projection matrix.
583 piglit_gen_ortho_uniform(GLint location
, double l
, double r
, double b
,
584 double t
, double n
, double f
)
586 const GLfloat values
[4][4] = {
587 { 2/(r
-l
), 0, 0, 0 },
588 { 0, 2/(t
-b
), 0, 0 },
589 { 0, 0, -2/(f
-n
), 0 },
590 { -(r
+l
)/(r
-l
), -(t
+b
)/(t
-b
), -(f
+n
)/(f
-n
), 1 }
592 glUniformMatrix4fv(location
, 1, GL_FALSE
, (const GLfloat
*)values
);
597 * Convenience function to configure a shader uniform variable as a
598 * projection matrix for window coordinates.
601 piglit_ortho_uniform(GLint location
, int w
, int h
)
603 /* Set up projection matrix so we can just draw using window
606 piglit_gen_ortho_uniform(location
, 0, w
, 0, h
, -1, 1);
611 required_gl_version_from_glsl_version(unsigned glsl_version
)
613 switch (glsl_version
) {
616 /* GLSL 1.30 is naturally matched with GL3,
617 * but is usefully supportable on GL2.1 if
618 * EXT_gpu_shader4 is also supported.
636 * Call glDrawArrays. verts is expected to be
640 * if not NULL; tex is expected to be
647 piglit_draw_rect_from_arrays(const void *verts
, const void *tex
,
648 bool use_patches
, unsigned instance_count
)
650 bool use_fixed_function_attributes
;
652 bool gles
= piglit_is_gles();
653 int version
= piglit_get_gl_version();
656 use_fixed_function_attributes
= (version
< 20);
657 } else if (version
>= 20 ||
658 piglit_is_extension_supported("GL_ARB_shader_objects")) {
661 glGetIntegerv(GL_CURRENT_PROGRAM
, (GLint
*) &prog
);
664 piglit_is_extension_supported("GL_ARB_separate_shader_objects")) {
667 glGetIntegerv(GL_PROGRAM_PIPELINE_BINDING
,
670 glGetProgramPipelineiv(pipeline
, GL_VERTEX_SHADER
,
674 /* If there is a current program and that program has an
675 * active attribute named piglit_vertex, don't use the fixed
676 * function inputs. Never use fixed function inputs on core
679 use_fixed_function_attributes
= ((prog
== 0)
680 || glGetAttribLocation(prog
, "piglit_vertex") == -1)
681 && !piglit_is_core_profile
;
683 use_fixed_function_attributes
= true;
686 if (use_fixed_function_attributes
) {
688 glVertexPointer(4, GL_FLOAT
, 0, verts
);
689 glEnableClientState(GL_VERTEX_ARRAY
);
693 glTexCoordPointer(2, GL_FLOAT
, 0, tex
);
694 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
698 GLint old_patch_vertices
;
700 glGetIntegerv(GL_PATCH_VERTICES
, &old_patch_vertices
);
701 glPatchParameteri(GL_PATCH_VERTICES
, 4);
702 if (instance_count
> 1)
703 glDrawArraysInstanced(GL_PATCHES
, 0, 4, instance_count
);
705 glDrawArrays(GL_PATCHES
, 0, 4);
706 glPatchParameteri(GL_PATCH_VERTICES
, old_patch_vertices
);
708 if (instance_count
> 1)
709 glDrawArraysInstanced(GL_TRIANGLE_STRIP
, 0, 4, instance_count
);
711 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
715 glDisableClientState(GL_VERTEX_ARRAY
);
717 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
724 /* Vertex array objects were added in both OpenGL 3.0 and
725 * OpenGL ES 3.0. The use of VAOs is required in desktop
726 * OpenGL 3.1 (without GL_ARB_compatibility) and all desktop
727 * OpenGL core profiles. If the functionality is supported,
730 if (piglit_get_gl_version() >= 30
731 || piglit_is_extension_supported("GL_OES_vertex_array_object")
732 || piglit_is_extension_supported("GL_ARB_vertex_array_object")) {
733 glGetIntegerv(GL_VERTEX_ARRAY_BINDING
,
735 glGenVertexArrays(1, &vao
);
736 glBindVertexArray(vao
);
739 /* Assume that VBOs are supported in any implementation that
742 glGetIntegerv(GL_ARRAY_BUFFER_BINDING
,
744 glGenBuffers(1, &buf
);
745 glBindBuffer(GL_ARRAY_BUFFER
, buf
);
746 glBufferData(GL_ARRAY_BUFFER
,
747 (sizeof(GLfloat
) * 4 * 4)
748 + (sizeof(GLfloat
) * 4 * 2),
753 glBufferSubData(GL_ARRAY_BUFFER
,
755 sizeof(GLfloat
) * 4 * 4,
757 glVertexAttribPointer(PIGLIT_ATTRIB_POS
, 4, GL_FLOAT
,
760 glEnableVertexAttribArray(PIGLIT_ATTRIB_POS
);
764 glBufferSubData(GL_ARRAY_BUFFER
,
765 sizeof(GLfloat
) * 4 * 4,
766 sizeof(GLfloat
) * 4 * 2,
768 glVertexAttribPointer(PIGLIT_ATTRIB_TEX
, 2, GL_FLOAT
,
770 BUFFER_OFFSET(sizeof(GLfloat
) * 4 * 4));
771 glEnableVertexAttribArray(PIGLIT_ATTRIB_TEX
);
775 GLint old_patch_vertices
;
777 glGetIntegerv(GL_PATCH_VERTICES
, &old_patch_vertices
);
778 glPatchParameteri(GL_PATCH_VERTICES
, 4);
779 if (instance_count
> 1)
780 glDrawArraysInstanced(GL_PATCHES
, 0, 4, instance_count
);
782 glDrawArrays(GL_PATCHES
, 0, 4);
783 glPatchParameteri(GL_PATCH_VERTICES
, old_patch_vertices
);
786 if (instance_count
> 1)
787 glDrawArraysInstanced(GL_TRIANGLE_STRIP
, 0, 4, instance_count
);
789 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
793 glDisableVertexAttribArray(PIGLIT_ATTRIB_POS
);
795 glDisableVertexAttribArray(PIGLIT_ATTRIB_TEX
);
797 glBindBuffer(GL_ARRAY_BUFFER
, old_buf
);
798 glDeleteBuffers(1, &buf
);
801 glBindVertexArray(old_vao
);
802 glDeleteVertexArrays(1, &vao
);
808 * Convenience function to draw an axis-aligned rectangle.
811 piglit_draw_rect_custom(float x
, float y
, float w
, float h
, bool use_patches
,
812 unsigned instance_count
)
833 piglit_draw_rect_from_arrays(verts
, NULL
, use_patches
, instance_count
);
837 * Convenience function to draw an axis-aligned rectangle.
840 piglit_draw_rect(float x
, float y
, float w
, float h
)
842 piglit_draw_rect_custom(x
, y
, w
, h
, false, 1);
846 * Convenience function to draw an axis-aligned rectangle.
849 piglit_draw_rect_z(float z
, float x
, float y
, float w
, float h
)
870 piglit_draw_rect_from_arrays(verts
, NULL
, false, 1);
874 * Convenience function to draw an axis-aligned rectangle
875 * with texture coordinates.
878 piglit_draw_rect_tex(float x
, float y
, float w
, float h
,
879 float tx
, float ty
, float tw
, float th
)
909 piglit_draw_rect_from_arrays(verts
, tex
, false, 1);
913 piglit_num_components(GLenum format
)
917 case GL_DEPTH_COMPONENT
:
924 case GL_DEPTH_STENCIL
:
925 case GL_LUMINANCE_ALPHA
:
936 printf("Unknown num_components for %s\n",
937 piglit_get_gl_enum_name(format
));
938 piglit_report_result(PIGLIT_FAIL
);
943 /* This function only handles formats not supported by the OpenGL framebuffer
944 * size queries, which only support querying the R,G,B,A sizes.
946 * The function doesn't change the bits for formats it doesn't handle.
948 * The returned number of bits is an approximation but should be no less than
949 * the actual number of bits for the format chosen by OpenGL.
951 * The combination of the OpenGL framebuffer queries size and calling
952 * this function without checking the return value should give you reasonable
953 * values for any format.
956 piglit_get_luminance_intensity_bits(GLenum internalformat
, int *bits
)
958 switch (internalformat
) {
960 bits
[0] = bits
[1] = bits
[2] = 4;
965 case GL_LUMINANCE_SNORM
:
967 case GL_LUMINANCE8_SNORM
:
968 case GL_LUMINANCE8I_EXT
:
969 case GL_LUMINANCE8UI_EXT
:
970 bits
[0] = bits
[1] = bits
[2] = 8;
975 bits
[0] = bits
[1] = bits
[2] = 12;
980 case GL_LUMINANCE16_SNORM
:
981 case GL_LUMINANCE16I_EXT
:
982 case GL_LUMINANCE16UI_EXT
:
983 case GL_LUMINANCE16F_ARB
:
984 bits
[0] = bits
[1] = bits
[2] = 16;
988 case GL_LUMINANCE32I_EXT
:
989 case GL_LUMINANCE32UI_EXT
:
990 case GL_LUMINANCE32F_ARB
:
991 bits
[0] = bits
[1] = bits
[2] = 32;
995 case GL_LUMINANCE4_ALPHA4
:
997 bits
[0] = bits
[1] = bits
[2] = bits
[3] = 4;
1000 case GL_LUMINANCE_ALPHA
:
1001 case GL_LUMINANCE_ALPHA_SNORM
:
1002 case GL_LUMINANCE8_ALPHA8
:
1003 case GL_LUMINANCE8_ALPHA8_SNORM
:
1004 case GL_LUMINANCE_ALPHA8I_EXT
:
1005 case GL_LUMINANCE_ALPHA8UI_EXT
:
1007 case GL_INTENSITY_SNORM
:
1009 case GL_INTENSITY8_SNORM
:
1010 case GL_INTENSITY8I_EXT
:
1011 case GL_INTENSITY8UI_EXT
:
1012 bits
[0] = bits
[1] = bits
[2] = bits
[3] = 8;
1015 case GL_LUMINANCE12_ALPHA12
:
1016 case GL_INTENSITY12
:
1017 bits
[0] = bits
[1] = bits
[2] = bits
[3] = 12;
1020 case GL_LUMINANCE16_ALPHA16
:
1021 case GL_LUMINANCE16_ALPHA16_SNORM
:
1022 case GL_LUMINANCE_ALPHA16I_EXT
:
1023 case GL_LUMINANCE_ALPHA16UI_EXT
:
1024 case GL_LUMINANCE_ALPHA16F_ARB
:
1025 case GL_INTENSITY16
:
1026 case GL_INTENSITY16_SNORM
:
1027 case GL_INTENSITY16I_EXT
:
1028 case GL_INTENSITY16UI_EXT
:
1029 case GL_INTENSITY16F_ARB
:
1030 bits
[0] = bits
[1] = bits
[2] = bits
[3] = 16;
1033 case GL_LUMINANCE_ALPHA32I_EXT
:
1034 case GL_LUMINANCE_ALPHA32UI_EXT
:
1035 case GL_LUMINANCE_ALPHA32F_ARB
:
1036 case GL_INTENSITY32I_EXT
:
1037 case GL_INTENSITY32UI_EXT
:
1038 case GL_INTENSITY32F_ARB
:
1039 bits
[0] = bits
[1] = bits
[2] = bits
[3] = 32;
1045 /* Wrapper around glReadPixels that always returns floats; reads and converts
1046 * GL_UNSIGNED_BYTE on GLES. If pixels == NULL, malloc a float array of the
1047 * appropriate size, otherwise use the one provided. */
1049 piglit_read_pixels_float(GLint x
, GLint y
, GLsizei width
, GLsizei height
,
1050 GLenum format
, GLfloat
*pixels
)
1054 int comps
= piglit_num_components(format
);
1057 pixels
= malloc(width
* height
* comps
* sizeof(GLfloat
));
1059 if (!piglit_is_gles()) {
1060 glReadPixels(x
, y
, width
, height
, format
, GL_FLOAT
, pixels
);
1064 pixels_b
= malloc(width
* height
* 4 * sizeof(GLubyte
));
1065 glReadPixels(x
, y
, width
, height
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels_b
);
1067 for (i
= 0; i
< width
* height
; i
++) {
1068 for (j
= 0; j
< comps
; j
++) {
1069 pixels
[k
++] = pixels_b
[i
*4+j
] / 255.0f
;
1081 if (!piglit_is_extension_supported("GL_ARB_framebuffer_object"))
1084 glGetIntegerv(GL_READ_BUFFER
, &read
);
1085 if (read
== GL_FRONT
)
1086 read
= GL_FRONT_LEFT
;
1087 if (read
== GL_BACK
)
1088 read
= GL_BACK_LEFT
;
1090 glGetFramebufferAttachmentParameteriv(GL_READ_FRAMEBUFFER
, read
,
1091 GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE
, &r
);
1092 glGetFramebufferAttachmentParameteriv(GL_READ_FRAMEBUFFER
, read
,
1093 GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE
, &g
);
1094 glGetFramebufferAttachmentParameteriv(GL_READ_FRAMEBUFFER
, read
,
1095 GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE
, &b
);
1096 glGetFramebufferAttachmentParameteriv(GL_READ_FRAMEBUFFER
, read
,
1097 GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE
, &a
);
1099 /* it could be LUMINANCE32F, etc. */
1100 if (!r
&& !g
&& !b
&& !a
)
1103 return r
<= 8 && g
<= 8 && b
<= 8 && a
<= 8;
1107 print_components_ubyte(const GLubyte
*pixel
, unsigned components
)
1110 for (p
= 0; p
< components
; ++p
)
1111 printf(" %u", pixel
[p
]);
1115 print_components_float(const float *pixel
, unsigned components
)
1118 for (p
= 0; p
< components
; ++p
)
1119 printf(" %f", pixel
[p
]);
1123 print_bad_pixel_ubyte(int x
, int y
, int num_components
,
1124 const GLubyte
*expected
, const GLubyte
*observed
)
1126 printf("Probe color at (%i,%i)\n", x
, y
);
1127 printf(" Expected:");
1128 print_components_ubyte(expected
, num_components
);
1129 printf("\n Observed:");
1130 print_components_ubyte(observed
, num_components
);
1135 print_bad_pixel_float(int x
, int y
, int num_components
,
1136 const float *expected
, const float *observed
)
1138 printf("Probe color at (%i,%i)\n", x
, y
);
1139 printf(" Expected:");
1140 print_components_float(expected
, num_components
);
1141 printf("\n Observed:");
1142 print_components_float(observed
, num_components
);
1147 compare_pixels_ubyte(const GLubyte
*color1
, const GLubyte
*color2
,
1148 const GLubyte
*tolerance
, int components
)
1150 for (int p
= 0; p
< components
; ++p
)
1151 if (abs((int)color1
[p
] - (int)color2
[p
]) > tolerance
[p
])
1157 piglit_compare_pixels_float(const float *color1
, const float *color2
,
1158 const float *tolerance
, int components
)
1160 for (int p
= 0; p
< components
; ++p
)
1161 if (fabsf(color1
[p
] - color2
[p
]) > tolerance
[p
])
1167 piglit_probe_pixel_rgb_silent(int x
, int y
, const float* expected
, float *out_probe
)
1171 piglit_read_pixels_float(x
, y
, 1, 1, GL_RGB
, probe
);
1174 piglit_compare_pixels_float(probe
, expected
, piglit_tolerance
, 3);
1177 memcpy(out_probe
, probe
, sizeof(probe
));
1183 piglit_probe_pixel_rgba_silent(int x
, int y
, const float* expected
, float *out_probe
)
1187 piglit_read_pixels_float(x
, y
, 1, 1, GL_RGBA
, probe
);
1190 piglit_compare_pixels_float(probe
, expected
, piglit_tolerance
, 4);
1193 memcpy(out_probe
, probe
, sizeof(probe
));
1199 * Read a pixel from the given location and compare its RGB value to the
1200 * given expected values.
1202 * Print a log message if the color value deviates from the expected value.
1203 * \return true if the color values match, false otherwise
1206 piglit_probe_pixel_rgb(int x
, int y
, const float* expected
)
1210 piglit_read_pixels_float(x
, y
, 1, 1, GL_RGB
, probe
);
1212 if (piglit_compare_pixels_float(probe
, expected
, piglit_tolerance
, 3))
1215 print_bad_pixel_float(x
, y
, 3, expected
, probe
);
1221 * Read a pixel from the given location and compare its RGBA value to the
1222 * given expected values.
1224 * Print a log message if the color value deviates from the expected value.
1225 * \return true if the color values match, false otherwise
1228 piglit_probe_pixel_rgba(int x
, int y
, const float* expected
)
1232 piglit_read_pixels_float(x
, y
, 1, 1, GL_RGBA
, probe
);
1234 if (piglit_compare_pixels_float(probe
, expected
, piglit_tolerance
, 4))
1237 print_bad_pixel_float(x
, y
, 4, expected
, probe
);
1243 array_float_to_ubyte(int n
, const float *f
, GLubyte
*b
)
1247 for (i
= 0; i
< n
; i
++)
1252 array_float_to_ubyte_roundup(int n
, const float *f
, GLubyte
*b
)
1256 for (i
= 0; i
< n
; i
++)
1257 b
[i
] = ceil(f
[i
] * 255);
1261 probe_rect_ubyte(int x
, int y
, int w
, int h
, int num_components
,
1262 const float *fexpected
, size_t x_pitch
, size_t y_pitch
,
1268 GLubyte tolerance
[4];
1269 GLubyte expected
[4];
1271 array_float_to_ubyte_roundup(num_components
, piglit_tolerance
,
1273 if (x_pitch
== 0 && y_pitch
== 0)
1274 array_float_to_ubyte(num_components
, fexpected
, expected
);
1276 /* RGBA readbacks are likely to be faster */
1277 pixels
= malloc(w
*h
*4);
1278 glReadPixels(x
, y
, w
, h
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
);
1280 for (j
= 0; j
< h
; j
++) {
1281 for (i
= 0; i
< w
; i
++) {
1282 probe
= &pixels
[(j
*w
+i
)*4];
1284 if (x_pitch
!= 0 || y_pitch
!= 0) {
1285 const float *pexp
= fexpected
+ i
* x_pitch
+
1287 array_float_to_ubyte(num_components
,
1291 if (compare_pixels_ubyte(probe
, expected
, tolerance
,
1296 print_bad_pixel_ubyte(
1297 x
+ i
, y
+ j
, num_components
,
1310 probe_rect_float(int x
, int y
, int w
, int h
, int num_components
,
1311 const float *fexpected
, size_t x_pitch
, size_t y_pitch
,
1314 float *pixels
= piglit_read_pixels_float(x
, y
, w
, h
, GL_RGBA
, NULL
);
1316 for (int j
= 0; j
< h
; j
++) {
1317 for (int i
= 0; i
< w
; i
++) {
1318 float *probe
= &pixels
[(j
*w
+i
)*4];
1319 const float *pexp
= fexpected
+ i
* x_pitch
+
1322 if (piglit_compare_pixels_float(probe
, pexp
,
1328 print_bad_pixel_float(x
+ i
, y
+ j
,
1342 probe_rect(int x
, int y
, int w
, int h
, int num_components
,
1343 const float *fexpected
, size_t x_pitch
, size_t y_pitch
,
1346 if (can_probe_ubyte()) {
1347 return probe_rect_ubyte(x
, y
, w
, h
, num_components
, fexpected
,
1348 x_pitch
, y_pitch
, silent
);
1350 return probe_rect_float(x
, y
, w
, h
, num_components
, fexpected
,
1351 x_pitch
, y_pitch
, silent
);
1357 piglit_probe_rect_rgb_silent(int x
, int y
, int w
, int h
, const float *expected
)
1359 return probe_rect(x
, y
, w
, h
, 3, expected
, 0, 0, true);
1362 /* More efficient variant if you don't know need floats and GBA channels. */
1364 piglit_probe_rect_r_ubyte(int x
, int y
, int w
, int h
, GLubyte expected
)
1366 int i
, j
, w_aligned
;
1368 GLubyte tolerance
= ceil(piglit_tolerance
[0] * 255);
1370 w_aligned
= ALIGN(w
, 4);
1371 pixels
= malloc(w_aligned
* h
);
1373 glReadPixels(x
, y
, w
, h
, GL_RED
, GL_UNSIGNED_BYTE
, pixels
);
1375 for (j
= 0; j
< h
; j
++) {
1376 for (i
= 0; i
< w
; i
++) {
1377 GLubyte probe
= pixels
[j
*w_aligned
+i
];
1379 if (abs((int)probe
- (int)expected
) >= tolerance
) {
1380 print_bad_pixel_ubyte(x
+ i
, y
+ j
, 1,
1394 piglit_probe_rect_rgb(int x
, int y
, int w
, int h
, const float *expected
)
1396 return probe_rect(x
, y
, w
, h
, 3, expected
, 0, 0, false);
1400 piglit_probe_rects_equal(int x1
, int y1
, int x2
, int y2
,
1401 int w
, int h
, GLenum format
)
1406 /* Allocate buffer large enough for two rectangles */
1407 ncomponents
= piglit_num_components(format
);
1409 /* Load the pixels into the buffer and compare */
1410 /* We only need to do one glReadPixels if the images are adjacent */
1411 if ((x1
+ w
) == x2
&& y1
== y2
) {
1413 piglit_read_pixels_float(x1
, y1
, 2 * w
, h
, format
, NULL
);
1414 retval
= piglit_compare_image_halves_color(2*w
, h
,
1421 piglit_read_pixels_float(x1
, y1
, w
, h
, format
, NULL
);
1423 piglit_read_pixels_float(x2
, y2
, w
, h
, format
, NULL
);
1424 retval
= piglit_compare_images_color(0, 0, w
, h
,
1436 piglit_probe_rect_halves_equal_rgba(int x
, int y
, int w
, int h
)
1441 GLubyte
*pixels
= malloc(w
*h
*4*sizeof(GLubyte
));
1443 glReadPixels(x
, y
, w
, h
, GL_RGBA
, GL_UNSIGNED_BYTE
, pixels
);
1445 for (j
= 0; j
< h
; j
++) {
1446 for (i
= 0; i
< w
/ 2; i
++) {
1447 GLubyte
*pixel1
= &pixels
[4 * (j
* w
+ i
)];
1448 GLubyte
*pixel2
= &pixels
[4 * (j
* w
+ w
/ 2 + i
)];
1450 for (p
= 0; p
< 4; ++p
) {
1451 probe1
[p
] = pixel1
[p
] / 255.0f
;
1452 probe2
[p
] = pixel2
[p
] / 255.0f
;
1455 if (piglit_compare_pixels_float(probe1
, probe2
,
1456 piglit_tolerance
, 4))
1459 printf("Probe color at (%i,%i)\n", x
+i
, x
+j
);
1460 printf(" Left: %f %f %f %f\n",
1461 probe1
[0], probe1
[1], probe1
[2], probe1
[3]);
1462 printf(" Right: %f %f %f %f\n",
1463 probe2
[0], probe2
[1], probe2
[2], probe2
[3]);
1475 piglit_probe_rect_rgba(int x
, int y
, int w
, int h
, const float *expected
)
1477 return probe_rect(x
, y
, w
, h
, 4, expected
, 0, 0, false);
1480 int piglit_probe_rect_rgba_varying(int x
, int y
, int w
, int h
,
1481 const float* expected
, size_t stride
)
1483 assert(stride
% sizeof(float) == 0);
1484 return probe_rect(x
, y
, w
, h
, 4, expected
,
1485 4, stride
/ sizeof(float), false);
1489 piglit_probe_rect_rgba_int(int x
, int y
, int w
, int h
, const int *expected
)
1493 GLint
*pixels
= malloc(w
*h
*4*sizeof(int));
1495 glReadPixels(x
, y
, w
, h
, GL_RGBA_INTEGER
, GL_INT
, pixels
);
1497 for (j
= 0; j
< h
; j
++) {
1498 for (i
= 0; i
< w
; i
++) {
1499 probe
= &pixels
[(j
*w
+i
)*4];
1501 for (p
= 0; p
< 4; ++p
) {
1502 if (probe
[p
] != expected
[p
]) {
1503 printf("Probe color at (%d,%d)\n", x
+i
, y
+j
);
1504 printf(" Expected: %d %d %d %d\n",
1505 expected
[0], expected
[1], expected
[2], expected
[3]);
1506 printf(" Observed: %d %d %d %d\n",
1507 probe
[0], probe
[1], probe
[2], probe
[3]);
1521 piglit_probe_rect_rgba_uint(int x
, int y
, int w
, int h
,
1522 const unsigned int *expected
)
1526 GLuint
*pixels
= malloc(w
*h
*4*sizeof(unsigned int));
1528 glReadPixels(x
, y
, w
, h
, GL_RGBA_INTEGER
, GL_UNSIGNED_INT
, pixels
);
1530 for (j
= 0; j
< h
; j
++) {
1531 for (i
= 0; i
< w
; i
++) {
1532 probe
= &pixels
[(j
*w
+i
)*4];
1534 for (p
= 0; p
< 4; ++p
) {
1535 if (probe
[p
] != expected
[p
]) {
1536 printf("Probe color at (%d,%d)\n", x
+i
, y
+j
);
1537 printf(" Expected: %u %u %u %u\n",
1538 expected
[0], expected
[1], expected
[2], expected
[3]);
1539 printf(" Observed: %u %u %u %u\n",
1540 probe
[0], probe
[1], probe
[2], probe
[3]);
1554 * Read color data from the given rectangle and compare its RGB value to the
1555 * given two expected values.
1557 * Print a log message if the color value deviates from both expected values.
1558 * \return true if the color values match, false otherwise
1561 piglit_probe_rect_two_rgb(int x
, int y
, int w
, int h
,
1562 const float *expected1
, const float *expected2
)
1564 /* RGBA readbacks are likely to be faster */
1565 float *pixels
= piglit_read_pixels_float(x
, y
, w
, h
, GL_RGBA
, NULL
);
1567 for (int j
= 0; j
< h
; j
++) {
1568 for (int i
= 0; i
< w
; i
++) {
1569 float *probe
= &pixels
[(j
* w
+ i
) * 4];
1571 if (piglit_compare_pixels_float(probe
, expected1
,
1572 piglit_tolerance
, 3) ||
1573 piglit_compare_pixels_float(probe
, expected2
,
1574 piglit_tolerance
, 3))
1577 printf("Probe color at (%i,%i)\n", x
+ i
, y
+ j
);
1578 printf(" Expected either:");
1579 print_components_float(expected1
, 3);
1581 print_components_float(expected2
, 3);
1582 printf("\n Observed:");
1583 print_components_float(probe
, 3);
1596 * Compute the appropriate tolerance for comparing images of the given
1600 piglit_compute_probe_tolerance(GLenum format
, float *tolerance
)
1602 int num_components
, component
;
1604 case GL_LUMINANCE_ALPHA
:
1605 tolerance
[0] = piglit_tolerance
[0];
1606 tolerance
[1] = piglit_tolerance
[3];
1609 tolerance
[0] = piglit_tolerance
[3];
1612 num_components
= piglit_num_components(format
);
1613 for (component
= 0; component
< num_components
; ++component
)
1614 tolerance
[component
] = piglit_tolerance
[component
];
1620 piglit_compare_pixels(int x
, int y
, const float *expected
, const float *probe
,
1621 const float *tolerance
, int num_components
)
1623 if (piglit_compare_pixels_float(probe
, expected
, tolerance
, num_components
))
1626 printf("Probe at (%i,%i)\n", x
, y
);
1627 printf(" Expected:");
1628 print_components_float(expected
, num_components
);
1629 printf("\n Observed:");
1630 print_components_float(probe
, num_components
);
1637 piglit_compare_image_halves_color(int w
, int h
, int num_components
,
1638 const float *tolerance
,
1641 int i
, j
, half_width
;
1644 for (j
= 0; j
< h
; j
++) {
1645 for (i
= 0; i
< half_width
; i
++) {
1646 const float *probe
=
1647 &image
[(j
*w
+i
)*num_components
];
1648 const float *expected
=
1649 &image
[(j
*w
+half_width
+i
)*num_components
];
1650 if (!piglit_compare_pixels(i
, j
, expected
, probe
,
1661 * Compare two in-memory floating-point images.
1664 piglit_compare_images_color(int x
, int y
, int w
, int h
, int num_components
,
1665 const float *tolerance
,
1666 const float *expected_image
,
1667 const float *observed_image
)
1670 for (j
= 0; j
< h
; j
++) {
1671 for (i
= 0; i
< w
; i
++) {
1672 const float *expected
=
1673 &expected_image
[((j
+ y
) * w
+ i
+ x
) *
1675 const float *probe
=
1676 &observed_image
[((j
+ y
) * w
+ i
+ x
) *
1679 if (piglit_compare_pixels_float(probe
, expected
, tolerance
,
1683 printf("Probe at (%i,%i)\n", x
+i
, y
+j
);
1684 printf(" Expected:");
1685 print_components_float(expected
, num_components
);
1686 printf("\n Observed:");
1687 print_components_float(probe
, num_components
);
1698 * Compare the region indicated by x, y, w and h of the current read
1699 * framebuffer with the given in-memory floating-point image of
1703 piglit_probe_image_color(int x
, int y
, int w
, int h
, GLenum format
,
1706 int c
= piglit_num_components(format
);
1711 piglit_compute_probe_tolerance(format
, tolerance
);
1713 if (format
== GL_INTENSITY
) {
1714 /* GL_INTENSITY is not allowed for ReadPixels so
1715 * substitute GL_LUMINANCE.
1717 format
= GL_LUMINANCE
;
1720 pixels
= piglit_read_pixels_float(x
, y
, w
, h
, format
, NULL
);
1722 result
= piglit_compare_images_color(0, 0, w
, h
, c
, tolerance
, image
,
1730 piglit_probe_image_rgb(int x
, int y
, int w
, int h
, const float *image
)
1732 return piglit_probe_image_color(x
, y
, w
, h
, GL_RGB
, image
);
1736 piglit_probe_image_rgba(int x
, int y
, int w
, int h
, const float *image
)
1738 return piglit_probe_image_color(x
, y
, w
, h
, GL_RGBA
, image
);
1742 * Compare two in-memory unsigned-byte images.
1745 piglit_compare_images_ubyte(int x
, int y
, int w
, int h
,
1746 const GLubyte
*expected_image
,
1747 const GLubyte
*observed_image
)
1750 for (j
= 0; j
< h
; j
++) {
1751 for (i
= 0; i
< w
; i
++) {
1752 const GLubyte expected
= expected_image
[j
*w
+i
];
1753 const GLubyte probe
= observed_image
[j
*w
+i
];
1755 if (probe
!= expected
) {
1756 printf("Probe at (%i,%i)\n", x
+i
, y
+j
);
1757 printf(" Expected: %d\n", expected
);
1758 printf(" Observed: %d\n", probe
);
1769 * Compare the image (array) stored in \p observed with the image obtained from
1770 * \p expected_original with the box described by ux,uy,uz and uw,uh,ud
1771 * replaced by \p expected_updated.
1773 * Only the highest \p bits bits of all four channels are compared.
1776 piglit_equal_images_update_rgba8(const GLubyte
*expected_original
,
1777 const GLubyte
*expected_updated
,
1778 const GLubyte
*observed
,
1779 unsigned w
, unsigned h
, unsigned d
,
1780 unsigned ux
, unsigned uy
, unsigned uz
,
1781 unsigned uw
, unsigned uh
, unsigned ud
,
1784 assert(bits
> 0 && bits
<= 8);
1787 const uint8_t compare_mask
= 0xff << (8 - bits
);
1789 for (z
= 0; z
< d
; ++z
) {
1790 for (y
= 0; y
< h
; y
++) {
1791 for (x
= 0; x
< w
; x
++) {
1794 if (x
>= ux
&& x
< ux
+ uw
&&
1795 y
>= uy
&& y
< uy
+ uh
&&
1796 z
>= uz
&& z
< uz
+ ud
)
1797 ref
= expected_updated
;
1799 ref
= expected_original
;
1802 ((ref
[0] ^ observed
[0]) |
1803 (ref
[1] ^ observed
[1]) |
1804 (ref
[2] ^ observed
[2]) |
1805 (ref
[3] ^ observed
[3])) &
1808 printf("%u,%u,%u: test = %u,%u,%u,%u "
1809 "ref = %u,%u,%u,%u (comparing %u bits)\n",
1811 observed
[0], observed
[1],
1812 observed
[2], observed
[3],
1813 ref
[0], ref
[1], ref
[2], ref
[3],
1819 expected_original
+= 4;
1820 expected_updated
+= 4;
1829 * Compare the contents of the current read framebuffer's stencil
1830 * buffer with the given in-memory byte image.
1833 piglit_probe_image_stencil(int x
, int y
, int w
, int h
,
1834 const GLubyte
*image
)
1836 GLubyte
*pixels
= malloc(w
*h
*sizeof(GLubyte
));
1838 GLint old_pack_alignment
;
1840 /* Temporarily set pack alignment to 1 so that glReadPixels
1841 * won't put any padding at the end of the row.
1843 glGetIntegerv(GL_PACK_ALIGNMENT
, &old_pack_alignment
);
1844 glPixelStorei(GL_PACK_ALIGNMENT
, 1);
1846 glReadPixels(x
, y
, w
, h
, GL_STENCIL_INDEX
, GL_UNSIGNED_BYTE
, pixels
);
1848 glPixelStorei(GL_PACK_ALIGNMENT
, old_pack_alignment
);
1850 result
= piglit_compare_images_ubyte(x
, y
, w
, h
, image
, pixels
);
1857 piglit_probe_image_ubyte(int x
, int y
, int w
, int h
, GLenum format
,
1858 const GLubyte
*image
)
1860 const int c
= piglit_num_components(format
);
1861 GLubyte
*pixels
= malloc(w
* h
* 4 * sizeof(GLubyte
));
1863 GLubyte tolerance
[4];
1865 array_float_to_ubyte_roundup(4, piglit_tolerance
, tolerance
);
1867 glReadPixels(x
, y
, w
, h
, format
, GL_UNSIGNED_BYTE
, pixels
);
1869 for (j
= 0; j
< h
; j
++) {
1870 for (i
= 0; i
< w
; i
++) {
1871 const GLubyte
*expected
= &image
[(j
* w
+ i
) * c
];
1872 const GLubyte
*probe
= &pixels
[(j
* w
+ i
) * c
];
1874 if (compare_pixels_ubyte(probe
, expected
, tolerance
,
1878 printf("Probe at (%i,%i)\n", x
+ i
, y
+ j
);
1879 printf(" Expected:");
1880 print_components_ubyte(expected
, c
);
1881 printf("\n Observed:");
1882 print_components_ubyte(probe
, c
);
1894 #ifndef PIGLIT_USE_OPENGL
1896 create_fbo_from_texture(GLenum target
, GLint texture
, GLint level
, GLint layer
)
1900 glGenFramebuffers(1, &fbo
);
1901 glBindFramebuffer(GL_FRAMEBUFFER
, fbo
);
1904 glFramebufferTextureLayer(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
1905 texture
, level
, layer
);
1907 glFramebufferTexture2D(GL_FRAMEBUFFER
, GL_COLOR_ATTACHMENT0
,
1908 target
, texture
, level
);
1911 assert(glCheckFramebufferStatus(GL_FRAMEBUFFER
) ==
1912 GL_FRAMEBUFFER_COMPLETE
);
1917 binding_from_target(GLenum target
)
1921 return GL_TEXTURE_BINDING_2D
;
1922 case GL_TEXTURE_2D_ARRAY
:
1923 return GL_TEXTURE_BINDING_2D_ARRAY
;
1925 fprintf(stderr
, "%s: unsupported target 0x%x\n",
1932 * Read texels in OpenGL ES compatible way.
1934 * Currently bound texture is attached to a framebuffer object and
1935 * contents are read using glReadPixels. Supported targets are
1936 * GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY.
1939 read_texture_via_fbo(int target
, int level
, int x
, int y
, int layer
, int w
,
1942 GLint width
, height
, depth
;
1943 GLint current_read_fbo
, current_draw_fbo
, current_texture
;
1944 GLenum binding
= binding_from_target(target
);
1949 assert(binding
!= 0);
1951 glGetIntegerv(binding
, ¤t_texture
);
1952 glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING
, ¤t_read_fbo
);
1953 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING
, ¤t_draw_fbo
);
1955 assert(target
== GL_TEXTURE_2D
|| target
== GL_TEXTURE_2D_ARRAY
);
1957 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_WIDTH
, &width
);
1958 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_HEIGHT
, &height
);
1959 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_DEPTH
, &depth
);
1961 /* Depth equals 1 in case of GL_TEXTURE_2D, in case of
1962 * GL_TEXTURE_2D_ARRAY we allocate space for many layers.
1964 buffer
= malloc(width
* height
* depth
* 4 * sizeof(GLfloat
));
1965 buf
= malloc(width
* height
* depth
* 4 * sizeof(unsigned char));
1967 /* Read all layers. */
1968 for (int i
= layer
; i
>= 0; i
--) {
1970 create_fbo_from_texture(target
, current_texture
, level
,
1974 /* Offset to the layer we are expected to read. Note, in case
1975 * of GL_TEXTURE_2D, offset will be always 0 as i equals 0.
1977 offset
= i
* (width
* height
* 4);
1978 glReadPixels(0, 0, width
, height
, GL_RGBA
, GL_UNSIGNED_BYTE
,
1981 glDeleteFramebuffers(1, &fbo
);
1984 /* Convert the result, callers expect floating point. */
1985 for (unsigned k
= 0; k
< (layer
+ 1) * width
* height
* 4; k
++)
1986 buffer
[k
] = ((float) buf
[k
]) / 255.0;
1990 /* Restore FBO state. */
1991 glBindFramebuffer(GL_READ_FRAMEBUFFER
, current_read_fbo
);
1992 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, current_draw_fbo
);
2000 * Read a texel rectangle from the given location and compare its RGB value to
2001 * the given expected values.
2003 * Print a log message if the color value deviates from the expected value.
2004 * \return true if the color values match, false otherwise
2006 int piglit_probe_texel_rect_rgb(int target
, int level
, int x
, int y
,
2007 int w
, int h
, const float* expected
)
2015 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_WIDTH
, &width
);
2016 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_HEIGHT
, &height
);
2017 buffer
= malloc(width
* height
* 3 * sizeof(GLfloat
));
2019 glGetTexImage(target
, level
, GL_RGB
, GL_FLOAT
, buffer
);
2023 assert(x
+w
<= width
);
2024 assert(y
+h
<= height
);
2026 for (j
= y
; j
< y
+h
; ++j
) {
2027 for (i
= x
; i
< x
+w
; ++i
) {
2028 probe
= &buffer
[(j
* width
+ i
) * 3];
2030 if (piglit_compare_pixels_float(probe
, expected
,
2031 piglit_tolerance
, 3))
2044 * Read a texel from the given location and compare its RGB value to the
2045 * given expected values.
2047 * Print a log message if the color value deviates from the expected value.
2048 * \return true if the color values match, false otherwise
2050 int piglit_probe_texel_rgb(int target
, int level
, int x
, int y
,
2051 const float *expected
)
2053 return piglit_probe_texel_rect_rgb(target
, level
, x
, y
, 1, 1, expected
);
2057 * Read a texel rectangle from the given location and compare its RGBA value to
2058 * the given expected values.
2060 * Print a log message if the color value deviates from the expected value.
2061 * \return true if the color values match, false otherwise
2063 int piglit_probe_texel_rect_rgba(int target
, int level
, int x
, int y
,
2064 int w
, int h
, const float* expected
)
2072 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_WIDTH
, &width
);
2073 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_HEIGHT
, &height
);
2075 #ifndef PIGLIT_USE_OPENGL
2076 if (target
== GL_TEXTURE_2D
) {
2077 buffer
= read_texture_via_fbo(target
, level
, x
, y
, 0, w
, h
);
2080 buffer
= malloc(width
* height
* 4 * sizeof(GLfloat
));
2081 glGetTexImage(target
, level
, GL_RGBA
, GL_FLOAT
, buffer
);
2083 #ifndef PIGLIT_USE_OPENGL
2088 assert(x
+w
<= width
);
2089 assert(y
+h
<= height
);
2091 for (j
= y
; j
< y
+h
; ++j
) {
2092 for (i
= x
; i
< x
+w
; ++i
) {
2093 probe
= &buffer
[(j
* width
+ i
) * 4];
2095 if (piglit_compare_pixels_float(probe
, expected
,
2096 piglit_tolerance
, 4))
2099 print_bad_pixel_float(i
, j
, 4,
2113 * Read a texel from the given location and compare its RGBA value to the
2114 * given expected values.
2116 * Print a log message if the color value deviates from the expected value.
2117 * \return true if the color values match, false otherwise
2119 int piglit_probe_texel_rgba(int target
, int level
, int x
, int y
,
2120 const float* expected
)
2122 return piglit_probe_texel_rect_rgba(target
, level
, x
, y
, 1, 1,
2127 * Read a texel rectangle from the given location and compare its RGBA value to
2128 * the given expected values.
2130 * Print a log message if the color value deviates from the expected value.
2131 * \return true if the color values match, false otherwise
2133 int piglit_probe_texel_volume_rgba(int target
, int level
, int x
, int y
, int z
,
2134 int w
, int h
, int d
, const float* expected
)
2143 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_WIDTH
, &width
);
2144 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_HEIGHT
, &height
);
2145 glGetTexLevelParameteriv(target
, level
, GL_TEXTURE_DEPTH
, &depth
);
2147 #ifndef PIGLIT_USE_OPENGL
2148 if (target
== GL_TEXTURE_2D_ARRAY
) {
2149 buffer
= read_texture_via_fbo(target
, level
, x
, y
, z
, w
, h
);
2152 buffer
= malloc(width
* height
* depth
* 4 * sizeof(GLfloat
));
2153 glGetTexImage(target
, level
, GL_RGBA
, GL_FLOAT
, buffer
);
2155 #ifndef PIGLIT_USE_OPENGL
2161 assert(x
+w
<= width
);
2162 assert(y
+h
<= height
);
2163 assert(z
+d
<= depth
);
2165 for (k
= z
; k
< z
+d
; ++k
) {
2166 for (j
= y
; j
< y
+h
; ++j
) {
2167 for (i
= x
; i
< x
+w
; ++i
) {
2168 probe
= &buffer
[(k
* width
* height
+ j
* width
+ i
) * 4];
2170 if (piglit_compare_pixels_float(probe
, expected
,
2171 piglit_tolerance
, 4))
2174 printf("Probe color at (%i,%i,%i)\n",
2176 printf(" Expected: ");
2177 print_components_float(expected
, 4);
2178 printf("\n Observed: ");
2179 print_components_float(probe
, 4);
2193 * Read a pixel from the given location and compare its depth value to the
2194 * given expected value.
2196 * Print a log message if the depth value deviates from the expected value.
2197 * \return true if the depth value matches, false otherwise
2199 int piglit_probe_pixel_depth(int x
, int y
, float expected
)
2204 glReadPixels(x
, y
, 1, 1, GL_DEPTH_COMPONENT
, GL_FLOAT
, &probe
);
2206 delta
= probe
- expected
;
2207 if (fabs(delta
) < 0.01)
2210 printf("Probe depth at (%i,%i)\n", x
, y
);
2211 printf(" Expected: %f\n", expected
);
2212 printf(" Observed: %f\n", probe
);
2217 int piglit_probe_rect_depth(int x
, int y
, int w
, int h
, float expected
)
2221 GLfloat
*pixels
= malloc(w
*h
*sizeof(float));
2223 glReadPixels(x
, y
, w
, h
, GL_DEPTH_COMPONENT
, GL_FLOAT
, pixels
);
2225 for (j
= 0; j
< h
; j
++) {
2226 for (i
= 0; i
< w
; i
++) {
2227 probe
= &pixels
[j
*w
+i
];
2229 if (fabs(*probe
- expected
) >= 0.01) {
2230 printf("Probe depth at (%i,%i)\n", x
+i
, y
+j
);
2231 printf(" Expected: %f\n", expected
);
2232 printf(" Observed: %f\n", *probe
);
2244 int piglit_probe_pixel_stencil(int x
, int y
, unsigned expected
)
2247 glReadPixels(x
, y
, 1, 1, GL_STENCIL_INDEX
, GL_UNSIGNED_INT
, &probe
);
2249 if (probe
== expected
)
2252 printf("Probe stencil at (%i, %i)\n", x
, y
);
2253 printf(" Expected: %u\n", expected
);
2254 printf(" Observed: %u\n", probe
);
2259 int piglit_probe_rect_stencil(int x
, int y
, int w
, int h
, unsigned expected
)
2262 GLuint
*pixels
= malloc(w
*h
*sizeof(GLuint
));
2264 glReadPixels(x
, y
, w
, h
, GL_STENCIL_INDEX
, GL_UNSIGNED_INT
, pixels
);
2266 for (j
= 0; j
< h
; j
++) {
2267 for (i
= 0; i
< w
; i
++) {
2268 GLuint probe
= pixels
[j
* w
+ i
];
2269 if (probe
!= expected
) {
2270 printf("Probe stencil at (%i, %i)\n", x
+ i
, y
+ j
);
2271 printf(" Expected: %u\n", expected
);
2272 printf(" Observed: %u\n", probe
);
2283 bool piglit_probe_buffer(GLuint buf
, GLenum target
, const char *label
,
2284 unsigned n
, unsigned num_components
,
2285 const float *expected
)
2291 glBindBuffer(target
, buf
);
2292 ptr
= glMapBuffer(target
, GL_READ_ONLY
);
2294 for (i
= 0; i
< n
* num_components
; i
++) {
2295 if (fabs(ptr
[i
] - expected
[i
% num_components
]) > 0.01) {
2296 printf("%s[%i]: %f, Expected: %f\n", label
, i
, ptr
[i
],
2297 expected
[i
% num_components
]);
2302 glUnmapBuffer(target
);
2307 bool piglit_probe_buffer_doubles(GLuint buf
, GLenum target
, const char *label
,
2308 unsigned n
, unsigned num_components
,
2309 const double *expected
)
2315 glBindBuffer(target
, buf
);
2316 ptr
= glMapBuffer(target
, GL_READ_ONLY
);
2318 for (i
= 0; i
< n
* num_components
; i
++) {
2319 if (fabs(ptr
[i
] - expected
[i
% num_components
]) > 0.01) {
2320 printf("%s[%i]: %f, Expected: %f\n", label
, i
, ptr
[i
],
2321 expected
[i
% num_components
]);
2326 glUnmapBuffer(target
);
2331 int piglit_use_fragment_program(void)
2333 return piglit_is_extension_supported("GL_ARB_fragment_program");
2336 void piglit_require_fragment_program(void)
2338 if (!piglit_use_fragment_program()) {
2339 printf("GL_ARB_fragment_program not supported.\n");
2340 piglit_report_result(PIGLIT_SKIP
);
2344 int piglit_use_vertex_program(void)
2346 return piglit_is_extension_supported("GL_ARB_vertex_program");
2349 void piglit_require_vertex_program(void)
2351 if (!piglit_use_vertex_program()) {
2352 printf("GL_ARB_vertex_program not supported.\n");
2353 piglit_report_result(PIGLIT_SKIP
);
2357 GLuint
piglit_compile_program(GLenum target
, const char* text
)
2362 glGenProgramsARB(1, &program
);
2363 glBindProgramARB(target
, program
);
2366 GL_PROGRAM_FORMAT_ASCII_ARB
,
2368 (const GLubyte
*)text
);
2369 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB
, &errorPos
);
2370 if (glGetError() != GL_NO_ERROR
|| errorPos
!= -1) {
2371 int l
= piglit_find_line(text
, errorPos
);
2374 fprintf(stderr
, "Compiler Error (pos=%d line=%d): %s\n",
2376 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB
));
2378 for (a
=-10; a
<10; a
++)
2382 if (errorPos
+a
>= strlen(text
))
2384 fprintf(stderr
, "%c", text
[errorPos
+a
]);
2386 fprintf(stderr
, "\nin program:\n%s", text
);
2387 piglit_report_result(PIGLIT_FAIL
);
2389 if (!glIsProgramARB(program
)) {
2390 fprintf(stderr
, "glIsProgramARB failed\n");
2391 piglit_report_result(PIGLIT_FAIL
);
2398 * Convenience function to draw a triangle.
2401 piglit_draw_triangle(float x1
, float y1
, float x2
, float y2
,
2404 piglit_draw_triangle_z(0.0, x1
, y1
, x2
, y2
, x3
, y3
);
2408 * Convenience function to draw a triangle at a given depth.
2411 piglit_draw_triangle_z(float z
, float x1
, float y1
, float x2
, float y2
,
2429 glVertexPointer(4, GL_FLOAT
, 0, verts
);
2430 glEnableClientState(GL_VERTEX_ARRAY
);
2432 glDrawArrays(GL_TRIANGLES
, 0, 3);
2434 glDisableClientState(GL_VERTEX_ARRAY
);
2438 * Generate an extended checkerboard texture where the color of each quadrant
2439 * in a 2x2 block of tiles can be specified individually.
2441 * \param tex Name of the texture to be used. If \c tex is
2442 * zero, a new texture name will be generated.
2443 * \param level Mipmap level the checkerboard should be written to
2444 * \param width Width of the texture image
2445 * \param height Height of the texture image
2446 * \param horiz_square_size Size of each checkerboard tile along the X axis
2447 * \param vert_square_size Size of each checkerboard tile along the Y axis
2448 * \param bl RGBA color to be used for "bottom-left" tiles
2449 * \param br RGBA color to be used for "bottom-right" tiles
2450 * \param tl RGBA color to be used for "top-left" tiles
2451 * \param tr RGBA color to be used for "top-right" tiles
2453 * The texture data is written to LOD \c level of the texture \c tex.
2455 * If \c tex is zero, a new texture created. This texture will have several
2456 * texture parameters set to non-default values:
2458 * - Min and mag filter will be set to \c GL_NEAREST.
2460 * - S and T wrap modes will be set to \c GL_CLAMP_TO_BORDER.
2461 * - Border color will be set to { 1.0, 0.0, 0.0, 1.0 }.
2463 * - S and T wrap modes will be set to \c GL_CLAMP_TO_EDGE.
2466 * Name of the texture. In addition, this texture will be bound to the
2467 * \c GL_TEXTURE_2D target of the currently active texture unit.
2470 piglit_quads_texture(GLuint tex
, unsigned level
,
2471 unsigned width
, unsigned height
,
2472 unsigned horiz_square_size
,
2473 unsigned vert_square_size
,
2474 const float *bl
, const float *br
,
2475 const float *tl
, const float *tr
)
2477 static const GLfloat border_color
[4] = { 1.0, 0.0, 0.0, 1.0 };
2482 unsigned pixel_size
;
2483 GLubyte bl_b
[4], br_b
[4], tl_b
[4], tr_b
[4];
2484 const void *bl_data
, *br_data
, *tl_data
, *tr_data
;
2486 if (piglit_is_gles()) {
2487 pixel_size
= 4 * sizeof(GLubyte
);
2488 for (i
= 0; i
< 4; i
++) {
2489 bl_b
[i
] = bl
[i
] * 255;
2490 br_b
[i
] = br
[i
] * 255;
2491 tl_b
[i
] = tl
[i
] * 255;
2492 tr_b
[i
] = tr
[i
] * 255;
2499 pixel_size
= 4 * sizeof(float);
2505 texel
= tex_data
= malloc(width
* height
* pixel_size
);
2507 for (i
= 0; i
< height
; i
++) {
2508 const unsigned row
= i
/ vert_square_size
;
2510 for (j
= 0; j
< width
; j
++) {
2511 const unsigned col
= j
/ horiz_square_size
;
2515 memcpy(texel
, tr_data
, pixel_size
);
2517 memcpy(texel
, tl_data
, pixel_size
);
2520 memcpy(texel
, br_data
, pixel_size
);
2522 memcpy(texel
, bl_data
, pixel_size
);
2525 texel
+= pixel_size
;
2530 glGenTextures(1, &tex
);
2532 glBindTexture(GL_TEXTURE_2D
, tex
);
2533 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
2535 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
2537 if (piglit_is_gles()) {
2538 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
,
2540 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
,
2543 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
,
2544 GL_CLAMP_TO_BORDER
);
2545 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
,
2546 GL_CLAMP_TO_BORDER
);
2547 glTexParameterfv(GL_TEXTURE_2D
,
2548 GL_TEXTURE_BORDER_COLOR
,
2552 glBindTexture(GL_TEXTURE_2D
, tex
);
2555 glTexImage2D(GL_TEXTURE_2D
, level
, GL_RGBA
, width
, height
, 0, GL_RGBA
,
2556 piglit_is_gles() ? GL_UNSIGNED_BYTE
: GL_FLOAT
, tex_data
);
2564 * Generate a checkerboard texture
2566 * \param tex Name of the texture to be used. If \c tex is
2567 * zero, a new texture name will be generated.
2568 * \param level Mipmap level the checkerboard should be written to
2569 * \param width Width of the texture image
2570 * \param height Height of the texture image
2571 * \param horiz_square_size Size of each checkerboard tile along the X axis
2572 * \param vert_square_size Size of each checkerboard tile along the Y axis
2573 * \param black RGBA color to be used for "black" tiles
2574 * \param white RGBA color to be used for "white" tiles
2576 * A texture with alternating black and white squares in a checkerboard
2577 * pattern is generated. The texture data is written to LOD \c level of
2578 * the texture \c tex.
2580 * If \c tex is zero, a new texture created. This texture will have several
2581 * texture parameters set to non-default values:
2583 * - Min and mag filter will be set to \c GL_NEAREST.
2585 * - S and T wrap modes will be set to \c GL_CLAMP_TO_BORDER.
2586 * - Border color will be set to { 1.0, 0.0, 0.0, 1.0 }.
2588 * - S and T wrap modes will be set to \c GL_CLAMP_TO_EDGE.
2591 * Name of the texture. In addition, this texture will be bound to the
2592 * \c GL_TEXTURE_2D target of the currently active texture unit.
2595 piglit_checkerboard_texture(GLuint tex
, unsigned level
,
2596 unsigned width
, unsigned height
,
2597 unsigned horiz_square_size
,
2598 unsigned vert_square_size
,
2599 const float *black
, const float *white
)
2601 return piglit_quads_texture(tex
, level
, width
, height
,
2602 horiz_square_size
, vert_square_size
,
2603 black
, white
, white
, black
);
2607 * Generates a 8x8 mipmapped texture whose layers contain solid r, g, b, and w.
2610 piglit_miptree_texture()
2616 glGenTextures(1, &tex
);
2617 glBindTexture(GL_TEXTURE_2D
, tex
);
2618 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2619 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2620 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
2621 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
2622 GL_NEAREST_MIPMAP_NEAREST
);
2624 for (level
= 0; level
< 4; ++level
) {
2627 data
= malloc(size
*size
*4*sizeof(GLfloat
));
2628 for (i
= 0; i
< size
* size
; ++i
) {
2629 memcpy(data
+ 4 * i
, color_wheel
[level
],
2630 4 * sizeof(GLfloat
));
2632 glTexImage2D(GL_TEXTURE_2D
, level
, GL_RGBA
,
2633 size
, size
, 0, GL_RGBA
, GL_FLOAT
, data
);
2640 * Generates an image of the given size with quadrants of red, green,
2642 * Note that for compressed teximages, where the blocking would be
2643 * problematic, we assign the whole layers at w == 4 to red, w == 2 to
2644 * green, and w == 1 to blue.
2646 * \param internalFormat either GL_RGBA or a specific compressed format
2647 * \param w the width in texels
2648 * \param h the height in texels
2649 * \param alpha if TRUE, use varied alpha values, else all alphas = 1
2650 * \param basetype either GL_UNSIGNED_NORMALIZED, GL_SIGNED_NORMALIZED
2654 piglit_rgbw_image(GLenum internalFormat
, int w
, int h
,
2655 GLboolean alpha
, GLenum basetype
)
2657 float red
[4] = {1.0, 0.0, 0.0, 0.0};
2658 float green
[4] = {0.0, 1.0, 0.0, 0.25};
2659 float blue
[4] = {0.0, 0.0, 1.0, 0.5};
2660 float white
[4] = {1.0, 1.0, 1.0, 1.0};
2672 case GL_UNSIGNED_NORMALIZED
:
2675 case GL_SIGNED_NORMALIZED
:
2676 for (x
= 0; x
< 4; x
++) {
2677 red
[x
] = red
[x
] * 2 - 1;
2678 green
[x
] = green
[x
] * 2 - 1;
2679 blue
[x
] = blue
[x
] * 2 - 1;
2680 white
[x
] = white
[x
] * 2 - 1;
2685 for (x
= 0; x
< 4; x
++) {
2686 red
[x
] = red
[x
] * 10 - 5;
2687 green
[x
] = green
[x
] * 10 - 5;
2688 blue
[x
] = blue
[x
] * 10 - 5;
2689 white
[x
] = white
[x
] * 10 - 5;
2697 data
= malloc(w
* h
* 4 * sizeof(GLfloat
));
2699 for (y
= 0; y
< h
; y
++) {
2700 for (x
= 0; x
< w
; x
++) {
2701 const int size
= w
> h
? w
: h
;
2704 if (x
< w
/ 2 && y
< h
/ 2)
2713 switch (internalFormat
) {
2714 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT
:
2715 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT
:
2716 case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT
:
2717 case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT
:
2718 case GL_COMPRESSED_RGB_FXT1_3DFX
:
2719 case GL_COMPRESSED_RGBA_FXT1_3DFX
:
2720 case GL_COMPRESSED_RED_RGTC1
:
2721 case GL_COMPRESSED_SIGNED_RED_RGTC1
:
2722 case GL_COMPRESSED_RG_RGTC2
:
2723 case GL_COMPRESSED_SIGNED_RG_RGTC2
:
2724 case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT
:
2725 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT
:
2726 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT
:
2727 case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT
:
2728 case GL_COMPRESSED_RGBA_BPTC_UNORM
:
2729 case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM
:
2730 case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT
:
2731 case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT
:
2743 memcpy(data
+ (y
* w
+ x
) * 4, color
,
2752 piglit_rgbw_image_ubyte(int w
, int h
, GLboolean alpha
)
2754 GLubyte red
[4] = {255, 0, 0, 0};
2755 GLubyte green
[4] = {0, 255, 0, 64};
2756 GLubyte blue
[4] = {0, 0, 255, 128};
2757 GLubyte white
[4] = {255, 255, 255, 255};
2768 data
= malloc(w
* h
* 4 * sizeof(GLubyte
));
2770 for (y
= 0; y
< h
; y
++) {
2771 for (x
= 0; x
< w
; x
++) {
2772 const GLubyte
*color
;
2774 if (x
< w
/ 2 && y
< h
/ 2)
2783 memcpy(data
+ (y
* w
+ x
) * 4, color
,
2784 4 * sizeof(GLubyte
));
2792 * Generates a texture with the given internalFormat, w, h with a
2793 * teximage of r, g, b, w quadrants.
2795 * Note that for compressed teximages, where the blocking would be
2796 * problematic, we assign the whole layers at w == 4 to red, w == 2 to
2797 * green, and w == 1 to blue.
2800 piglit_rgbw_texture(GLenum internalFormat
, int w
, int h
, GLboolean mip
,
2801 GLboolean alpha
, GLenum basetype
)
2805 GLenum teximage_type
;
2808 case GL_UNSIGNED_NORMALIZED
:
2809 case GL_SIGNED_NORMALIZED
:
2811 teximage_type
= GL_FLOAT
;
2813 case GL_UNSIGNED_BYTE
:
2814 teximage_type
= GL_UNSIGNED_BYTE
;
2821 glGenTextures(1, &tex
);
2822 glBindTexture(GL_TEXTURE_2D
, tex
);
2823 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2824 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2826 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
2828 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
2829 GL_LINEAR_MIPMAP_NEAREST
);
2831 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
2833 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
2837 for (level
= 0, size
= w
> h
? w
: h
; size
> 0; level
++, size
>>= 1) {
2840 if (teximage_type
== GL_UNSIGNED_BYTE
)
2841 data
= piglit_rgbw_image_ubyte(w
, h
, alpha
);
2843 data
= piglit_rgbw_image(internalFormat
, w
, h
,
2846 glTexImage2D(GL_TEXTURE_2D
, level
,
2849 GL_RGBA
, teximage_type
, data
);
2865 * Generate a 4 texel RGBA 1D texture with texels red, green, blue, white,
2866 * edge clamping and NEAREST filtering.
2869 piglit_rgbw_texture_1d(void)
2872 glGenTextures(1, &tex
);
2873 glBindTexture(GL_TEXTURE_1D
, tex
);
2874 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2875 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2876 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
2877 glTexParameteri(GL_TEXTURE_1D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
2879 static const float img
[] = {1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1};
2880 glTexImage1D(GL_TEXTURE_1D
, 0, GL_RGBA
, 4, 0, GL_RGBA
, GL_FLOAT
, img
);
2886 * Generate a 2 by 2 by 2 texel RGBA 3D texture with texels red, green, blue,
2887 * white, yellow, magenta, cyan, black, edge clamping and NEAREST filtering.
2890 piglit_rgbw_texture_3d(void)
2893 glGenTextures(1, &tex
);
2894 glBindTexture(GL_TEXTURE_3D
, tex
);
2895 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2896 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2897 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_WRAP_R
, GL_CLAMP_TO_EDGE
);
2898 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
2899 glTexParameteri(GL_TEXTURE_3D
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
2901 static const float img
[] = {1, 0, 0, 1, 0, 1, 0, 1,
2902 0, 0, 1, 1, 1, 1, 1, 1,
2903 1, 1, 0, 1, 1, 0, 1, 1,
2904 0, 1, 1, 1, 0, 0, 0, 1};
2905 glTexImage3D(GL_TEXTURE_3D
, 0, GL_RGBA
, 2, 2, 2, 0, GL_RGBA
, GL_FLOAT
, img
);
2911 * Maps a given integer internalformat to a valid format, including
2912 * the num_components info.
2915 map_integer_internalformat(GLenum internalformat
, GLenum
*format
, int *num_components
)
2917 switch(internalformat
) {
2919 *format
= GL_RED_INTEGER
;
2920 *num_components
= 1;
2923 *format
= GL_RG_INTEGER
;
2924 *num_components
= 2;
2927 *format
= GL_RGB_INTEGER
;
2928 *num_components
= 3;
2931 *format
= GL_RGBA_INTEGER
;
2932 *num_components
= 4;
2935 printf("piglit_integer_texture only supports 32-bit integer"
2936 " internalformats\n");
2937 piglit_report_result(PIGLIT_FAIL
);
2942 * Generates a texture with the given integer internal format.
2943 * It tries to use all the 4 data references (x, y, b, a) to fill the data. So:
2944 * * For 4 components: R = x, G = y, B = b, A = a.
2945 * * For 3 components: R = x, G = y, B = b + a
2946 * * For 2 components: R = x + b, G = y + a
2947 * * For 1 components: R = x + y * b + a
2948 * Note that it assumes internalformats using 32 bit integer, so we would use GL_INT.
2950 GLuint
piglit_integer_texture(GLenum internalFormat
, int w
, int h
, int b
, int a
)
2959 map_integer_internalformat(internalFormat
, &format
, &num_components
);
2961 img
= malloc(w
* h
* num_components
* sizeof(int));
2963 for (y
= 0, p
= img
; y
< h
; ++y
) {
2964 for (x
= 0; x
< w
; ++x
) {
2965 switch(num_components
) {
2982 p
[0] = x
+ y
* b
+ a
;
2986 p
+= num_components
;
2990 glGenTextures(1, &tex
);
2991 glBindTexture(GL_TEXTURE_2D
, tex
);
2992 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
2993 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
2994 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MAG_FILTER
,
2996 glTexParameteri(GL_TEXTURE_2D
, GL_TEXTURE_MIN_FILTER
,
2999 glTexStorage2D(GL_TEXTURE_2D
, 1, internalFormat
, w
, h
);
3000 glTexSubImage2D(GL_TEXTURE_2D
,
3001 0, 0, 0, w
, h
, format
, GL_INT
, img
);
3008 * Create a depth texture. The depth texture will be a gradient which varies
3009 * from 0.0 at the left side to 1.0 at the right side. For a 2D array texture,
3010 * all the texture layers will have the same gradient.
3012 * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_1D_ARRAY,
3013 * GL_TEXTURE_2D_ARRAY or GL_TEXTURE_RECTANGLE.
3014 * \param internalformat either GL_DEPTH_STENCIL, GL_DEPTH_COMPONENT,
3015 * GL_DEPTH24_STENCIL8_EXT or GL_DEPTH32F_STENCIL8.
3016 * \param w, h, d level 0 image width, height and depth
3017 * \param mip if true, create a full mipmap. Else, create single-level texture.
3018 * \return the new texture object id
3021 piglit_depth_texture(GLenum target
, GLenum internalformat
, int w
, int h
, int d
, GLboolean mip
)
3024 float *f
= NULL
, *f2
= NULL
;
3025 unsigned int *i
= NULL
;
3026 int size
, x
, y
, level
, layer
;
3028 GLenum type
, format
;
3030 glGenTextures(1, &tex
);
3031 glBindTexture(target
, tex
);
3032 glTexParameteri(target
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
3033 glTexParameteri(target
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
3035 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
,
3037 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
,
3038 GL_LINEAR_MIPMAP_NEAREST
);
3040 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
,
3042 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
,
3045 data
= malloc(w
* h
* 4 * sizeof(GLfloat
));
3047 if (internalformat
== GL_DEPTH_STENCIL_EXT
||
3048 internalformat
== GL_DEPTH24_STENCIL8_EXT
) {
3049 format
= GL_DEPTH_STENCIL_EXT
;
3050 type
= GL_UNSIGNED_INT_24_8_EXT
;
3052 } else if (internalformat
== GL_DEPTH32F_STENCIL8
) {
3053 format
= GL_DEPTH_STENCIL
;
3054 type
= GL_FLOAT_32_UNSIGNED_INT_24_8_REV
;
3057 format
= GL_DEPTH_COMPONENT
;
3062 for (level
= 0, size
= w
> h
? w
: h
; size
> 0; level
++, size
>>= 1) {
3063 for (y
= 0; y
< h
; y
++) {
3064 for (x
= 0; x
< w
; x
++) {
3065 float val
= (float)(x
) / (w
- 1);
3069 f2
[(y
* w
+ x
)*2] = val
;
3071 i
[y
* w
+ x
] = 0xffffff00 * val
;
3077 glTexImage1D(target
, level
,
3080 format
, type
, data
);
3083 case GL_TEXTURE_1D_ARRAY
:
3085 case GL_TEXTURE_RECTANGLE
:
3086 glTexImage2D(target
, level
,
3089 format
, type
, data
);
3092 case GL_TEXTURE_2D_ARRAY
:
3093 glTexImage3D(target
, level
,
3096 format
, type
, NULL
);
3097 for (layer
= 0; layer
< d
; layer
++) {
3098 glTexSubImage3D(target
, level
,
3099 0, 0, layer
, w
, h
, 1,
3100 format
, type
, data
);
3113 if (target
!= GL_TEXTURE_1D
&&
3114 target
!= GL_TEXTURE_1D_ARRAY
&&
3123 * Create 1D or 2D array texture in which each slice is a different color.
3124 * the color pattern is red, green, blue, white, red, green, ...
3127 piglit_array_texture(GLenum target
, GLenum internalformat
,
3128 int w
, int h
, int d
, GLboolean mip
)
3131 int size
, i
, level
, layer
;
3133 GLenum type
= GL_FLOAT
, format
= GL_RGBA
;
3135 if (target
== GL_TEXTURE_1D_ARRAY
) {
3139 assert(target
== GL_TEXTURE_2D_ARRAY
);
3142 glGenTextures(1, &tex
);
3143 glBindTexture(target
, tex
);
3144 glTexParameteri(target
, GL_TEXTURE_WRAP_S
, GL_CLAMP_TO_EDGE
);
3145 glTexParameteri(target
, GL_TEXTURE_WRAP_T
, GL_CLAMP_TO_EDGE
);
3147 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
,
3149 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
,
3150 GL_LINEAR_MIPMAP_NEAREST
);
3152 glTexParameteri(target
, GL_TEXTURE_MAG_FILTER
,
3154 glTexParameteri(target
, GL_TEXTURE_MIN_FILTER
,
3157 data
= malloc(w
* h
* 4 * sizeof(GLfloat
));
3159 size
= w
> h
? w
: h
;
3161 for (level
= 0; size
> 0; level
++, size
>>= 1) {
3163 /* Create mipmap level */
3164 if (target
== GL_TEXTURE_1D_ARRAY
) {
3165 glTexImage2D(target
, level
, internalformat
,
3166 w
, d
, 0, format
, type
, NULL
);
3169 glTexImage3D(target
, level
, internalformat
,
3170 w
, h
, d
, 0, format
, type
, NULL
);
3173 for (layer
= 0; layer
< d
; layer
++) {
3174 /* Set whole layer to one color */
3175 for (i
= 0; i
< w
* h
; i
++) {
3176 memcpy(data
+ 4 * i
,
3178 ARRAY_SIZE(color_wheel
)],
3179 sizeof(color_wheel
[0]));
3182 if (target
== GL_TEXTURE_1D_ARRAY
) {
3183 glTexSubImage2D(target
, level
,
3185 format
, type
, data
);
3188 glTexSubImage3D(target
, level
,
3189 0, 0, layer
, w
, h
, 1,
3190 format
, type
, data
);
3206 static const char multisample_texture_vs_source
[] =
3209 "out vec2 tex_coords;\n"
3212 " tex_coords = vertex;\n"
3213 " vec2 pos = (vertex.xy * 2) - vec2(1, 1);\n"
3214 " gl_Position = vec4(pos, 0, 1);\n"
3217 static const char multisample_texture_fs_source
[] =
3219 "#extension GL_ARB_sample_shading : enable\n"
3220 "in vec2 tex_coords;\n"
3221 "uniform sampler2DArray tex;\n"
3222 "uniform int tex_depth;\n"
3226 " int layer = (gl_SampleID * tex_depth) + z;\n"
3227 " gl_FragColor = texture(tex, vec3(tex_coords, layer));\n"
3231 * Uploads an arbitrary multisample texture.
3233 * This function acts like glTexImage for multisample textures. If the
3234 * input texture is zero, it will create one. Otherwise, it will use the
3235 * texture given and assumes that glTexImage[23]DMultisample has already
3236 * been called to establish the storage.
3238 * When this function returns, multisample texture will be bound to the
3239 * currently active texture.
3241 * \param target either GL_TEXTURE_2D_MULTISAMPLE or
3242 * GL_TEXTURE2D_MULTISAMPLE_ARRAY
3243 * \param tex texture ID for existing texture, or zero
3244 * \param internalformat a renderable color format accepted by
3245 * glTexImage2DMultisample
3246 * \param width texture width
3247 * \param height texture height
3248 * \param depth texture depth. If target is
3249 * GL_TEXTURE_2D_MULTISAMPLE, this must be 1.
3250 * \param samples the number of samples
3251 * \param format format of the pixel data
3252 * \param type type of the pixel data
3253 * \param data pixel data with which to fill the texture
3255 * \return the new texture object id
3258 piglit_multisample_texture(GLenum target
, GLuint tex
, GLenum internalFormat
,
3259 unsigned width
, unsigned height
,
3260 unsigned depth
, unsigned samples
,
3261 GLenum format
, GLenum type
, const void *data
)
3263 static GLuint prog
= 0;
3264 static GLint tex_loc
, tex_depth_loc
, z_loc
;
3265 static GLuint fbo
, array_tex
, ms_tex
;
3266 static const float verts
[] = {
3281 GLboolean arb_sample_shading
;
3282 GLfloat min_sample_shading
;
3283 GLint clamp_fragment_color
;
3286 piglit_require_extension("GL_ARB_texture_multisample");
3287 piglit_require_extension("GL_ARB_sample_shading");
3289 if (target
== GL_TEXTURE_2D_MULTISAMPLE
) {
3291 } else if (target
== GL_TEXTURE_2D_MULTISAMPLE_ARRAY
) {
3293 assert(!"Invalid texture target");
3298 /* First-run setup */
3299 prog
= piglit_build_simple_program_unlinked(
3300 multisample_texture_vs_source
,
3301 multisample_texture_fs_source
);
3302 glBindAttribLocation(prog
, 0, "vertex");
3303 glLinkProgram(prog
);
3304 if (!piglit_link_check_status(prog
)) {
3309 tex_loc
= glGetUniformLocation(prog
, "tex");
3310 tex_depth_loc
= glGetUniformLocation(prog
, "tex_depth");
3311 z_loc
= glGetUniformLocation(prog
, "z");
3313 glGenFramebuffers(1, &fbo
);
3314 glGenTextures(1, &array_tex
);
3317 /* Backup client values so we can restore them later */
3318 glGetIntegerv(GL_ACTIVE_TEXTURE
, &backup
.active_tex
);
3319 glGetIntegerv(GL_CURRENT_PROGRAM
, &backup
.prog
);
3320 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING
, &backup
.draw_fbo
);
3321 glGetIntegerv(GL_CLAMP_FRAGMENT_COLOR
, &backup
.clamp_fragment_color
);
3322 glGetIntegerv(GL_VIEWPORT
, backup
.viewport
);
3323 glGetBooleanv(GL_SAMPLE_SHADING_ARB
, &backup
.arb_sample_shading
);
3324 glGetFloatv(GL_MIN_SAMPLE_SHADING_VALUE_ARB
, &backup
.min_sample_shading
);
3326 glEnable(GL_SAMPLE_SHADING_ARB
);
3327 glMinSampleShadingARB(1.0f
);
3332 glGenTextures(1, &ms_tex
);
3333 glBindTexture(target
, ms_tex
);
3334 if (target
== GL_TEXTURE_2D_MULTISAMPLE
) {
3336 glTexImage2DMultisample(target
, samples
, internalFormat
,
3337 width
, height
, GL_TRUE
);
3339 glTexImage3DMultisample(target
, samples
, internalFormat
,
3340 width
, height
, depth
, GL_TRUE
);
3344 glBindTexture(GL_TEXTURE_2D_ARRAY
, array_tex
);
3345 glTexParameteri(GL_TEXTURE_2D_ARRAY
, GL_TEXTURE_MIN_FILTER
, GL_NEAREST
);
3346 glTexParameteri(GL_TEXTURE_2D_ARRAY
, GL_TEXTURE_MAG_FILTER
, GL_NEAREST
);
3347 glTexImage3D(GL_TEXTURE_2D_ARRAY
, 0, internalFormat
, width
, height
,
3348 depth
* samples
, 0, format
, type
, data
);
3350 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, fbo
);
3351 glViewport(0, 0, width
, height
);
3353 glClampColor(GL_CLAMP_FRAGMENT_COLOR
, GL_FALSE
);
3356 glUniform1i(tex_loc
, backup
.active_tex
- GL_TEXTURE0
);
3357 glUniform1i(tex_depth_loc
, depth
);
3359 glEnableVertexAttribArray(0);
3360 glVertexAttribPointer(0, 2, GL_FLOAT
, GL_FALSE
, 0, verts
);
3362 if (target
== GL_TEXTURE_2D_MULTISAMPLE
) {
3363 glUniform1i(z_loc
, 0);
3364 glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER
,
3365 GL_COLOR_ATTACHMENT0
,
3367 if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
) !=
3368 GL_FRAMEBUFFER_COMPLETE
)
3371 glDrawArrays(GL_TRIANGLES
, 0, 6);
3373 for (z
= 0; z
< depth
; ++z
) {
3374 glUniform1i(z_loc
, z
);
3375 glFramebufferTextureLayer(GL_DRAW_FRAMEBUFFER
,
3376 GL_COLOR_ATTACHMENT0
,
3378 if (glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER
) !=
3379 GL_FRAMEBUFFER_COMPLETE
)
3382 glDrawArrays(GL_TRIANGLES
, 0, 6);
3386 glDisableVertexAttribArray(0);
3388 /* Restore values for the client */
3389 if (!backup
.arb_sample_shading
)
3390 glDisable(GL_SAMPLE_SHADING_ARB
);
3391 glMinSampleShadingARB(backup
.min_sample_shading
);
3393 glUseProgram(backup
.prog
);
3394 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, backup
.draw_fbo
);
3395 glViewport(backup
.viewport
[0], backup
.viewport
[1],
3396 backup
.viewport
[2], backup
.viewport
[3]);
3397 glBindTexture(target
, ms_tex
);
3398 glClampColor(GL_CLAMP_FRAGMENT_COLOR
, backup
.clamp_fragment_color
);
3403 if (tex
== 0) /* We created it, clean it up */
3404 glDeleteTextures(1, &ms_tex
);
3410 * Require transform feedback.
3412 * Transform feedback may either be provided by GL 3.0 or
3413 * EXT_transform_feedback.
3416 piglit_require_transform_feedback(void)
3418 if (!(piglit_get_gl_version() >= 30 ||
3419 piglit_is_extension_supported("GL_EXT_transform_feedback"))) {
3420 printf("Transform feedback not supported.\n");
3421 piglit_report_result(PIGLIT_SKIP
);
3426 * Convert the image into a format that can be easily understood by
3427 * visual inspection, and display it on the screen.
3429 * Luminance and intensity values are converted to a grayscale value.
3430 * Alpha values are visualized by blending the image with a grayscale
3433 * Pass image_count = 0 to disable drawing multiple images to window
3434 * system framebuffer.
3437 piglit_visualize_image(float *img
, GLenum base_internal_format
,
3438 int image_width
, int image_height
,
3439 int image_count
, bool rhs
)
3443 unsigned components
= piglit_num_components(base_internal_format
);
3444 float *visualization
=
3445 (float *) malloc(sizeof(float)*3*image_width
*image_height
);
3446 for (y
= 0; y
< image_height
; ++y
) {
3447 for ( x
= 0; x
< image_width
; ++x
) {
3448 float r
= 0, g
= 0, b
= 0, a
= 1;
3450 &img
[(y
* image_width
+ x
) * components
];
3451 switch (base_internal_format
) {
3467 case GL_LUMINANCE_ALPHA
:
3477 checker
= ((x
^ y
) & 0x10) ? 0.75 : 0.25;
3478 r
= r
* a
+ checker
* (1 - a
);
3479 g
= g
* a
+ checker
* (1 - a
);
3480 b
= b
* a
+ checker
* (1 - a
);
3481 visualization
[(y
* image_width
+ x
) * 3] = r
;
3482 visualization
[(y
* image_width
+ x
) * 3 + 1] = g
;
3483 visualization
[(y
* image_width
+ x
) * 3 + 2] = b
;
3486 glBindFramebuffer(GL_DRAW_FRAMEBUFFER
, piglit_winsys_fbo
);
3489 /* To simultaneously display multiple images on window system
3493 /* Use glWindowPos to directly update x, y coordinates of
3494 * current raster position without getting transformed by
3495 * modelview projection matrix and viewport-to-window
3498 glWindowPos2f(rhs
? image_width
: 0,
3499 (image_count
- 1) * image_height
);
3502 glRasterPos2f(rhs
? 0 : -1, -1);
3504 glDrawPixels(image_width
, image_height
, GL_RGB
, GL_FLOAT
,
3506 free(visualization
);
3510 * Convert from sRGB color space to linear color space, using the
3511 * formula from the GL 3.0 spec, section 4.1.8 (sRGB Texture Color
3515 piglit_srgb_to_linear(float x
)
3520 return pow((x
+ 0.055) / 1.055, 2.4);
3523 /* Convert from linear color space to sRGB color space. */
3525 piglit_linear_to_srgb(float x
)
3529 else if (x
< 0.0031308f
)
3532 return 1.055f
* powf(x
, 0.41666f
) - 0.055f
;