2 * Copyright © 2009 Intel Corporation
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 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * 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 NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * \file fp-unpack-01.c
26 * Validate the four unpack instructions in GL_NV_fragment_program_option.
28 * \author Ian Romanick <ian.d.romanick@intel.com>
31 #include "piglit-util-gl.h"
33 /* There are 128 possible values. These values a distributed into 3 color
34 * components. Ensure that all of the values are seen at least once.
36 #define TEST_COLS ((128 / 3) + 1)
38 /* One for the reference square and each of the 4 unpack instructions
44 PIGLIT_GL_TEST_CONFIG_BEGIN
46 config
.supports_gl_compat_version
= 10;
48 config
.window_width
= (((BOX_SIZE
+1)*TEST_COLS
)+1);
49 config
.window_height
= (((BOX_SIZE
+1)*TEST_ROWS
)+1);
50 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
52 PIGLIT_GL_TEST_CONFIG_END
54 static char shader_source
[64 * 1024];
55 static GLfloat colors
[TEST_COLS
][4];
57 static const GLenum types
[4] = {
65 static const char *const opcodes
[4] = {
66 "UP4B", "UP4UB", "UP2US", "UP2H"
71 * Source for the fragment program to render the reference box.
73 static const char reference_shader_source
[] =
75 "MOV result.color, program.env[0];\n"
80 * \name Handles to fragment programs.
83 static GLint reference_prog
;
84 static GLint progs
[ARRAY_SIZE(types
)];
89 generate_shader(GLenum type
)
96 len
= sprintf(& shader_source
[0],
98 "OPTION NV_fragment_program;\n"
108 case GL_UNSIGNED_SHORT
:
113 case GL_UNSIGNED_BYTE
:
124 len
+= sprintf(& shader_source
[len
],
126 "# Unpack the data in fragment.color into four\n"
127 "# components of color data.\n"
128 "%s R0.%s, program.env[0].x;\n",
132 len
+= sprintf(& shader_source
[len
],
133 "%s R0.%s, program.env[0].y;\n",
137 len
+= sprintf(& shader_source
[len
],
138 "MOV result.color, R0;\n"
143 pack(float *packed
, const float *color
, GLenum type
)
145 unsigned *p
= (unsigned *) packed
;
157 for (i
= 0; i
< 4; i
++)
158 us
[i
] = piglit_half_from_float(color
[i
]);
160 p
[0] = (us
[0]) | (us
[1] << 16);
161 p
[1] = (us
[2]) | (us
[3] << 16);
164 case GL_UNSIGNED_SHORT
:
165 for (i
= 0; i
< 4; i
++) {
166 const float tmp
= CLAMP(color
[i
], 0.0, 1.0);
167 us
[i
] = (GLushort
) round(65535.0 * tmp
);
170 p
[0] = (us
[0]) | (us
[1] << 16);
171 p
[1] = (us
[2]) | (us
[3] << 16);
174 case GL_UNSIGNED_BYTE
:
175 for (i
= 0; i
< 4; i
++) {
176 const float tmp
= CLAMP(color
[i
], 0.0, 1.0);
177 ub
[i
] = (GLubyte
) round(255.0 * tmp
);
180 p
[0] = (ub
[0]) | (ub
[1] << 8) | (ub
[2] << 16) | (ub
[3] << 24);
184 for (i
= 0; i
< 4; i
++) {
186 CLAMP(color
[i
], -(128.0 / 127.0), 1.0);
187 ub
[i
] = (GLubyte
) round(127.0 * tmp
+ 128.0);
190 p
[0] = (ub
[0]) | (ub
[1] << 8) | (ub
[2] << 16) | (ub
[3] << 24);
201 enum piglit_result result
= PIGLIT_PASS
;
204 glClear(GL_COLOR_BUFFER_BIT
);
205 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
207 for (i
= 0; i
< TEST_COLS
; i
++) {
208 const int x
= (i
* (BOX_SIZE
+ 1)) + 1;
210 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, reference_prog
);
211 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
,
213 piglit_draw_rect(x
, 1, BOX_SIZE
, BOX_SIZE
);
215 for (j
= 0; j
< ARRAY_SIZE(types
); j
++) {
216 const int y
= ((j
+ 1) * (BOX_SIZE
+ 1)) + 1;
219 pack(v
, colors
[i
], types
[j
]);
220 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
,
223 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, progs
[j
]);
224 piglit_draw_rect(x
, y
, BOX_SIZE
, BOX_SIZE
);
226 if (!piglit_probe_pixel_rgb(x
+ (BOX_SIZE
/ 2),
229 if (!piglit_automatic
)
230 printf("%s failed on color { %f %f %f %f }\n",
232 colors
[i
][0], colors
[i
][1],
233 colors
[i
][2], colors
[i
][3]);
235 result
= PIGLIT_FAIL
;
240 piglit_present_results();
246 * Shuffle values in-place using Fisher–Yates shuffle.
248 void shuffle(float *values
, unsigned count
)
251 for (/* empty */; count
> 1; count
--) {
255 /* Generate a random index within the unshuffled portion of the
261 /* Exchange the randomly selected index and the list unshuffled
262 * element in the array.
265 values
[idx
] = values
[count
- 1];
266 values
[count
- 1] = tmp
;
272 piglit_init(int argc
, char **argv
)
275 float v
[TEST_COLS
* 3 ];
280 piglit_require_fragment_program();
281 piglit_require_extension("GL_NV_fragment_program_option");
282 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
284 reference_prog
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
,
285 reference_shader_source
);
287 glClearColor(1.0, 1.0, 1.0, 1.0);
289 for (i
= 0; i
< ARRAY_SIZE(types
); i
++) {
290 generate_shader(types
[i
]);
291 progs
[i
] = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
,
296 /* Generate the possible color values.
298 for (i
= 0; i
<= 127; i
++) {
299 v
[i
] = ((float) i
) / 127.0;
302 for (/* empty */; i
< ARRAY_SIZE(v
); i
++) {
307 /* Shuffle the values into random order. Generate the color data
308 * used by the tests from the shuffled values.
311 for (i
= 0; i
< TEST_COLS
; i
++) {
312 assert((i
* 3) + 2 < ARRAY_SIZE(v
));
314 colors
[i
][0] = v
[(i
* 3) + 0];
315 colors
[i
][1] = v
[(i
* 3) + 1];
316 colors
[i
][2] = v
[(i
* 3) + 2];