2 * Copyright © 2009 Marek Olšák (maraeo@gmail.com)
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 * Marek Olšák <mareao@gmail.com>
28 /** @file glsl-routing.c
30 * Tests whether streams are routed in this chain correctly:
31 * vertex attributes -> vertex shader -> fragment shader -> output
32 * with emphasis on linking vertex and fragment shaders
35 #include "piglit-util-gl.h"
37 PIGLIT_GL_TEST_CONFIG_BEGIN
39 config
.supports_gl_compat_version
= 10;
41 config
.window_width
= 260;
42 config
.window_height
= 365;
43 config
.window_visual
= PIGLIT_GL_VISUAL_RGB
| PIGLIT_GL_VISUAL_DOUBLE
;
44 config
.khr_no_error_support
= PIGLIT_NO_ERRORS
;
46 PIGLIT_GL_TEST_CONFIG_END
50 #define ATTRIBS (COLORS+TEXCOORDS)
53 static char vs_code
[] =
56 " gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\n"
57 "AA gl_FrontColor = gl_Color;\n"
58 "BB gl_FrontSecondaryColor = gl_SecondaryColor;\n"
59 "CC gl_TexCoord[0] = gl_MultiTexCoord0;\n"
60 "DD gl_TexCoord[1] = gl_MultiTexCoord1;\n"
61 "EE gl_TexCoord[2] = gl_MultiTexCoord2;\n"
62 "FF gl_TexCoord[3] = gl_MultiTexCoord3;\n"
63 "GG gl_TexCoord[4] = gl_MultiTexCoord4;\n"
64 "HH gl_TexCoord[5] = gl_MultiTexCoord5;\n"
67 static char fs_code
[] =
68 "uniform float index;\n"
69 "bool eq(float a, float b)\n"
71 " return abs(a - b) < 0.01;\n"
75 " vec4 r = vec4(0.0);\n"
77 "AA if (eq(index, float(i))) r += gl_Color;\n"
79 "BB if (eq(index, float(i))) r += gl_SecondaryColor;\n"
81 "CC if (eq(index, float(i))) r += gl_TexCoord[0];\n"
83 "DD if (eq(index, float(i))) r += gl_TexCoord[1];\n"
85 "EE if (eq(index, float(i))) r += gl_TexCoord[2];\n"
87 "FF if (eq(index, float(i))) r += gl_TexCoord[3];\n"
89 "GG if (eq(index, float(i))) r += gl_TexCoord[4];\n"
91 "HH if (eq(index, float(i))) r += gl_TexCoord[5];\n"
92 " gl_FragColor = r;\n"
95 static GLint
setup_shaders(unsigned vsbitmask
, unsigned fsbitmask
)
99 char fscode
[1024], vscode
[1024], pattern
[3] = {'A', 'A', '\0'};
102 memcpy(vscode
, vs_code
, strlen(vs_code
)+1);
103 memcpy(fscode
, fs_code
, strlen(fs_code
)+1);
105 for (i
= 0; i
< ATTRIBS
; i
++) {
106 ptr
= strstr(vscode
, pattern
);
109 if ((1 << i
) & vsbitmask
) {
112 memcpy(ptr
, "//", 2);
115 ptr
= strstr(fscode
, pattern
);
118 if ((1 << i
) & fsbitmask
) {
121 memcpy(ptr
, "//", 2);
128 vs
= piglit_compile_shader_text(GL_VERTEX_SHADER
, vscode
);
129 fs
= piglit_compile_shader_text(GL_FRAGMENT_SHADER
, fscode
);
130 prog
= piglit_link_simple_program(vs
, fs
);
136 static void draw_rect(float posX
, float posY
, int attribIndex
,
137 float attrib
[ATTRIBS
][16])
142 posX
+BOX_SIZE
, posY
+BOX_SIZE
,
147 glEnableClientState(GL_VERTEX_ARRAY
);
148 glVertexPointer(2, GL_FLOAT
, 0, pos
);
151 glEnableClientState(GL_COLOR_ARRAY
);
152 glColorPointer(4, GL_FLOAT
, 0, &attrib
[0][0]);
155 glEnableClientState(GL_SECONDARY_COLOR_ARRAY
);
156 glSecondaryColorPointer(3, GL_FLOAT
, 4*sizeof(float), &attrib
[1][0]);
159 for (i
= 0; i
< TEXCOORDS
; i
++) {
160 glClientActiveTexture(GL_TEXTURE0
+ i
);
161 glEnableClientState(GL_TEXTURE_COORD_ARRAY
);
162 glTexCoordPointer(4, GL_FLOAT
, 0, &attrib
[COLORS
+i
][0]);
165 glDrawArrays(GL_QUADS
, 0, 4);
167 glDisableClientState(GL_VERTEX_ARRAY
);
169 glDisableClientState(GL_COLOR_ARRAY
);
172 glDisableClientState(GL_SECONDARY_COLOR_ARRAY
);
174 for (i
= 0; i
< TEXCOORDS
; i
++) {
175 glClientActiveTexture(GL_TEXTURE0
+ i
);
176 glDisableClientState(GL_TEXTURE_COORD_ARRAY
);
178 glClientActiveTexture(GL_TEXTURE0
);
181 static GLboolean
test(unsigned vsbitmask
, unsigned fsbitmask
, int line
)
183 GLint prog
, location
;
184 GLboolean pass
= GL_TRUE
;
186 float input
[4*ATTRIBS
] = {
196 float attrib
[ATTRIBS
][16];
197 float height
= line
* 30;
199 prog
= setup_shaders(vsbitmask
, fsbitmask
);
200 location
= glGetUniformLocation(prog
, "index");
202 for (i
= 0; i
< ATTRIBS
; i
++) {
203 for (j
= 0; j
< 16; j
++) {
204 attrib
[i
][j
] = input
[i
*4+(j
%4)];
208 for (i
= 0; i
< ATTRIBS
; i
++) {
209 if (((1 << i
) & vsbitmask
) && ((1 << i
) & fsbitmask
)) {
211 glUniform1f(location
, j
);
212 draw_rect(5 + (i
*(BOX_SIZE
+5)) % 240, 5 + height
, i
, attrib
);
215 if (!piglit_check_gl_error(GL_NO_ERROR
))
216 piglit_report_result(PIGLIT_FAIL
);
218 for (i
= 0; i
< ATTRIBS
; i
++) {
219 if (((1 << i
) & vsbitmask
) && ((1 << i
) & fsbitmask
)) {
220 pass
= piglit_probe_pixel_rgb(7 + (i
*(BOX_SIZE
+5)), 7 + height
, &input
[i
*4]) && pass
;
236 static void printconf(unsigned b
)
238 printf("%s %s %s %s %s %s %s %s",
239 (1 & b
) ? "C0" : "--",
240 (2 & b
) ? "C1" : "--",
241 (4 & b
) ? "T0" : "--",
242 (8 & b
) ? "T1" : "--",
243 (16 & b
) ? "T2" : "--",
244 (32 & b
) ? "T3" : "--",
245 (64 & b
) ? "T4" : "--",
246 (128 & b
) ? "T5" : "--");
252 GLboolean pass
= GL_TRUE
;
254 static unsigned conf
[][2] = {
255 // All VS outputs, some FS inputs
257 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
,
258 C0
| T0
| T2
| T4
| T5
261 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
,
265 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
,
266 C0
| C1
| T2
| T4
| T5
269 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
,
272 // Some VS outputs, all FS inputs
274 C0
| T0
| T2
| T4
| T5
,
275 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
279 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
283 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
287 C0
| C1
| T0
| T1
| T2
| T3
| T4
| T5
289 // Some VS outputs, some FS inputs
291 C0
| T0
| T2
| T4
| T5
,
292 C0
| C1
| T0
| T1
| T4
295 C0
| C1
| T1
| T4
| T5
,
296 C1
| T1
| T2
| T3
| T4
299 C1
| T0
| T2
| T3
| T5
,
300 C1
| T1
| T2
| T3
| T4
| T5
303 C0
| C1
| T0
| T2
| T3
| T4
| T5
,
308 glClearColor(0.5, 0.5, 0.5, 0.5);
309 glClear(GL_COLOR_BUFFER_BIT
);
311 for (i
= 0; i
< sizeof(conf
) / sizeof(*conf
); i
++) {
312 printf("\nTest: VS(");
313 printconf(conf
[i
][0]);
315 printconf(conf
[i
][1]);
318 pass
= test(conf
[i
][0], conf
[i
][1], i
) && pass
;
321 piglit_present_results();
323 return pass
? PIGLIT_PASS
: PIGLIT_FAIL
;
326 void piglit_init(int argc
, char **argv
)
328 piglit_ortho_projection(piglit_width
, piglit_height
, GL_FALSE
);
330 piglit_require_gl_version(20);