glx-multithread-texture: Avoid front-buffer rendering.
[piglit.git] / tests / shaders / fp-unpack-01.c
blob9d3f675ceb18748d4f4f0060f872d800d4886a90
1 /*
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
13 * Software.
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
21 * IN THE SOFTWARE.
24 /**
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
40 #define TEST_ROWS 5
42 #define BOX_SIZE 16
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] = {
58 GL_BYTE,
59 GL_UNSIGNED_BYTE,
60 GL_UNSIGNED_SHORT,
61 GL_HALF_FLOAT
65 static const char *const opcodes[4] = {
66 "UP4B", "UP4UB", "UP2US", "UP2H"
70 /**
71 * Source for the fragment program to render the reference box.
73 static const char reference_shader_source[] =
74 "!!ARBfp1.0\n"
75 "MOV result.color, program.env[0];\n"
76 "END"
79 /**
80 * \name Handles to fragment programs.
82 /*@{*/
83 static GLint reference_prog;
84 static GLint progs[ARRAY_SIZE(types)];
85 /*@}*/
88 void
89 generate_shader(GLenum type)
91 unsigned len;
92 char *swiz1;
93 char *swiz2 = NULL;
94 char *inst;
96 len = sprintf(& shader_source[0],
97 "!!ARBfp1.0\n"
98 "OPTION NV_fragment_program;\n"
99 "TEMP R0;\n"
100 "\n");
102 switch (type) {
103 case GL_HALF_FLOAT:
104 inst = "UP2H";
105 swiz1 = "xy";
106 swiz2 = "zw";
107 break;
108 case GL_UNSIGNED_SHORT:
109 inst = "UP2US";
110 swiz1 = "xy";
111 swiz2 = "zw";
112 break;
113 case GL_UNSIGNED_BYTE:
114 inst = "UP4UB";
115 swiz1 = "xyzw";
116 break;
117 case GL_BYTE:
118 default:
119 inst = "UP4B";
120 swiz1 = "xyzw";
121 break;
124 len += sprintf(& shader_source[len],
125 "\n"
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",
129 inst, swiz1);
131 if (swiz2 != NULL) {
132 len += sprintf(& shader_source[len],
133 "%s R0.%s, program.env[0].y;\n",
134 inst, swiz2);
137 len += sprintf(& shader_source[len],
138 "MOV result.color, R0;\n"
139 "END\n");
142 void
143 pack(float *packed, const float *color, GLenum type)
145 unsigned *p = (unsigned *) packed;
146 GLubyte ub[4];
147 GLushort us[4];
148 unsigned i;
150 packed[0] = 0.0f;
151 packed[1] = 0.0f;
152 packed[2] = 0.0f;
153 packed[3] = 1.0f;
155 switch (type) {
156 case GL_HALF_FLOAT:
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);
162 break;
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);
172 break;
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);
181 break;
183 case GL_BYTE:
184 for (i = 0; i < 4; i++) {
185 const float tmp =
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);
191 break;
196 enum piglit_result
197 piglit_display(void)
199 unsigned i;
200 unsigned j;
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,
212 0, colors[i]);
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;
217 GLfloat v[4];
219 pack(v, colors[i], types[j]);
220 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB,
221 0, v);
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),
227 y + (BOX_SIZE / 2),
228 colors[i])) {
229 if (!piglit_automatic)
230 printf("%s failed on color { %f %f %f %f }\n",
231 opcodes[j],
232 colors[i][0], colors[i][1],
233 colors[i][2], colors[i][3]);
235 result = PIGLIT_FAIL;
240 piglit_present_results();
241 return result;
246 * Shuffle values in-place using Fisher–Yates shuffle.
248 void shuffle(float *values, unsigned count)
250 srand(0xCAFEBEEF);
251 for (/* empty */; count > 1; count--) {
252 int32_t idx;
253 float tmp;
255 /* Generate a random index within the unshuffled portion of the
256 * array.
258 idx = rand();
259 idx = idx % count;
261 /* Exchange the randomly selected index and the list unshuffled
262 * element in the array.
264 tmp = values[idx];
265 values[idx] = values[count - 1];
266 values[count - 1] = tmp;
271 void
272 piglit_init(int argc, char **argv)
274 unsigned i;
275 float v[TEST_COLS * 3 ];
277 (void) argc;
278 (void) argv;
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,
292 shader_source);
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++) {
303 v[i] = 0.5;
307 /* Shuffle the values into random order. Generate the color data
308 * used by the tests from the shuffled values.
310 shuffle(v, 128);
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];
317 colors[i][3] = 1.0;