2 * Copyright © 2008 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
24 * Eric Anholt <eric@anholt.net>
28 #include "piglit-util.h"
30 int piglit_width
= 100, piglit_height
= 100;
31 int piglit_window_mode
= GLUT_RGB
| GLUT_DOUBLE
;
33 static int get_program_i(GLenum pname
)
37 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, pname
, &val
);
43 * Generate a program that samples the texture into the same temporary over
46 * This should excersize case (2) of question (24) of the ARB_fragment_program
49 * Note that the compiler could optimize out our inner TEX instructions
50 * since they've got the same coordinates. Assume the compiler isn't
53 static char *gen_temporary_dest_indirections(int sample_count
,
60 "MOV val, fragment.color;\n";
62 "TEX sample, fragment.color, texture[0], 2D;\n"
63 "MUL val, val, sample;\n";
65 "MOV result.color, val;\n"
69 prog
= malloc(strlen(pre
) + strlen(sample
) * sample_count
+
73 printf("malloc failed.\n");
74 piglit_report_result(PIGLIT_FAILURE
);
78 sprintf(prog
, "%s", pre
);
79 for (i
= 0; i
< sample_count
; i
++)
83 instr_count
= 2 + 2 * (sample_count
- 1) + 1;
84 if (get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
) < instr_count
) {
85 printf("indirection count %d too low to generate program with "
86 "%d indirections and %d instructions\n",
87 get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
),
88 sample_count
, instr_count
);
93 *progname
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
, prog
);
94 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, *progname
);
100 * Generate a program that samples two textures into a pair of temporaries
103 * This should excersize case (1) of question (24) of the ARB_fragment_program
104 * spec without hitting case (2) at the same time.
106 * Note that the compiler could optimize out our inner TEX instructions
107 * since they've got the same coordinates. Assume the compiler isn't
110 static char *gen_temporary_source_indirections(int sample_count
,
116 "TEMP val, val2, sample, sample2;\n"
117 "MOV val, fragment.color;\n"
118 "MOV val2, fragment.color;\n";
120 "TEX sample, val, texture[0], 2D;\n"
121 "TEX sample2, val2, texture[1], 2D;\n"
122 "MUL val, sample, sample2;\n"
123 "MUL val2, val2, val;\n";
125 "MOV result.color, val;\n"
129 instr_count
= 2 + 4 * (sample_count
- 1) + 1;
130 if (get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
) < instr_count
) {
131 printf("indirection count %d too low to generate program with "
132 "%d indirections and %d instructions\n",
133 get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
),
134 sample_count
, instr_count
);
138 prog
= malloc(strlen(pre
) + strlen(sample
) * (sample_count
- 1) +
142 printf("malloc failed.\n");
143 piglit_report_result(PIGLIT_FAILURE
);
147 sprintf(prog
, "%s", pre
);
148 for (i
= 0; i
< sample_count
- 1; i
++)
149 strcat(prog
, sample
);
152 *progname
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
, prog
);
153 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, *progname
);
159 print_program_info(char *program
)
161 printf("Program:\n");
162 printf("%s", program
);
165 printf("tex instructions: %d\n",
166 get_program_i(GL_PROGRAM_TEX_INSTRUCTIONS_ARB
));
167 printf("native tex instructions: %d\n",
168 get_program_i(GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
));
169 printf("tex indirections: %d\n",
170 get_program_i(GL_PROGRAM_TEX_INDIRECTIONS_ARB
));
171 printf("native tex indirections: %d\n",
172 get_program_i(GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
));
177 * Test that we can emit a whole load of samples as long as the indirection
180 GLboolean
test_temporary_dest_indirections(void)
182 GLboolean pass
= GL_TRUE
;
185 GLint indirections_limit
;
188 indirections_limit
= get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
);
190 count
= indirections_limit
- 1;
191 printf("testing program with %d indirections from temporary dests\n",
193 prog
= gen_temporary_dest_indirections(count
, &progname
);
195 if (!get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
196 printf("Program with %d indirections unexpectedly "
197 "exceeded native limits.\n", count
);
198 print_program_info(prog
);
204 count
= indirections_limit
+ 1;
205 printf("testing program with %d indirections from temporary dests\n",
207 prog
= gen_temporary_dest_indirections(count
, &progname
);
209 if (get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
210 printf("Program with %d indirections unexpectedly "
211 "met native limits.\n", count
);
212 print_program_info(prog
);
221 * Test that we can emit a whole load of samples as long as the indirection
224 GLboolean
test_temporary_source_indirections(void)
226 GLboolean pass
= GL_TRUE
;
229 GLint indirections_limit
;
232 indirections_limit
= get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
);
234 count
= indirections_limit
- 1;
235 printf("testing program with %d indirections from temporary sources\n",
237 prog
= gen_temporary_source_indirections(count
, &progname
);
239 if (!get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
240 printf("Program with %d indirections unexpectedly "
241 "exceeded native limits.\n", count
);
242 print_program_info(prog
);
248 count
= indirections_limit
+ 1;
249 printf("testing program with %d indirections from temporary sources\n",
251 prog
= gen_temporary_source_indirections(count
, &progname
);
253 if (get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
254 printf("Program with %d indirections unexpectedly "
255 "met native limits.\n", count
);
256 print_program_info(prog
);
267 GLboolean pass
= GL_TRUE
;
269 pass
= test_temporary_dest_indirections() && pass
;
270 pass
= test_temporary_source_indirections() && pass
;
272 return pass
? PIGLIT_SUCCESS
: PIGLIT_FAILURE
;
276 piglit_init(int argc
, char **argv
)
278 piglit_require_fragment_program();
280 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
282 printf("Maximum tex instructions: %d\n",
283 get_program_i(GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
));
284 printf("Maximum native tex instructions: %d\n",
285 get_program_i(GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
));
286 printf("Maximum tex indirections: %d\n",
287 get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
));
288 printf("Maximum native tex indirections: %d\n",
289 get_program_i(GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
));