framework/replay: recently introduced HTML tags should be in innerHTML
[piglit.git] / tests / shaders / glsl-max-varyings.c
blob83310cb15599f02531b43aa4c02679d94580e50a
1 /*
2 * Copyright © 2010 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 /** @file glsl-max-varyings.c
30 * Tests whether each varying can be used at all numbers of varyings up to
31 * GL_MAX_VARYING_FLOATS / 4.
34 #include "piglit-util-gl.h"
36 #define MAX_VARYING 256
38 /* 2x2 rectangles with 2 pixels of pad. Deal with up to 256 varyings. */
40 PIGLIT_GL_TEST_CONFIG_BEGIN
42 config.supports_gl_compat_version = 10;
44 config.window_width = (2+MAX_VARYING*4);
45 config.window_height = (2+MAX_VARYING*4);
46 config.window_visual = PIGLIT_GL_VISUAL_RGB | PIGLIT_GL_VISUAL_DOUBLE;
48 PIGLIT_GL_TEST_CONFIG_END
50 static bool exceed_limits = false;
51 static int max_varyings;
53 /* Generate a VS that writes to num_varyings vec4s, and put
54 * interesting data in data_varying with 0.0 everywhere else.
56 static GLint get_vs(int num_varyings)
58 GLuint shader;
59 unsigned i;
60 char *code = malloc(4096);
61 char temp[2048];
63 code[0] = 0;
64 for (i = 0; i < num_varyings; i++) {
65 sprintf(temp, "varying vec4 v%d;\n", i);
66 strcat(code, temp);
69 sprintf(temp,
70 "attribute vec4 vertex;\n"
71 "attribute vec4 green;\n"
72 "attribute vec4 red;\n"
73 "uniform int data_varying;\n"
74 "void main()\n"
75 "{\n"
76 " gl_Position = (gl_ModelViewProjectionMatrix * \n"
77 " vertex);\n");
78 strcat(code, temp);
80 for (i = 0; i < num_varyings; i++) {
81 sprintf(temp, " v%d = (data_varying == %d) ? green : red;\n", i, i);
82 strcat(code, temp);
85 sprintf(temp,
86 "}\n"
88 strcat(code, temp);
90 shader = piglit_compile_shader_text(GL_VERTEX_SHADER, code);
91 /* printf("%s\n", code); */
93 free(code);
94 return shader;
97 /* Generate a FS that does operations on num_varyings, yet makes only
98 * data_varying contribute to the output.
100 * We could make a single FS per num_varyings that did this by using a
101 * uniform for data_varying and some multiplication by comparisons
102 * (see glsl-routing for an example), but since we're linking a new
103 * shader each time anyway, this produces a simpler FS to read and
104 * verify.
106 static GLint get_fs(int num_varyings)
108 GLuint shader;
109 unsigned i;
110 char *code = malloc(8192);
111 char temp[2048];
113 code[0] = 0;
114 for (i = 0; i < num_varyings; i++) {
115 sprintf(temp, "varying vec4 v%d;\n", i);
116 strcat(code, temp);
119 sprintf(temp,
120 "uniform float contribution[%d];\n"
121 "void main()\n"
122 "{\n"
123 " vec4 val = vec4(0.0);\n",
124 num_varyings);
125 strcat(code, temp);
127 for (i = 0; i < num_varyings; i++) {
128 sprintf(temp, " val += contribution[%d] * v%d;\n", i, i);
129 strcat(code, temp);
132 sprintf(temp,
133 " gl_FragColor = val;\n"
134 "}\n"
136 strcat(code, temp);
138 /* printf("%s\n", code); */
139 shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, code);
141 free(code);
142 return shader;
145 static int
146 coord_from_index(int index)
148 return 2 + 4 * index;
151 static bool
152 draw(int num_varyings)
154 int data_varying;
155 float vertex[4][4] = { {0.0, 0.0, 0.0, 1.0},
156 {0.0, 0.0, 0.0, 1.0},
157 {0.0, 0.0, 0.0, 1.0},
158 {0.0, 0.0, 0.0, 1.0} };
159 float green[4][4] = { {0.0, 1.0, 0.0, 0.0},
160 {0.0, 1.0, 0.0, 0.0},
161 {0.0, 1.0, 0.0, 0.0},
162 {0.0, 1.0, 0.0, 0.0} };
163 float red[4][4] = { {1.0, 0.0, 0.0, 0.0},
164 {1.0, 0.0, 0.0, 0.0},
165 {1.0, 0.0, 0.0, 0.0},
166 {1.0, 0.0, 0.0, 0.0} };
168 glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
169 vertex);
170 glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
171 green);
172 glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
173 red);
174 glEnableVertexAttribArray(0);
175 glEnableVertexAttribArray(1);
176 glEnableVertexAttribArray(2);
178 GLuint vs = get_vs(num_varyings);
179 GLuint fs = get_fs(num_varyings);
180 GLuint prog = glCreateProgram();
181 glAttachShader(prog, vs);
182 glAttachShader(prog, fs);
184 glBindAttribLocation(prog, 0, "vertex");
185 glBindAttribLocation(prog, 1, "green");
186 glBindAttribLocation(prog, 2, "red");
188 glLinkProgram(prog);
189 if (!piglit_link_check_status_quiet(prog)) {
190 if (num_varyings > max_varyings) {
191 printf("Failed to link with %d out of %d "
192 "varyings used\n",
193 num_varyings, max_varyings);
194 return false;
195 } else {
196 piglit_report_result(PIGLIT_FAIL);
200 int data_varying_loc = glGetUniformLocation(prog, "data_varying");
201 int contribution_loc = glGetUniformLocation(prog, "contribution");
203 glUseProgram(prog);
205 for (data_varying = 0; data_varying < num_varyings; data_varying++) {
206 float x, y;
208 glUniform1i(data_varying_loc, data_varying);
209 glUniform1f(contribution_loc + data_varying, 1.0);
210 if (data_varying > 0)
211 glUniform1f(contribution_loc + data_varying - 1, 0.0);
213 x = coord_from_index(data_varying);
214 y = coord_from_index(num_varyings - 1);
215 vertex[0][0] = x;
216 vertex[0][1] = y;
217 vertex[1][0] = x + 2;
218 vertex[1][1] = y;
219 vertex[2][0] = x;
220 vertex[2][1] = y + 2;
221 vertex[3][0] = x + 2;
222 vertex[3][1] = y + 2;
223 glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
226 glDeleteShader(vs);
227 glDeleteShader(fs);
228 glDeleteProgram(prog);
230 return true;
233 enum piglit_result
234 piglit_display(void)
236 GLint max_components;
237 int test_varyings, row, col;
238 GLboolean pass = GL_TRUE, warned = GL_FALSE;
239 bool drew[MAX_VARYING];
241 piglit_ortho_projection(piglit_width, piglit_height, GL_FALSE);
243 glGetIntegerv(GL_MAX_VARYING_FLOATS, &max_components);
244 max_varyings = max_components / 4;
246 printf("GL_MAX_VARYING_FLOATS = %i\n", max_components);
248 test_varyings = max_varyings;
249 if (exceed_limits)
250 test_varyings++;
251 if (test_varyings > MAX_VARYING) {
252 printf("test not designed to handle >%d varying vec4s.\n"
253 "(implementation reports %d components)\n",
254 MAX_VARYING, max_varyings);
255 test_varyings = MAX_VARYING;
256 warned = GL_TRUE;
259 glClearColor(0.5, 0.5, 0.5, 0.5);
260 glClear(GL_COLOR_BUFFER_BIT);
262 for (row = 0; row < test_varyings; row++) {
263 drew[row] = draw(row + 1);
266 for (row = 0; row < test_varyings; row++) {
267 if (!drew[row])
268 continue;
270 for (col = 0; col <= row; col++) {
271 GLboolean ok;
272 float green[3] = {0.0, 1.0, 0.0};
274 ok = piglit_probe_rect_rgb(coord_from_index(col),
275 coord_from_index(row),
276 2, 2,
277 green);
278 if (!ok) {
279 printf(" Failure with %d vec4 varyings used "
280 "in varying index %d\n",
281 row + 1, col);
282 pass = GL_FALSE;
283 break;
288 piglit_present_results();
290 if (!pass)
291 return PIGLIT_FAIL;
292 if (warned)
293 return PIGLIT_WARN;
294 else
295 return PIGLIT_PASS;
298 void piglit_init(int argc, char **argv)
300 int i;
302 piglit_require_gl_version(20);
304 for (i = 0; i < argc; i++) {
305 if (strcmp(argv[i], "--exceed-limits") == 0)
306 exceed_limits = true;
309 printf("Vertical axis: Increasing numbers of varyings.\n");
310 printf("Horizontal axis: Which of the varyings contains the color.\n");