<div dir="ltr">On 4 September 2013 12:57, Ian Romanick <span dir="ltr"><<a href="mailto:idr@freedesktop.org" target="_blank">idr@freedesktop.org</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Gregory Hainaut <<a href="mailto:gregory.hainaut@gmail.com">gregory.hainaut@gmail.com</a>><br>
<br>
Catalyst status: Part 11 & 12 failed<br>
<br>
V4:<br>
* Use standard piglit_report_subtest_result (with basic test number)<br>
* use standard bool versus GLBoolean<br>
* Merge VS shader with the help of __VERSION__<br>
* asprintf shader with a common GLSL version<br>
<br>
V5 (idr):<br>
* Use 'pass = foo() && pass;' idiom instead of 'pass &= foo();'.  C's<br>
  short-circuit evaulation rules cause these to be different.<br>
* #extension is only necessary to use layout qualifiers, so remove it.<br>
* Produce no output with -auto.<br>
* Use descriptive names for subtests.<br>
* Trivial reformatting.<br>
* Refactor (and reorder) test bodies into the<br>
  build_and_validate_pipeline function.<br>
---<br>
 tests/all.tests                                    |   1 +<br>
 .../arb_separate_shader_objects/CMakeLists.gl.txt  |   1 +<br>
 .../ValidateProgramPipeline.c                      | 531 +++++++++++++++++++++<br>
 3 files changed, 533 insertions(+)<br>
 create mode 100644 tests/spec/arb_separate_shader_objects/ValidateProgramPipeline.c<br>
