Add more structure constructor tests.
[piglit/hramrach.git] / tests / shaders / glsl-max-varyings.c
blob538043155d29afe8536316c23fed700f4f351ae6
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.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)
47 GLuint shader;
48 unsigned i;
49 char code[1024], temp[1024];
51 code[0] = 0;
52 for (i = 0; i < num_varyings; i++) {
53 sprintf(temp, "varying vec4 v%d;\n", i);
54 strcat(code, temp);
57 sprintf(temp,
58 "attribute vec4 green;\n"
59 "attribute vec4 black;\n"
60 "void main()\n"
61 "{\n"
62 " gl_Position = (gl_ModelViewProjectionMatrix * \n"
63 " gl_Vertex);\n"
65 strcat(code, temp);
67 for (i = 0; i < num_varyings; i++) {
68 if (i == data_varying)
69 sprintf(temp, " v%d = green;\n", i);
70 else
71 sprintf(temp, " v%d = black;\n", i);
72 strcat(code, temp);
75 sprintf(temp,
76 "}\n"
78 strcat(code, temp);
80 shader = piglit_compile_shader_text(GL_VERTEX_SHADER, code);
81 /* printf("%s\n", code); */
83 return shader;
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
93 * verify.
95 static GLint get_fs(int num_varyings, int data_varying)
97 GLuint shader;
98 unsigned i;
99 char code[1024], temp[1024];
101 code[0] = 0;
102 for (i = 0; i < num_varyings; i++) {
103 sprintf(temp, "varying vec4 v%d;\n", i);
104 strcat(code, temp);
107 sprintf(temp,
108 "uniform float zero;\n"
109 "uniform float one;\n"
110 "void main()\n"
111 "{\n"
112 " vec4 val = vec4(0.0);\n"
114 strcat(code, temp);
116 for (i = 0; i < num_varyings; i++) {
117 if (i == data_varying)
118 sprintf(temp, " val += one * v%d;\n", i);
119 else
120 sprintf(temp, " val += zero * v%d;\n", i);
121 strcat(code, temp);
124 sprintf(temp,
125 " gl_FragColor = val;\n"
126 "}\n"
128 strcat(code, temp);
130 /* printf("%s\n", code); */
131 shader = piglit_compile_shader_text(GL_FRAGMENT_SHADER, code);
133 return shader;
136 static int
137 coord_from_index(int index)
139 return 2 + 12 * index;
142 static void
143 draw(int max_varyings)
145 int data_varying;
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),
156 green);
157 glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(float),
158 black);
159 glEnableVertexAttribArray(1);
160 glEnableVertexAttribArray(2);
162 for (data_varying = 0; data_varying < max_varyings; data_varying++) {
163 GLuint prog, vs, fs;
164 GLint loc;
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");
176 glLinkProgram(prog);
177 if (!piglit_link_check_status(prog))
178 piglit_report_result(PIGLIT_FAILURE);
180 glUseProgram(prog);
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),
193 10);
195 glDeleteShader(vs);
196 glDeleteShader(fs);
197 glDeleteProgram(prog);
201 enum piglit_result
202 piglit_display(void)
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;
220 warned = GL_TRUE;
223 glClearColor(0.5, 0.5, 0.5, 0.5);
224 glClear(GL_COLOR_BUFFER_BIT);
226 for (row = 0; row < max_varyings; row++) {
227 draw(row + 1);
230 for (row = 0; row < max_varyings; row++) {
231 for (col = 0; col <= row; col++) {
232 GLboolean ok;
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,
237 green);
238 if (!ok) {
239 printf(" Failure with %d vec4 varyings used "
240 "in varying index %d\n",
241 row + 1, col);
242 pass = GL_FALSE;
243 break;
248 glutSwapBuffers();
250 if (!pass)
251 return PIGLIT_FAILURE;
252 if (warned)
253 return PIGLIT_WARN;
254 else
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");