2 * Copyright © 2013 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
21 * DEALINGS IN THE SOFTWARE.
26 * Test that any desktop GLSL version may be linked with any other
27 * desktop GLSL version.
29 * From the GLSL 4.30 spec, section 3.3 (Preprocessor):
31 * "Shaders for the core or compatibility profiles that declare
32 * different versions can be linked together."
34 * This is a deliberate relaxation of the cross-version linking rules
35 * from previous versions of the GLSL spec (which prohibited some
36 * combinations of GLSL versions from being linked together). It was
37 * made because existing implementations didn't follow the old
38 * cross-version linking rules (see Khronos bug 8463). So it seems
39 * reasonable to expect all implementations to follow the new relaxed
42 * This test can be run in the following ways:
44 * - "interstage" checks that a vertex shader of one version can be
45 * linked with a fragment shader of another version.
47 * - "intrastage" checks that two vertex shaders of different versions
48 * can be linked together.
50 * - "vs-gs" checks that a vertex shader of one version can be linked
51 * with a geometry shader of another version.
54 #include "piglit-util-gl.h"
56 static enum test_type
{
62 static void parse_params(int argc
, char **argv
);
64 PIGLIT_GL_TEST_CONFIG_BEGIN
66 piglit_gl_process_args(&argc
, argv
, &config
);
67 parse_params(argc
, argv
);
68 if (test_type
== test_type_vs_gs
) {
69 config
.supports_gl_compat_version
= 32;
70 config
.supports_gl_core_version
= 32;
72 config
.supports_gl_compat_version
= 10;
73 config
.supports_gl_core_version
= 31;
76 PIGLIT_GL_TEST_CONFIG_END
78 static const char *interstage_vs
=
83 " gl_Position = vec4(0.0);\n"
86 static const char *interstage_gs
=
89 "layout(triangles) in;\n"
90 "layout(triangle_strip, max_vertices = 3) out;\n"
93 " for (int i = 0; i < 3; i++) {\n"
94 " gl_Position = gl_in[i].gl_Position;\n"
99 static const char *interstage_fs
=
104 " gl_FragColor = vec4(0.0);\n"
107 /* Section 1.2.1 (Summary of Changes from Version 4.10) of the OpenGL
108 * Shading Language 4.20 spec says:
110 * Move these previously deprecated features to be only in the
111 * compatibility profile:
113 * * The built-in variables gl_FragColor and gl_FragData.
115 static const char *interstage_fs_420
=
122 " color = vec4(0.0);\n"
125 static const char *intrastage_vs1
=
134 static const char *intrastage_vs2
=
139 " gl_Position = vec4(0.0);\n"
142 static int all_glsl_versions
[] = {
143 110, 120, 130, 140, 150, 330, 400, 410, 420, 430, 440
148 print_usage_and_exit(const char *prog_name
)
150 printf("Usage: %s <subtest>\n"
151 " where <subtest> is one of:\n"
152 " interstage: test interstage linking (vs-to-fs)\n"
153 " intrastage: test intrastage linking (vs-to-vs)\n"
154 " vs-gs: test interstage linking (vs-to-gs)\n",
156 piglit_report_result(PIGLIT_FAIL
);
161 get_max_glsl_version()
165 piglit_get_glsl_version(&es
, &major
, &minor
);
167 printf("This test should only be run on desktop GL.\n");
168 piglit_report_result(PIGLIT_FAIL
);
170 return 100 * major
+ minor
;
175 * Try compiling a shader of type \c target, whose string is formed by
176 * applying \c version to \c shader_template, and attach it to \c
177 * prog. On success, return true. If there is a problem, print an
178 * error message using \c shader_desc to describe the shader, and
182 try_attach_shader(GLuint prog
, const char *shader_desc
, GLenum target
,
183 const char *shader_template
, int version
)
185 char *shader_text
= NULL
;
186 GLuint shader
= glCreateShader(target
);
189 (void)!asprintf(&shader_text
, shader_template
, version
);
190 glShaderSource(shader
, 1, (const GLchar
**) &shader_text
, NULL
);
192 glCompileShader(shader
);
193 glGetShaderiv(shader
, GL_COMPILE_STATUS
, &ok
);
195 printf("%s failed to compile.\n", shader_desc
);
196 glDeleteShader(shader
);
199 glAttachShader(prog
, shader
);
200 glDeleteShader(shader
);
206 * Test interstage linking between VS and FS, and print a message
207 * describing the result, and return true if compilation and linking
211 test_interstage(int version_vs
, int version_other
, bool use_gs
)
213 GLuint prog
= glCreateProgram();
216 if (!try_attach_shader(prog
, "vertex shader", GL_VERTEX_SHADER
,
217 interstage_vs
, version_vs
)) {
218 glDeleteProgram(prog
);
222 if (version_other
< 150) {
223 printf("Not tested (GS requires GLSL 1.50).\n");
224 glDeleteProgram(prog
);
227 if (!try_attach_shader(prog
, "geometry shader",
228 GL_GEOMETRY_SHADER
, interstage_gs
,
230 glDeleteProgram(prog
);
234 const char *fs
= interstage_fs
;
236 if (version_other
>= 420)
237 fs
= interstage_fs_420
;
239 if (!try_attach_shader(prog
, "fragment shader",
240 GL_FRAGMENT_SHADER
, fs
,
242 glDeleteProgram(prog
);
247 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
249 printf("Success.\n");
251 printf("Link failed.\n");
257 * Test intrastage linking between two VS shaders, and print a message
258 * describing the result, and return true if compilation and linking
262 test_intrastage(int version_vs1
, int version_vs2
)
264 GLuint prog
= glCreateProgram();
267 if (!try_attach_shader(prog
, "vertex shader 1", GL_VERTEX_SHADER
,
268 intrastage_vs1
, version_vs1
)) {
269 glDeleteProgram(prog
);
272 if (!try_attach_shader(prog
, "vertex shader 2", GL_VERTEX_SHADER
,
273 intrastage_vs2
, version_vs2
)) {
274 glDeleteProgram(prog
);
278 glGetProgramiv(prog
, GL_LINK_STATUS
, &ok
);
280 printf("Success.\n");
282 printf("Link failed.\n");
288 parse_params(int argc
, char **argv
)
291 print_usage_and_exit(argv
[0]);
292 if (strcmp(argv
[1], "interstage") == 0)
293 test_type
= test_type_interstage
;
294 else if (strcmp(argv
[1], "intrastage") == 0)
295 test_type
= test_type_intrastage
;
296 else if (strcmp(argv
[1], "vs-gs") == 0)
297 test_type
= test_type_vs_gs
;
299 print_usage_and_exit(argv
[0]);
304 piglit_init(int argc
, char **argv
)
308 int max_glsl_version
;
310 piglit_require_vertex_shader();
311 if (test_type
!= test_type_intrastage
)
312 piglit_require_fragment_shader();
314 max_glsl_version
= get_max_glsl_version();
316 for (i
= 0; i
< ARRAY_SIZE(all_glsl_versions
); i
++) {
317 if (all_glsl_versions
[i
] > max_glsl_version
)
319 for (j
= 0; j
< ARRAY_SIZE(all_glsl_versions
); j
++) {
320 if (all_glsl_versions
[j
] > max_glsl_version
)
322 printf("Testing versions %d and %d: ",
323 all_glsl_versions
[i
], all_glsl_versions
[j
]);
325 case test_type_interstage
:
326 pass
= test_interstage(all_glsl_versions
[i
],
327 all_glsl_versions
[j
],
331 case test_type_vs_gs
:
332 pass
= test_interstage(all_glsl_versions
[i
],
333 all_glsl_versions
[j
],
337 case test_type_intrastage
:
338 pass
= test_intrastage(all_glsl_versions
[i
],
339 all_glsl_versions
[j
])
343 /* Should never occur */
344 piglit_report_result(PIGLIT_FAIL
);
350 piglit_report_result(pass
? PIGLIT_PASS
: PIGLIT_FAIL
);
357 /* Should never be reached */