<br>
diff --git a/tests/all.tests b/tests/all.tests<br>
index c8df16d..ceefaf3 100644<br>
--- a/tests/all.tests<br>
+++ b/tests/all.tests<br>
@@ -1241,6 +1241,7 @@ arb_separate_shader_objects['GetProgramPipelineiv'] = concurrent_test('arb_separ<br>
 arb_separate_shader_objects['IsProgramPipeline'] = concurrent_test('arb_separate_shader_object-IsProgramPipeline')<br>
 arb_separate_shader_objects['UseProgramStages - non-separable program'] = concurrent_test('arb_separate_shader_object-UseProgramStages-non-separable')<br>
 arb_separate_shader_objects['Mix BindProgramPipeline and UseProgram'] = concurrent_test('arb_separate_shader_object-mix_pipeline_useprogram')<br>
+arb_separate_shader_objects['ValidateProgramPipeline'] = concurrent_test('arb_separate_shader_object-ValidateProgramPipeline')<br>
<br>
 # Group ARB_sampler_objects<br>
 arb_sampler_objects = Group()<br>
diff --git a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt<br>
index 70ef99a..ad22987 100644<br>
--- a/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt<br>
+++ b/tests/spec/arb_separate_shader_objects/CMakeLists.gl.txt<br>
@@ -13,3 +13,4 @@ piglit_add_executable (arb_separate_shader_object-GetProgramPipelineiv GetProgra<br>
 piglit_add_executable (arb_separate_shader_object-IsProgramPipeline IsProgramPipeline.c)<br>
 piglit_add_executable (arb_separate_shader_object-mix_pipeline_useprogram mix_pipeline_useprogram.c)<br>
 piglit_add_executable (arb_separate_shader_object-UseProgramStages-non-separable UseProgramStages-non-separable.c)<br>
+piglit_add_executable (arb_separate_shader_object-ValidateProgramPipeline ValidateProgramPipeline.c)<br>
diff --git a/tests/spec/arb_separate_shader_objects/ValidateProgramPipeline.c b/tests/spec/arb_separate_shader_objects/ValidateProgramPipeline.c<br>
new file mode 100644<br>
index 0000000..227454e<br>
--- /dev/null<br>
+++ b/tests/spec/arb_separate_shader_objects/ValidateProgramPipeline.c<br>
@@ -0,0 +1,531 @@<br>
+/*<br>
+ * Copyright © 2013 Gregory Hainaut <<a href="mailto:gregory.hainaut@gmail.com">gregory.hainaut@gmail.com</a>><br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the "Software"),<br>
+ * to deal in the Software without restriction, including without limitation<br>
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,<br>
+ * and/or sell copies of the Software, and to permit persons to whom the<br>
+ * Software is furnished to do so, subject to the following conditions:<br>
+ *<br>
+ * The above copyright notice and this permission notice (including the next<br>
+ * paragraph) shall be included in all copies or substantial portions of the<br>
+ * Software.<br>
+ *<br>
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL<br>
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING<br>
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS<br>
+ * IN THE SOFTWARE.<br>
+ */<br>
+#define _GNU_SOURCE<br>
+#include "piglit-util-gl-common.h"<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_BEGIN<br>
+<br>
+       config.supports_gl_compat_version = 21;<br>
+<br>
+       config.window_width = 32;<br>
+       config.window_height = 32;<br>
+<br>
+PIGLIT_GL_TEST_CONFIG_END<br>
+<br>
+static const char vs_source_template[] =<br>
+       "#version %d\n"<br>
+       "\n"<br>
+       "#if __VERSION__ > 140\n"<br>
+       "out gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "};\n"<br>
+       "\n"<br>
+       "in vec4 position;\n"<br>
+       "#endif\n"<br>
+       "\n"<br>
+       "void main()\n"<br>
+       "{\n"<br>
+       "#if __VERSION__ > 140\n"<br>
+       "       gl_Position = position;\n"<br>
+       "#else\n"<br>
+       "       gl_Position = gl_Vertex;\n"<br>
+       "#endif\n"<br>
+       "}\n"<br>
+       ;<br>
+static const char fs_source_template[] =<br>
+       "#version %d\n"<br>
+       "\n"<br>
+       "void main()\n"<br>
+       "{\n"<br>
+       "       gl_FragColor = vec4(0.0, 1.0, 0.0, 0.0);\n"<br>
+       "}\n"<br>
+       ;<br>
+static const char gs_source_template[] =<br>
+       "#version %d\n"<br>
+       "\n"<br>
+       "in gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "} gl_in[];\n"<br>
+       "\n"<br>
+       "out gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "};\n"<br>
+       "\n"<br>
+       "layout(triangles) in;\n"<br>
+       "layout(triangle_strip, max_vertices = 3) out;\n"<br>
+       "void main() {\n"<br>
+       "  for(int i = 0; i < gl_in.length(); i++) {\n"<br>
+       "    gl_Position = gl_in[i].gl_Position;\n"<br>
+       "    EmitVertex();\n"<br>
+       "  }\n"<br>
+       "  EndPrimitive();\n"<br>
+       "}\n"<br>
+       ;<br>
+static const char tc_source_template[] =<br>
+       "#version %d\n"<br>
+       "#extension GL_ARB_tessellation_shader: enable\n"<br>
+       "\n"<br>
+       "in gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "} gl_in[];\n"<br>
+       "\n"<br>
+       "out gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "} gl_out[];\n"<br>
+       "\n"<br>
+       "layout(vertices = 3) out;\n"<br>
+       "void main()\n"<br>
+       "{\n"<br>
+       "        gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"<br>
+       "        gl_TessLevelOuter[0] = 1.0;\n"<br>
+       "        gl_TessLevelOuter[1] = 1.0;\n"<br>
+       "        gl_TessLevelOuter[2] = 1.0;\n"<br>
+       "        gl_TessLevelInner[0] = 1.0;\n"<br>
+       "        gl_TessLevelInner[1] = 1.0;\n"<br>
+       "}\n"<br>
+       ;<br>
+static const char te_source_template[] =<br>
+       "#version %d\n"<br>
+       "#extension GL_ARB_tessellation_shader: enable\n"<br>
+       "\n"<br>
+       "in gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "} gl_in[];\n"<br>
+       "\n"<br>
+       "out gl_PerVertex {\n"<br>
+       "    vec4 gl_Position;\n"<br>
+       "    float gl_PointSize;\n"<br>
+       "    float gl_ClipDistance[];\n"<br>
+       "};\n"<br>
+       "\n"<br>
+       "layout(triangles, equal_spacing)  in;\n"<br>
+       "\n"<br>
+       "void main()\n"<br>
+       "{\n"<br>
+       "        vec4 p0 = gl_in[0].gl_Position;\n"<br>
+       "        vec4 p1 = gl_in[1].gl_Position;\n"<br>
+       "        vec4 p2 = gl_in[2].gl_Position;\n"<br>
+       "\n"<br>
+       "        vec3 p = gl_TessCoord.xyz;\n"<br>
+       "\n"<br>
+       "        gl_Position = p0*p.x + p1*p.y + p2*p.z;\n"<br>
+       "}\n"<br>
+       ;<br>
+<br>
+static bool pass;<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       /* UNREACHED */<br>
+       return PIGLIT_FAIL;<br>
+}<br>
+<br>
+static void<br>
+validate_pipe(GLuint pipe, bool expected, const char *msg)<br></blockquote><div><br></div><div>The name "msg" sounds like the name of text that will be printed if the test fails.  Maybe rename it to "subtest_name"?<br>
</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+{<br>
+       GLint status;<br>
+<br>
+       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;<br>
+<br>
+       status = piglit_program_pipeline_check_status_quiet(pipe);<br>
+<br>
+       if (status != expected) {<br>
+               fprintf(stderr,<br>
+                       "Wrong pipeline validation status. Got %d, but "<br>
+                       "expected %d\n",<br>
+                       status, expected);<br>
+               piglit_report_subtest_result(PIGLIT_FAIL, msg);<br>
+               pass = false;<br>
+       } else {<br>
+               piglit_report_subtest_result(PIGLIT_PASS, msg);<br>
+       }<br>
+}<br>
+<br>
+static void<br>
+build_and_validate_pipe(GLuint pipe, bool expected, const char *test_name,<br>
+                       GLbitfield bit_a, GLuint prog_a,<br>
+                       GLbitfield bit_b, GLuint prog_b,<br>
+                       GLbitfield bit_c, GLuint prog_c,<br>
+                       GLbitfield bit_d, GLuint prog_d,<br>
+                       GLbitfield bit_e, GLuint prog_e)<br>
+{<br>
+       if (!piglit_automatic)<br>
+               printf("%s\n", test_name);<br>
+<br></blockquote><div><br></div><div>There's stray end-of-line whitespace here, and in several other places in the patch.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+       if (bit_a != GL_ALL_SHADER_BITS)<br>
+               glUseProgramStages(pipe, GL_ALL_SHADER_BITS, 0);<br>
+<br>
+       if (bit_a != 0)<br>
+               glUseProgramStages(pipe, bit_a, prog_a);<br>
+<br>
+       if (bit_b != 0)<br>
+               glUseProgramStages(pipe, bit_b, prog_b);<br>
+<br>
+       if (bit_c != 0)<br>
+               glUseProgramStages(pipe, bit_c, prog_c);<br>
+<br>
+       if (bit_d != 0)<br>
+               glUseProgramStages(pipe, bit_d, prog_d);<br>
+<br>
+       if (bit_e != 0)<br>
+               glUseProgramStages(pipe, bit_e, prog_e);<br>
+<br>
+       validate_pipe(pipe, expected, test_name);<br>
+<br>
+       if (!piglit_automatic)<br>
+               printf("\n");<br>
+}<br>
+<br>
+static GLuint<br>
+create_prog(GLint sh1, GLint sh2)<br>
+{<br>
+       GLint p = 0;<br>
+<br>
+       p = glCreateProgram();<br>
+       glProgramParameteri(p, GL_PROGRAM_SEPARABLE, GL_TRUE);<br>
+       if (sh1)<br>
+               glAttachShader(p, sh1);<br>
+       if (sh2)<br>
+               glAttachShader(p, sh2);<br>
+       glLinkProgram(p);<br>
+<br>
+       pass = piglit_link_check_status(p) && pass;<br>
+<br>
+       return p;<br>
+}<br>
+<br>
+void<br>
+piglit_init(int argc, char **argv)<br>
+{<br>
+       GLint vs, fs, gs, tes, tcs;<br>
+       GLuint pipe;<br>
+       GLint prog_vs, prog_fs, prog_gs, prog_tcs, prog_tes, prog_tess;<br>
+       GLint prog_vs_fs, prog_vs_gs;<br>
+       GLint separable;<br>
+       int version;<br>
+<br>
+       char *vs_source, *fs_source, *gs_source, *te_source, *tc_source;<br>
+<br>
+       const bool has_tess =<br>
+               piglit_is_extension_supported("GL_ARB_tessellation_shader");<br></blockquote><div><br></div><div>Add "piglit_get_gl_version() >= 40 ||"<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+       const bool has_geo =<br>
+               piglit_is_extension_supported("GL_ARB_geometry_shader4");<br></blockquote><div><br></div><div>Add "piglit_get_gl_version() >= 32 ||"<br><br></div><div>Actually, come to think of it, the shaders look like they wouldn't work with the extensions anyhow, so maybe this should just be:<br>
<br></div><div>const bool has_tess = piglit_get_gl_version() >= 40;<br>const bool has_geom = piglit_get_gl_version() >= 32;<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+       piglit_require_gl_version(21);<br>
+       piglit_require_extension("GL_ARB_separate_shader_objects");<br>
+<br>
+       if (piglit_get_gl_version() >= 32)<br>
+               version = 150;<br>
+       else<br>
+               version = 120;<br>
+<br>
+       pass = true;<br>
+<br>
+       /* create the shader program */<br>
+       asprintf(&vs_source, vs_source_template, version);<br>
+       asprintf(&fs_source, fs_source_template, version);<br>
+       asprintf(&gs_source, gs_source_template, version);<br>
+       asprintf(&te_source, te_source_template, version);<br>
+       asprintf(&tc_source, tc_source_template, version);<br>
+<br>
+       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_source);<br>
+       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_source);<br>
+       pass = (fs != 0) && (vs != 0) && pass;<br>
+       if (has_geo) {<br>
+               gs = piglit_compile_shader_text(GL_GEOMETRY_SHADER, gs_source);<br>
+               pass = (gs != 0) && pass;<br>
+       }<br>
+       if (has_tess) {<br>
+               tes = piglit_compile_shader_text(GL_TESS_EVALUATION_SHADER,<br>
+                                                te_source);<br>
+               tcs = piglit_compile_shader_text(GL_TESS_CONTROL_SHADER,<br>
+                                                tc_source);<br>
+               pass = (tes != 0) && (tcs != 0) && pass;<br>
+       }<br>
+<br>
+       free(vs_source);<br>
+       free(fs_source);<br>
+       free(gs_source);<br>
+       free(te_source);<br>
+       free(tc_source);<br>
+<br>
+       prog_vs = create_prog(vs, 0);<br>
+       prog_fs = create_prog(fs, 0);<br>
+       prog_vs_fs = create_prog(vs, fs);<br>
+       if (has_geo) {<br>
+               prog_gs = create_prog(gs, 0);<br>
+               prog_vs_gs = create_prog(vs, gs);<br>
+       }<br>
+       if (has_tess) {<br>
+               prog_tcs = create_prog(tcs, 0);<br>
+               prog_tes = create_prog(tes, 0);<br>
+               prog_tess = create_prog(tcs, tes);<br>
+       }<br>
+<br>
+       /* Setup or compilation failure. Stop here */<br>
+       pass = piglit_check_gl_error(GL_NO_ERROR) && pass;<br>
+       if (!pass) {<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+               return;<br>
+       }<br>
+<br>
+       if (!piglit_automatic) {<br>
+               if (has_tess && has_geo) {<br>
+                       printf("INFO: ALL stages supported: running all "<br>
+                              "test\n");<br>
+               } else {<br>
+                       if (!has_tess)<br>
+                               printf("INFO: GL_ARB_tessellation_shader not "<br>
+                                      "supported: tesselation test "<br>
+                                      "disabled\n");<br>
+                       if (!has_geo)<br>
+                               printf("INFO: GL_ARB_geometry_shader4 not "<br>
+                                      "supported: geometry test disabled\n");<br>
+               }<br>
+       }<br>
+<br>
+       /* Create the pipeline */<br>
+       glGenProgramPipelines(1, &pipe);<br>
+<br>
+       build_and_validate_pipe(pipe, true,<br>
+                               "VS/FS program, single glUseProgramStages "<br>
+                               "call",<br>
+                               GL_ALL_SHADER_BITS, prog_vs_fs,<br>
+                               0, 0,<br>
+                               0, 0,<br>
+                               0, 0,<br>
+                               0, 0);<br>
+<br>
+       build_and_validate_pipe(pipe, true,<br>
+                               "VS/FS program, multiple glUseProgramStages "<br>
+                               "calls",<br>
+                               GL_FRAGMENT_SHADER_BIT, prog_vs_fs,<br>
+                               GL_VERTEX_SHADER_BIT, prog_vs_fs,<br>
+                               0, 0,<br>
+                               0, 0,<br>
+                               0, 0);<br>
+<br>
+       build_and_validate_pipe(pipe, true,<br>
+                               "program per pipeline stage",<br>
+                               GL_VERTEX_SHADER_BIT, prog_vs,<br>
+                               GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                               (has_geo) ? GL_GEOMETRY_SHADER_BIT : 0,<br>
+                               prog_gs,<br>
+                               (has_tess) ? GL_TESS_CONTROL_SHADER_BIT : 0,<br>
+                               prog_tcs,<br>
+                               (has_tess) ? GL_TESS_EVALUATION_SHADER_BIT : 0,<br>
+                               prog_tes);<br>
+<br>
+       /* Section 2.11.11 (Shader Execution), subpart "Validation" of the<br>
+        * OpenGL 4.1 spec says:<br>
+        *<br>
+        *     "If the current set of active program objects cannot be<br>
+        *     executed, no primitives are processed and the error<br>
+        *     INVALID_OPERATION will be generated.  This error is generated<br>
+        *     by any command that transfers vertices to the GL if:<br>
+        *<br>
+        *     ...<br>
+        *<br>
+        *     - One program object is active for at least two shader stages<br>
+        *       and a second program is active for a shader stage between two<br>
+        *       stages for which the first program was active."<br>
+        */<br>
+       if (has_geo)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "GS splitting a VS/FS pipeline",<br>
+                                       GL_ALL_SHADER_BITS, prog_vs_fs,<br>
+                                       GL_GEOMETRY_SHADER_BIT, prog_gs,<br>
+                                       0, 0,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP,<br>
+                                            "GS splitting a VS/FS pipeline");<br>
+<br>
+       if (has_tess)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "TCS splitting a VS/GS pipeline",<br>
+                                       GL_ALL_SHADER_BITS, prog_vs_gs,<br>
+                                       GL_TESS_CONTROL_SHADER_BIT, prog_tcs,<br>
+                                       0, 0,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP,<br>
+                                            "TCS splitting a VS/GS pipeline");<br>
+<br>
+       if (has_tess)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "TES splitting a VS/GS program",<br>
+                                       GL_ALL_SHADER_BITS, prog_vs_gs,<br>
+                                       GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                                       GL_TESS_EVALUATION_SHADER_BIT, prog_tes,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP,<br>
+                                            "TES splitting a VS/GS program");<br>
+<br>
+       /* Section 2.11.11 (Shader Execution), subpart "Validation" of the<br>
+        * OpenGL 4.1 spec says:<br>
+        *<br>
+        *     "If the current set of active program objects cannot be<br>
+        *     executed, no primitives are processed and the error<br>
+        *     INVALID_OPERATION will be generated.  This error is generated<br>
+        *     by any command that transfers vertices to the GL if:<br>
+        *<br>
+        *     ...<br>
+        *<br>
+        *     - There is an active program for tessellation control,<br>
+        *       tessellation evaluation, or geometry stages with<br>
+        *       corresponding executable shader, but there is no active<br>
+        *       program with executable vertex shader."<br>
+        */<br>
+       if (has_geo)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "GS without VS",<br>
+                                       GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                                       GL_GEOMETRY_SHADER_BIT, prog_gs,<br>
+                                       0, 0,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP, "GS without VS");<br>
+<br>
+       if (has_tess)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "TES/TCS without VS",<br>
+                                       GL_ALL_SHADER_BITS, prog_tess,<br>
+                                       GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                                       0, 0,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP, "TES/TCS without VS");<br>
+<br>
+       /* Section 2.11.11 (Shader Execution), subpart "Validation" of the<br>
+        * OpenGL 4.1 spec says:<br>
+        *<br>
+        *     "If the current set of active program objects cannot be<br>
+        *     executed, no primitives are processed and the error<br>
+        *     INVALID_OPERATION will be generated.  This error is generated<br>
+        *     by any command that transfers vertices to the GL if:<br>
+        *<br>
+        *     - A program object is active for at least one, but not all of<br>
+        *       the shader stages that were present when the program was<br>
+        *       linked."<br>
+        */<br>
+       build_and_validate_pipe(pipe, false,<br>
+                               "Only VS from a VS/FS program",<br>
+                               GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                               GL_VERTEX_SHADER_BIT, prog_vs_fs,<br>
+                               0, 0,<br>
+                               0, 0,<br>
+                               0, 0);<br>
+<br>
+       if (has_geo)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "Only VS from a VS/GS program",<br></blockquote><div><br></div><div>I think what was meant was "Only GS from a VS/GS program".<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+                                       GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                                       GL_GEOMETRY_SHADER_BIT, prog_vs_gs,<br>
+                                       GL_VERTEX_SHADER_BIT, prog_vs,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP,<br>
+                                            "Only VS from a VS/GS program");<br></blockquote><div><br></div><div>Same issue here.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+       if (has_tess)<br>
+               build_and_validate_pipe(pipe, false,<br>
+                                       "Only TES from TES/TCS program",<br>
+                                       GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                                       GL_TESS_EVALUATION_SHADER_BIT, prog_tess,<br>
+                                       GL_VERTEX_SHADER_BIT, prog_vs,<br>
+                                       0, 0,<br>
+                                       0, 0);<br>
+       else<br>
+               piglit_report_subtest_result(PIGLIT_SKIP,<br>
+                                            "Only TES from TES/TCS program");<br>
+<br>
+       /* Section 2.11.11 (Shader Execution), subpart "Validation" of the<br>
+        * OpenGL 4.1 spec says:<br>
+        *<br>
+        *     "If the current set of active program objects cannot be<br>
+        *     executed, no primitives are processed and the error<br>
+        *     INVALID_OPERATION will be generated.  This error is generated<br>
+        *     by any command that transfers vertices to the GL if:<br>
+        *<br>
+        *     ...<br>
+        *<br>
+        *     - There is no current unified program object and the current<br>
+        *       program pipeline object includes a program object that was<br>
+        *       relinked since being applied to the pipeline object via<br>
+        *       UseProgramStages with the PROGRAM_SEPARABLE parameter set to<br>
+        *       FALSE."<br>
+        */<br>
+       build_and_validate_pipe(pipe, true,<br>
+                               "Relink attached FS without "<br>
+                               "GL_PROGRAM_SEPARABLE (sanity pre-test)",<br>
+                               GL_FRAGMENT_SHADER_BIT, prog_fs,<br>
+                               GL_VERTEX_SHADER_BIT, prog_vs,<br>
+                               0, 0,<br>
+                               0, 0,<br>
+                               0, 0);<br>
+<br>
+       glGetProgramiv(prog_fs, GL_PROGRAM_SEPARABLE, &separable);<br>
+       if (!separable) {<br>
+               printf("Error: %d was not a separable program\n", prog_fs);<br>
+               pass = false;<br>
+       }<br>
+<br>
+       glProgramParameteri(prog_fs, GL_PROGRAM_SEPARABLE, GL_FALSE);<br>
+<br>
+       glGetProgramiv(prog_fs, GL_PROGRAM_SEPARABLE, &separable);<br>
+       if (separable) {<br>
+               printf("Error: fail to remove separable flags of program %d\n",<br>
+                      prog_fs);<br>
+               pass = false;<br>
+       }<br>
+<br>
+       glLinkProgram(prog_fs);<br>
+       pass = piglit_link_check_status(prog_fs) && pass;<br>
+       validate_pipe(pipe, GL_FALSE,<br>
+                     "Relink attached FS without GL_PROGRAM_SEPARABLE");<br></blockquote><div><br></div><div>If I'm not mistaken, this last subtest is the only part of this test that relies on compatibility functionality, and it only does so because it tries to link a non-separable program containing only a fragment shader.  I'd prefer to see this subtest rewritten so that it operates on prog_vs_fs.  Then I believe we can add "supports_gl_core_version" to the config block.<br>
<br></div><div>With those minor fixes, the patch is:<br><br>Reviewed-by: Paul Berry <<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

+<br>
+       piglit_present_results();<br>
+<br>
+       piglit_report_result(pass ? PIGLIT_PASS : PIGLIT_FAIL);<br>
+}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.1.4<br>
<br>
_______________________________________________<br>
Piglit mailing list<br>
<a href="mailto:Piglit@lists.freedesktop.org">Piglit@lists.freedesktop.org</a><br>
<a href="http://lists.freedesktop.org/mailman/listinfo/piglit" target="_blank">http://lists.freedesktop.org/mailman/listinfo/piglit</a><br>
</font></span></blockquote></div><br></div></div>