2 * Copyright (c) 2009 Nicolai Hähnle
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 * Nicolai Hähnle <nhaehnle@gmail.com>
30 * Test certain type of very long fragment programs.
37 #include "piglit-util-gl.h"
39 PIGLIT_GL_TEST_CONFIG_BEGIN
41 config
.supports_gl_compat_version
= 10;
43 config
.window_visual
= PIGLIT_GL_VISUAL_RGBA
;
45 PIGLIT_GL_TEST_CONFIG_END
47 int max_alu_instructions
;
49 static const char program_Head
[] =
55 static const char program_Step
[] = "ADD %s, r.wxyz, { %f, %f, %f, %f };\n";
57 static const char program_Tail
[] =
60 static const char program_Output
[] = "result.color";
62 static void step_add(unsigned int i
, float * add
)
64 unsigned int rotate
= i
% 4;
65 add
[(0 + rotate
) % 4] = ((i
+1) % 16) ? 0.0625 : -1.0+0.0625;
66 add
[(1 + rotate
) % 4] = ((i
+1) % 16) ? 0.0 : (((i
+1) % 256) ? 0.0625 : -1.0+0.0625);
67 add
[(2 + rotate
) % 4] = ((i
+1) % 256) ? 0.0 : (((i
+1) % 4096) ? 0.0625 : -1.0+0.0625);
68 add
[(3 + rotate
) % 4] = ((i
+1) % 4096) ? 0.0 : 0.0625;
71 static enum piglit_result
test(unsigned int alu_depth
)
73 char * program_text
= malloc(sizeof(program_Head
) +
74 2*alu_depth
*sizeof(program_Step
) +
75 sizeof(program_Tail
) +
76 sizeof(program_Output
));
79 GLuint program_object
;
81 float expected
[4] = { 0.0, 0.0, 0.0, 0.0 };
83 /* Note: This test makes sense up to alu_depth of 65536,
84 * but current drivers are not exactly efficient with such
85 * long programs, and if 16k works, then 64k will probably
88 if (!alu_depth
|| alu_depth
> 16384 || alu_depth
+ 1 > max_alu_instructions
) {
93 printf("Testing: alu_depth = %u\n", alu_depth
);
95 memcpy(program_text
, program_Head
, sizeof(program_Head
)-1);
96 buildp
= program_text
+ sizeof(program_Head
)-1;
98 for(i
= 0; i
< alu_depth
; ++i
) {
102 length
= snprintf(buf
, sizeof(buf
),
103 program_Step
, i
== (alu_depth
-1) ? program_Output
: "r",
104 add
[0], add
[1], add
[2], add
[3]);
105 memcpy(buildp
, buf
, length
);
108 memcpy(buildp
, program_Tail
, sizeof(program_Tail
));
110 // printf(program_text);
112 program_object
= piglit_compile_program(GL_FRAGMENT_PROGRAM_ARB
, program_text
);
116 glEnable(GL_FRAGMENT_PROGRAM_ARB
);
117 glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB
, program_object
);
119 piglit_draw_rect(0, 0, 32, 32);
121 glDisable(GL_FRAGMENT_PROGRAM_ARB
);
122 glDeleteProgramsARB(1, &program_object
);
124 expected
[0] = (alu_depth
% 16) * 0.0625;
125 expected
[1] = ((alu_depth
/16) % 16) * 0.0625;
126 expected
[2] = ((alu_depth
/256) % 16) * 0.0625;
127 expected
[3] = (alu_depth
/4096) * 0.0625;
128 for(i
= 0; i
< ((alu_depth
+3) % 4); ++i
) {
129 float tmp
= expected
[3];
130 expected
[3] = expected
[2];
131 expected
[2] = expected
[1];
132 expected
[1] = expected
[0];
135 if (expected
[0] > 1.0)
137 if (expected
[1] > 1.0)
139 if (expected
[2] > 1.0)
141 if (expected
[3] > 1.0)
144 if (!piglit_probe_pixel_rgba(16, 16, expected
)) {
145 fprintf(stderr
, "Failure in alu_depth = %i\n", alu_depth
);
152 enum piglit_result
piglit_display(void)
154 enum piglit_result result
;
155 unsigned int alu_depth
;
157 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
158 glClear(GL_COLOR_BUFFER_BIT
);
162 result
= test(alu_depth
);
163 if (result
== PIGLIT_SKIP
)
165 if (result
!= PIGLIT_PASS
)
171 /* Not quite powers of two to avoid aliasing */
172 alu_depth
= (alu_depth
* 2) - 5;
180 void piglit_init(int argc
, char ** argv
)
182 piglit_require_fragment_program();
184 glGetProgramivARB(GL_FRAGMENT_PROGRAM_ARB
,
185 GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB
,
186 &max_alu_instructions
);
188 printf("Max (native) ALU instructions: %i\n",
189 max_alu_instructions
);