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.h"
36 #define MAX_VARYING 32
38 /* 10x10 rectangles with 2 pixels of pad. Deal with up to 32 varyings. */
39 int piglit_width
= (2 + MAX_VARYING
* 12), piglit_height
= (2 + MAX_VARYING
* 12);
40 int piglit_window_mode
= GLUT_RGB
| GLUT_DOUBLE
;
42 /* Generate a VS that writes to num_varyings vec4s, and put
43 * interesting data in data_varying with 0.0 everywhere else.
45 static GLint
get_vs(int num_varyings
, int data_varying
)
49 char code
[1024], temp
[1024];
52 for (i
= 0; i
< num_varyings
; i
++) {
53 sprintf(temp
, "varying vec4 v%d;\n", i
);
58 "attribute vec4 green;\n"
59 "attribute vec4 black;\n"
62 " gl_Position = (gl_ModelViewProjectionMatrix * \n"
67 for (i
= 0; i
< num_varyings
; i
++) {
68 if (i
== data_varying
)
69 sprintf(temp
, " v%d = green;\n", i
);
71 sprintf(temp
, " v%d = black;\n", i
);
80 shader
= piglit_compile_shader_text(GL_VERTEX_SHADER
, code
);
81 /* printf("%s\n", code); */
86 /* Generate a FS that does operations on num_varyings, yet makes only
87 * data_varying contribute to the output.
89 * We could make a single FS per num_varyings that did this by using a
90 * uniform for data_varying and some multiplication by comparisons
91 * (see glsl-routing for an example), but since we're linking a new
92 * shader each time anyway, this produces a simpler FS to read and
95 static GLint
get_fs(int num_varyings
, int data_varying
)
99 char code
[1024], temp
[1024];
102 for (i
= 0; i
< num_varyings
; i
++) {
103 sprintf(temp
, "varying vec4 v%d;\n", i
);
108 "uniform float zero;\n"
109 "uniform float one;\n"
112 " vec4 val = vec4(0.0);\n"
116 for (i
= 0; i
< num_varyings
; i
++) {
117 if (i
== data_varying
)
118 sprintf(temp
, " val += one * v%d;\n", i
);
120 sprintf(temp
, " val += zero * v%d;\n", i
);
125 " gl_FragColor = val;\n"
130 /* printf("%s\n", code); */
131 shader
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, code
);
137 coord_from_index(int index
)
139 return 2 + 12 * index
;
143 draw(int max_varyings
)
146 float green
[4][4] = { {0.0, 1.0, 0.0, 0.0},
147 {0.0, 1.0, 0.0, 0.0},
148 {0.0, 1.0, 0.0, 0.0},
149 {0.0, 1.0, 0.0, 0.0} };
150 float black
[4][4] = { {0.0, 0.0, 0.0, 0.0},
151 {0.0, 0.0, 0.0, 0.0},
152 {0.0, 0.0, 0.0, 0.0},
153 {0.0, 0.0, 0.0, 0.0} };
155 glVertexAttribPointer(1, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
157 glVertexAttribPointer(2, 4, GL_FLOAT
, GL_FALSE
, 4 * sizeof(float),
159 glEnableVertexAttribArray(1);
160 glEnableVertexAttribArray(2);
162 for (data_varying
= 0; data_varying
< max_varyings
; data_varying
++) {
166 vs
= get_vs(max_varyings
, data_varying
);
167 fs
= get_fs(max_varyings
, data_varying
);
169 prog
= glCreateProgram();
170 glAttachShader(prog
, vs
);
171 glAttachShader(prog
, fs
);
173 glBindAttribLocation(prog
, 1, "green");
174 glBindAttribLocation(prog
, 2, "black");
177 if (!piglit_link_check_status(prog
))
178 piglit_report_result(PIGLIT_FAILURE
);
182 loc
= glGetUniformLocation(prog
, "zero");
183 if (loc
!= -1) /* not used for max_varyings == 1 */
184 glUniform1f(loc
, 0.0);
186 loc
= glGetUniformLocation(prog
, "one");
187 assert(loc
!= -1); /* should always be used */
188 glUniform1f(loc
, 1.0);
190 piglit_draw_rect(coord_from_index(data_varying
),
191 coord_from_index(max_varyings
- 1),
197 glDeleteProgram(prog
);
204 GLint max_components
;
205 int max_varyings
, row
, col
;
206 GLboolean pass
= GL_TRUE
, warned
= GL_FALSE
;
208 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
210 glGetIntegerv(GL_MAX_VARYING_FLOATS
, &max_components
);
211 max_varyings
= max_components
/ 4;
213 printf("GL_MAX_VARYING_FLOATS = %i\n", max_components
);
215 if (max_varyings
> MAX_VARYING
) {
216 printf("test not designed to handle >%d varying vec4s.\n"
217 "(implementation reports %d components)\n",
218 max_components
, MAX_VARYING
);
219 max_varyings
= MAX_VARYING
;
223 glClearColor(0.5, 0.5, 0.5, 0.5);
224 glClear(GL_COLOR_BUFFER_BIT
);
226 for (row
= 0; row
< max_varyings
; row
++) {
230 for (row
= 0; row
< max_varyings
; row
++) {
231 for (col
= 0; col
<= row
; col
++) {
233 float green
[3] = {0.0, 1.0, 0.0};
235 ok
= piglit_probe_pixel_rgb(coord_from_index(col
) + 5,
236 coord_from_index(row
) + 5,
239 printf(" Failure with %d vec4 varyings used "
240 "in varying index %d\n",
251 return PIGLIT_FAILURE
;
255 return PIGLIT_SUCCESS
;
258 void piglit_init(int argc
, char **argv
)
260 if (!GLEW_VERSION_2_0
) {
261 printf("Requires OpenGL 2.0\n");
262 piglit_report_result(PIGLIT_SKIP
);
265 printf("Vertical axis: Increasing numbers of varyings.\n");
266 printf("Horizontal axis: Which of the varyings contains the color.\n");