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-condition_codes-01.c
26 * Validate that the correct components of the condition code register are
27 * set to the desired value.
29 * \author Ian Romanick <ian.d.romanick@intel.com>
32 #include "piglit-util-gl.h"
34 /* One for the reference square and one for each possible condition code.
36 #define TEST_ROWS (1 + 6)
38 /* One for each possible non-empty write mask.
40 #define TEST_COLS (15)
44 PIGLIT_GL_TEST_CONFIG_BEGIN
46 config
.supports_gl_compat_version
= 10;
48 config
.window_width
= (((BOX_SIZE
+1)*TEST_ROWS
)+1);
49 config
.window_height
= (((BOX_SIZE
+1)*TEST_COLS
)+1);
50 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
52 PIGLIT_GL_TEST_CONFIG_END
54 #define INVERT_MASK(x) (~(x) & 0x0f)
56 static char shader_source
[64 * 1024];
60 * Strings for binary write-masks.
62 * Bit 0 corresponds to X, bit 1 to y, etc.
64 static const char *const mask_strings
[16] = {
85 * Strings for condition codes.
87 static const char *const cc_strings
[6] = {
98 * Constant values that will set required condition codes
100 * The even values set the parallel condition code in \c cc_strings, and the
101 * odd values set something else. For example, element 4 sets GT, and element
102 * 5 does not (it sets LT).
104 static const GLfloat cc_values
[12] = {
115 * Source for the fragment program to render the reference box.
117 static const char reference_shader_source
[] =
119 "MOV result.color, program.env[0];\n"
124 * \name Handles to fragment programs.
127 static GLint reference_prog
;
128 static GLint progs
[TEST_ROWS
* TEST_COLS
];
133 generate_shader(unsigned cc
, unsigned good_mask
)
136 static const char *const swiz
[16] = {
137 "yyyy", "xyyy", "yxyy", "xxyy",
138 "yyxy", "xyxy", "yxxy", "xxxy",
139 "yyyx", "xyyx", "yxyx", "xxyx",
140 "yyxx", "xyxx", "yxxx", "xxxx",
144 len
= sprintf(& shader_source
[0],
146 "OPTION NV_fragment_program;\n"
147 "PARAM good = program.env[0];\n"
148 "PARAM junk = program.env[1];\n"
151 "# Create a combination of good and bad data in R0.\n"
155 if (good_mask
!= 0) {
156 len
+= sprintf(& shader_source
[len
],
157 "MOV R0.%s, good;\n",
158 mask_strings
[good_mask
]);
161 len
+= sprintf(& shader_source
[len
],
163 "# Set the condition codes. Inputs are on the range\n"
164 "# [0, 1], so the range must be expanded to [-1, 1].\n"
165 "MADC R2, fragment.color.%s, 2.0, -1.0;\n"
167 "# Create a combination of good and bad data in R1.\n"
168 "# The components in R0 that already have good data\n"
169 "# should have bad data in R1.\n"
171 swiz
[INVERT_MASK(good_mask
)]);
173 if (good_mask
!= 0) {
174 len
+= sprintf(& shader_source
[len
],
175 "MOV R1.%s, junk;\n",
176 mask_strings
[good_mask
]);
179 len
+= sprintf(& shader_source
[len
],
181 "# Fill remaining bits of R0 with good data from R1.\n"
182 "# Write that data to the shader output.\n"
183 "MOV R0 (%s.xyzw), R1;\n"
184 "MOV result.color, R0;\n"
193 static const GLfloat good_color
[4] = { 0.9, 0.5, 0.7, 1.0 };
194 static const GLfloat junk_color
[4] = { 0.2, 0.2, 0.2, 1.0 };
198 enum piglit_result result
= PIGLIT_PASS
;
201 glClear(GL_COLOR_BUFFER_BIT
);
203 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
,
205 glProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB
,
208 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
209 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, reference_prog
);
210 piglit_draw_rect(1, 1, BOX_SIZE
, BOX_SIZE
);
212 for (cc
= 0; cc
< 6; cc
++) {
213 glColor4f(cc_values
[(cc
* 2) + 0], cc_values
[(cc
* 2) + 1],
216 for (mask
= 0; mask
< 0x0f; mask
++) {
217 const int x
= ((cc
+ 1) * (BOX_SIZE
+ 1)) + 1;
218 const int y
= (mask
* (BOX_SIZE
+ 1)) + 1;
219 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, progs
[i
]);
220 piglit_draw_rect(x
, y
, BOX_SIZE
, BOX_SIZE
);
223 if (!piglit_probe_pixel_rgb(x
+ (BOX_SIZE
/ 2),
226 if (!piglit_automatic
)
227 printf("CC %s with mask %s failed.\n",
231 result
= PIGLIT_FAIL
;
236 piglit_present_results();
242 piglit_init(int argc
, char **argv
)
251 piglit_require_fragment_program();
252 piglit_require_extension("GL_NV_fragment_program_option");
253 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
255 reference_prog
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
,
256 reference_shader_source
);
259 for (cc
= 0; cc
< 6; cc
++) {
260 for (mask
= 0; mask
< 0x0f; mask
++) {
261 generate_shader(cc
, mask
);
263 piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
,