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-gl.h"
30 PIGLIT_GL_TEST_CONFIG_BEGIN
32 config
.supports_gl_compat_version
= 10;
34 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
36 PIGLIT_GL_TEST_CONFIG_END
38 static int get_program_i(GLenum pname
)
42 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
, pname
, &val
);
48 * Generate a program that samples the texture into the same temporary over
51 * This should exercise case (2) of question (24) of the ARB_fragment_program
54 * Note that the compiler could optimize out our inner TEX instructions
55 * since they've got the same coordinates. Assume the compiler isn't
58 static char *gen_temporary_dest_indirections(int sample_count
,
65 "MOV val, fragment.color;\n";
67 "TEX sample, fragment.color, texture[0], 2D;\n"
68 "MUL val, val, sample;\n";
70 "MOV result.color, val;\n"
74 prog
= malloc(strlen(pre
) + strlen(sample
) * sample_count
+
78 printf("malloc failed.\n");
79 piglit_report_result(PIGLIT_FAIL
);
83 sprintf(prog
, "%s", pre
);
84 for (i
= 0; i
< sample_count
; i
++)
88 instr_count
= 2 + 2 * (sample_count
- 1) + 1;
89 if (get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
) < instr_count
) {
90 printf("indirection count %d too low to generate program with "
91 "%d indirections and %d instructions\n",
92 get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
),
93 sample_count
, instr_count
);
98 *progname
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
, prog
);
99 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, *progname
);
105 * Generate a program that samples two textures into a pair of temporaries
108 * This should exercise case (1) of question (24) of the ARB_fragment_program
109 * spec without hitting case (2) at the same time.
111 * Note that the compiler could optimize out our inner TEX instructions
112 * since they've got the same coordinates. Assume the compiler isn't
115 static char *gen_temporary_source_indirections(int sample_count
,
121 "TEMP val, val2, sample, sample2;\n"
122 "MOV val, fragment.color;\n"
123 "MOV val2, fragment.color;\n";
125 "TEX sample, val, texture[0], 2D;\n"
126 "TEX sample2, val2, texture[1], 2D;\n"
127 "MUL val, sample, sample2;\n"
128 "MUL val2, val2, val;\n";
130 "MOV result.color, val;\n"
134 instr_count
= 2 + 4 * (sample_count
- 1) + 1;
135 if (get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
) < instr_count
) {
136 printf("indirection count %d too low to generate program with "
137 "%d indirections and %d instructions\n",
138 get_program_i(GL_MAX_PROGRAM_INSTRUCTIONS_ARB
),
139 sample_count
, instr_count
);
143 prog
= malloc(strlen(pre
) + strlen(sample
) * (sample_count
- 1) +
147 printf("malloc failed.\n");
148 piglit_report_result(PIGLIT_FAIL
);
152 sprintf(prog
, "%s", pre
);
153 for (i
= 0; i
< sample_count
- 1; i
++)
154 strcat(prog
, sample
);
157 *progname
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
, prog
);
158 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, *progname
);
164 print_program_info(char *program
)
166 printf("Program:\n");
167 printf("%s", program
);
170 printf("tex instructions: %d\n",
171 get_program_i(GL_PROGRAM_TEX_INSTRUCTIONS_ARB
));
172 printf("native tex instructions: %d\n",
173 get_program_i(GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
));
174 printf("tex indirections: %d\n",
175 get_program_i(GL_PROGRAM_TEX_INDIRECTIONS_ARB
));
176 printf("native tex indirections: %d\n",
177 get_program_i(GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
));
182 * Test that we can emit a whole load of samples as long as the indirection
185 GLboolean
test_temporary_dest_indirections(void)
187 GLboolean pass
= GL_TRUE
;
190 GLint indirections_limit
, use_limit
;
193 indirections_limit
= get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
);
195 use_limit
= MIN2(indirections_limit
, 1024);
197 count
= use_limit
- 1;
198 printf("testing program with %d indirections from temporary dests\n",
200 prog
= gen_temporary_dest_indirections(count
, &progname
);
202 if (!get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
203 printf("Program with %d indirections unexpectedly "
204 "exceeded native limits.\n", count
);
205 print_program_info(prog
);
211 count
= use_limit
+ 1;
212 printf("testing program with %d indirections from temporary dests\n",
214 prog
= gen_temporary_dest_indirections(count
, &progname
);
215 if (prog
!= NULL
&& count
> indirections_limit
) {
216 if (get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
217 printf("Program with %d indirections unexpectedly "
218 "met native limits.\n", count
);
219 print_program_info(prog
);
228 * Test that we can emit a whole load of samples as long as the indirection
231 GLboolean
test_temporary_source_indirections(void)
233 GLboolean pass
= GL_TRUE
;
236 GLint indirections_limit
, use_limit
;
239 indirections_limit
= get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
);
241 use_limit
= MIN2(indirections_limit
, 1024);
243 count
= use_limit
- 1;
244 printf("testing program with %d indirections from temporary sources\n",
246 prog
= gen_temporary_source_indirections(count
, &progname
);
248 if (!get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
249 printf("Program with %d indirections unexpectedly "
250 "exceeded native limits.\n", count
);
251 print_program_info(prog
);
257 count
= use_limit
+ 1;
258 printf("testing program with %d indirections from temporary sources\n",
260 prog
= gen_temporary_source_indirections(count
, &progname
);
261 if (prog
!= NULL
&& count
> indirections_limit
) {
262 if (get_program_i(GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB
)) {
263 printf("Program with %d indirections unexpectedly "
264 "met native limits.\n", count
);
265 print_program_info(prog
);
276 GLboolean pass
= GL_TRUE
;
278 pass
= test_temporary_dest_indirections() && pass
;
279 pass
= test_temporary_source_indirections() && pass
;
281 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
285 piglit_init(int argc
, char **argv
)
287 piglit_require_fragment_program();
289 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
291 printf("Maximum tex instructions: %d\n",
292 get_program_i(GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB
));
293 printf("Maximum native tex instructions: %d\n",
294 get_program_i(GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB
));
295 printf("Maximum tex indirections: %d\n",
296 get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
));
297 printf("Maximum native tex indirections: %d\n",
298 get_program_i(GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB
));
300 /* If the GL reports more than 10000 texture indirections, then we're probably
301 * running on hardware with no limitations - the driver just picked some
302 * arbitrary large number to report back. The test isn't meaningful, and
303 * the run time explodes with huge limits, so just skip it.
305 * For reference, Mesa and NVIDIA report 16384; AMD reports 2147483647.
306 * Pineview hardware (where this test is relevant) has a limit of 4.
308 if (get_program_i(GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB
) > 10000) {
309 printf("Skipping; the hardware doesn't appear to have real limits.\n");
310 piglit_report_result(PIGLIT_SKIP
);