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 /* 1x1 rectangles with 1 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
= MAX_VARYING
;
45 config
.window_height
= MAX_VARYING
;
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 draw(int num_varyings
)
149 float vertex
[4][4] = { {0.0, 0.0, 0.0, 1.0},
150 {0.0, 0.0, 0.0, 1.0},
151 {0.0, 0.0, 0.0, 1.0},
152 {0.0, 0.0, 0.0, 1.0} };
153 float green
[4][4] = { {0.0, 1.0, 0.0, 0.0},
154 {0.0, 1.0, 0.0, 0.0},
155 {0.0, 1.0, 0.0, 0.0},
156 {0.0, 1.0, 0.0, 0.0} };
157 float red
[4][4] = { {1.0, 0.0, 0.0, 0.0},
158 {1.0, 0.0, 0.0, 0.0},
159 {1.0, 0.0, 0.0, 0.0},
160 {1.0, 0.0, 0.0, 0.0} };
162 glVertexAttribPointer(0, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
164 glVertexAttribPointer(1, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
166 glVertexAttribPointer(2, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
168 glEnableVertexAttribArray(0);
169 glEnableVertexAttribArray(1);
170 glEnableVertexAttribArray(2);
172 GLuint vs
= get_vs(num_varyings
);
173 GLuint fs
= get_fs(num_varyings
);
174 GLuint prog
= glCreateProgram();
175 glAttachShader(prog
, vs
);
176 glAttachShader(prog
, fs
);
178 glBindAttribLocation(prog
, 0, "vertex");
179 glBindAttribLocation(prog
, 1, "green");
180 glBindAttribLocation(prog
, 2, "red");
183 if (!piglit_link_check_status_quiet(prog
)) {
184 if (num_varyings
> max_varyings
) {
185 printf("Failed to link with %d out of %d "
187 num_varyings
, max_varyings
);
190 piglit_report_result(PIGLIT_FAIL
);
194 int data_varying_loc
= glGetUniformLocation(prog
, "data_varying");
195 int contribution_loc
= glGetUniformLocation(prog
, "contribution");
199 for (data_varying
= 0; data_varying
< num_varyings
; data_varying
++) {
202 glUniform1i(data_varying_loc
, data_varying
);
203 glUniform1f(contribution_loc
+ data_varying
, 1.0);
204 if (data_varying
> 0)
205 glUniform1f(contribution_loc
+ data_varying
- 1, 0.0);
208 y
= num_varyings
- 1;
211 vertex
[1][0] = x
+ 1;
214 vertex
[2][1] = y
+ 1;
215 vertex
[3][0] = x
+ 1;
216 vertex
[3][1] = y
+ 1;
217 glDrawArrays(GL_TRIANGLE_STRIP
, 0, 4);
222 glDeleteProgram(prog
);
230 GLint max_components
;
231 int test_varyings
, row
, col
;
232 GLboolean pass
= GL_TRUE
, warned
= GL_FALSE
;
233 bool drew
[MAX_VARYING
];
234 float readback_buffer
[MAX_VARYING
* MAX_VARYING
* 3] = {0};
236 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
238 glGetIntegerv(GL_MAX_VARYING_FLOATS
, &max_components
);
239 max_varyings
= max_components
/ 4;
241 printf("GL_MAX_VARYING_FLOATS = %i\n", max_components
);
243 test_varyings
= max_varyings
;
246 if (test_varyings
> MAX_VARYING
) {
247 printf("test not designed to handle >%d varying vec4s.\n"
248 "(implementation reports %d components)\n",
249 MAX_VARYING
, max_varyings
);
250 test_varyings
= MAX_VARYING
;
254 glClearColor(0.5, 0.5, 0.5, 0.5);
255 glClear(GL_COLOR_BUFFER_BIT
);
257 for (row
= 0; row
< test_varyings
; row
++) {
258 drew
[row
] = draw(row
+ 1);
261 glReadPixels(0, 0, test_varyings
, test_varyings
, GL_RGB
, GL_FLOAT
, readback_buffer
);
263 for (row
= 0; row
< test_varyings
; row
++) {
267 for (col
= 0; col
<= row
; col
++) {
269 float green
[3] = {0.0, 1.0, 0.0};
270 int pixel_id
= 3 * (row
* test_varyings
+ col
);
272 ok
= readback_buffer
[pixel_id
+ 0] == green
[0] &&
273 readback_buffer
[pixel_id
+ 1] == green
[1] &&
274 readback_buffer
[pixel_id
+ 2] == green
[2];
277 printf(" Failure with %d vec4 varyings used "
278 "in varying index %d\n",
280 printf(" Expected %f %f %f\n Got %f %f %f\n\n",
281 green
[0], green
[1], green
[2],
282 readback_buffer
[pixel_id
+ 0],
283 readback_buffer
[pixel_id
+ 1],
284 readback_buffer
[pixel_id
+ 2]);
291 piglit_present_results();
301 void piglit_init(int argc
, char **argv
)
305 piglit_require_gl_version(20);
307 for (i
= 0; i
< argc
; i
++) {
308 if (strcmp(argv
[i
], "--exceed-limits") == 0)
309 exceed_limits
= true;
312 printf("Vertical axis: Increasing numbers of varyings.\n");
313 printf("Horizontal axis: Which of the varyings contains the color.\n");