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
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 /** @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
)
60 char *code
= malloc(4096);
64 for (i
= 0; i
< num_varyings
; i
++) {
65 sprintf(temp
, "varying vec4 v%d;\n", i
);
70 "attribute vec4 vertex;\n"
71 "attribute vec4 green;\n"
72 "attribute vec4 red;\n"
73 "uniform int data_varying;\n"
76 " gl_Position = (gl_ModelViewProjectionMatrix * \n"
80 for (i
= 0; i
< num_varyings
; i
++) {
81 sprintf(temp
, " v%d = (data_varying == %d) ? green : red;\n", i
, i
);
90 shader
= piglit_compile_shader_text(GL_VERTEX_SHADER
, code
);
91 /* printf("%s\n", code); */
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
106 static GLint
get_fs(int num_varyings
)
110 char *code
= malloc(8192);
114 for (i
= 0; i
< num_varyings
; i
++) {
115 sprintf(temp
, "varying vec4 v%d;\n", i
);
120 "uniform float contribution[%d];\n"
123 " vec4 val = vec4(0.0);\n",
127 for (i
= 0; i
< num_varyings
; i
++) {
128 sprintf(temp
, " val += contribution[%d] * v%d;\n", i
, i
);
133 " gl_FragColor = val;\n"
138 /* printf("%s\n", code); */
139 shader
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, code
);
146 coord_from_index(int index
)
148 return 2 + 4 * index
;
152 draw(int num_varyings
)
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),
170 glVertexAttribPointer(1, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
172 glVertexAttribPointer(2, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
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");
189 if (!piglit_link_check_status_quiet(prog
)) {
190 if (num_varyings
> max_varyings
) {
191 printf("Failed to link with %d out of %d "
193 num_varyings
, max_varyings
);
196 piglit_report_result(PIGLIT_FAIL
);
200 int data_varying_loc
= glGetUniformLocation(prog
, "data_varying");
201 int contribution_loc
= glGetUniformLocation(prog
, "contribution");
205 for (data_varying
= 0; data_varying
< num_varyings
; data_varying
++) {
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);
217 vertex
[1][0] = x
+ 2;
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);
228 glDeleteProgram(prog
);
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
;
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
;
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
++) {
270 for (col
= 0; col
<= row
; col
++) {
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
),
279 printf(" Failure with %d vec4 varyings used "
280 "in varying index %d\n",
288 piglit_present_results();
298 void piglit_init(int argc
, char **argv
)
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");