Add more structure constructor tests.
[piglit/hramrach.git] / tests / shaders / fp-indirections.c
blob9df19db9b1f298de1f2507d63855e22c3e00539f
1 /*
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
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.
23 * Authors:
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)
35 GLint val;
37 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB, pname, &val);
39 return val;
42 /**
43 * Generate a program that samples the texture into the same temporary over
44 * and over..
46 * This should excersize case (2) of question (24) of the ARB_fragment_program
47 * spec.
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
51 * for now.
53 static char *gen_temporary_dest_indirections(int sample_count,
54 GLuint *progname)
56 char *prog;
57 char *pre =
58 "!!ARBfp1.0\n"
59 "TEMP val, sample;\n"
60 "MOV val, fragment.color;\n";
61 char *sample =
62 "TEX sample, fragment.color, texture[0], 2D;\n"
63 "MUL val, val, sample;\n";
64 char *post =
65 "MOV result.color, val;\n"
66 "END";
67 int i, instr_count;
69 prog = malloc(strlen(pre) + strlen(sample) * sample_count +
70 strlen(post) + 1);
72 if (prog == 0) {
73 printf("malloc failed.\n");
74 piglit_report_result(PIGLIT_FAILURE);
75 exit(1);
78 sprintf(prog, "%s", pre);
79 for (i = 0; i < sample_count; i++)
80 strcat(prog, sample);
81 strcat(prog, post);
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);
89 free(prog);
90 return NULL;
93 *progname = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB, prog);
94 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *progname);
96 return prog;
99 /**
100 * Generate a program that samples two textures into a pair of temporaries
101 * over and over.
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
108 * for now.
110 static char *gen_temporary_source_indirections(int sample_count,
111 GLuint *progname)
113 char *prog;
114 char *pre =
115 "!!ARBfp1.0\n"
116 "TEMP val, val2, sample, sample2;\n"
117 "MOV val, fragment.color;\n"
118 "MOV val2, fragment.color;\n";
119 char *sample =
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";
124 char *post =
125 "MOV result.color, val;\n"
126 "END";
127 int i, instr_count;
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);
135 return NULL;
138 prog = malloc(strlen(pre) + strlen(sample) * (sample_count - 1) +
139 strlen(post) + 1);
141 if (prog == 0) {
142 printf("malloc failed.\n");
143 piglit_report_result(PIGLIT_FAILURE);
144 exit(1);
147 sprintf(prog, "%s", pre);
148 for (i = 0; i < sample_count - 1; i++)
149 strcat(prog, sample);
150 strcat(prog, post);
152 *progname = piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB, prog);
153 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, *progname);
155 return prog;
158 void
159 print_program_info(char *program)
161 printf("Program:\n");
162 printf("%s", program);
163 printf("\n");
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));
173 printf("\n");
177 * Test that we can emit a whole load of samples as long as the indirection
178 * count is low.
180 GLboolean test_temporary_dest_indirections(void)
182 GLboolean pass = GL_TRUE;
183 GLuint progname;
184 char *prog;
185 GLint indirections_limit;
186 GLint count;
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",
192 count);
193 prog = gen_temporary_dest_indirections(count, &progname);
194 if (prog != NULL) {
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);
199 pass = GL_FALSE;
201 free(prog);
204 count = indirections_limit + 1;
205 printf("testing program with %d indirections from temporary dests\n",
206 count);
207 prog = gen_temporary_dest_indirections(count, &progname);
208 if (prog != NULL) {
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);
214 free(prog);
217 return pass;
221 * Test that we can emit a whole load of samples as long as the indirection
222 * count is low.
224 GLboolean test_temporary_source_indirections(void)
226 GLboolean pass = GL_TRUE;
227 GLuint progname;
228 char *prog;
229 GLint indirections_limit;
230 GLint count;
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",
236 count);
237 prog = gen_temporary_source_indirections(count, &progname);
238 if (prog != NULL) {
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);
243 pass = GL_FALSE;
245 free(prog);
248 count = indirections_limit + 1;
249 printf("testing program with %d indirections from temporary sources\n",
250 count);
251 prog = gen_temporary_source_indirections(count, &progname);
252 if (prog != NULL) {
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);
258 free(prog);
261 return pass;
264 enum piglit_result
265 piglit_display(void)
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;
275 void
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));