On 4 November 2011 16:34, Ian Romanick <span dir="ltr">&lt;<a href="mailto:idr@freedesktop.org">idr@freedesktop.org</a>&gt;</span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
From: Ian Romanick &lt;<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a>&gt;<br>
<br>
This test fails on AMD&#39;s closed-source driver and NVIDIA&#39;s<br>
closed-source driver because they both allow an array to be assigned<br>
to location GL_MAX_DRAW_BUFFERS-1.  See comments in the test for the<br>
reasons this should be rejected.<br>
<br>
Signed-off-by: Ian Romanick &lt;<a href="mailto:ian.d.romanick@intel.com">ian.d.romanick@intel.com</a>&gt;<br>
---<br>
 tests/all.tests                                 |    1 +<br>
 tests/spec/gl-3.0/api/CMakeLists.gl.txt         |    1 +<br>
 tests/spec/gl-3.0/api/bindfragdata-link-error.c |  172 +++++++++++++++++++++++<br>
 3 files changed, 174 insertions(+), 0 deletions(-)<br>
 create mode 100644 tests/spec/gl-3.0/api/bindfragdata-link-error.c<br>
<br>
diff --git a/tests/all.tests b/tests/all.tests<br>
index 429f65a..9641281 100644<br>
--- a/tests/all.tests<br>
+++ b/tests/all.tests<br>
@@ -789,6 +789,7 @@ add_concurrent_test(gl20, &#39;vertex-program-two-side&#39;)<br>
 gl30 = Group()<br>
 spec[&#39;!OpenGL 3.0&#39;] = gl30<br>
 add_concurrent_test(gl30, &#39;bindfragdata-invalid-location&#39;)<br>
+add_concurrent_test(gl30, &#39;bindfragdata-link-error&#39;)<br>
 add_concurrent_test(gl30, &#39;clearbuffer-depth-stencil&#39;)<br>
 add_concurrent_test(gl30, &#39;clearbuffer-invalid-drawbuffer&#39;)<br>
 add_concurrent_test(gl30, &#39;clearbuffer-invalid-buffer&#39;)<br>
diff --git a/tests/spec/gl-3.0/api/CMakeLists.gl.txt b/tests/spec/gl-3.0/api/CMakeLists.gl.txt<br>
index 2e9f190..51fbce4 100644<br>
--- a/tests/spec/gl-3.0/api/CMakeLists.gl.txt<br>
+++ b/tests/spec/gl-3.0/api/CMakeLists.gl.txt<br>
@@ -13,6 +13,7 @@ link_libraries (<br>
 )<br>
<br>
 add_executable (bindfragdata-invalid-parameters bindfragdata-invalid-parameters.c)<br>
+add_executable (bindfragdata-link-error bindfragdata-link-error.c)<br>
 add_executable (clearbuffer-depth clearbuffer-common.c clearbuffer-depth.c)<br>
 add_executable (clearbuffer-depth-stencil clearbuffer-common.c clearbuffer-depth-stencil.c)<br>
 add_executable (clearbuffer-invalid-drawbuffer clearbuffer-invalid-drawbuffer.c)<br>
diff --git a/tests/spec/gl-3.0/api/bindfragdata-link-error.c b/tests/spec/gl-3.0/api/bindfragdata-link-error.c<br>
new file mode 100644<br>
index 0000000..70e44ca<br>
--- /dev/null<br>
+++ b/tests/spec/gl-3.0/api/bindfragdata-link-error.c<br>
@@ -0,0 +1,172 @@<br>
+/* Copyright © 2011 Intel Corporation<br>
+ *<br>
+ * Permission is hereby granted, free of charge, to any person obtaining a<br>
+ * copy of this software and associated documentation files (the &quot;Software&quot;),<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 &quot;AS IS&quot;, 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>
+<br>
+/**<br>
+ * \file bindfragdata-link-error.c<br>
+ *<br>
+ * \author Ian Romanick<br>
+ */<br>
+#include &quot;piglit-util.h&quot;<br>
+<br>
+int piglit_width = 100, piglit_height = 100;<br>
+int piglit_window_mode = GLUT_RGB | GLUT_DOUBLE;<br>
+<br>
+static const char *vs_text =<br>
+       &quot;#version 130\n&quot;<br>
+       &quot;in vec4 vertex;\n&quot;<br>
+       &quot;void main() { gl_Position = vertex; }\n&quot;<br>
+       ;<br>
+<br>
+static const char *fs_text =<br>
+       &quot;#version 130\n&quot;<br>
+       &quot;out vec4 v;\n&quot;<br>
+       &quot;out vec4 a[2];\n&quot;<br>
+       &quot;void main() {\n&quot;<br>
+       &quot;    v = vec4(0.0);\n&quot;<br>
+       &quot;    a[0] = vec4(1.0);\n&quot;<br>
+       &quot;    a[1] = vec4(2.0);\n&quot;<br>
+       &quot;}\n&quot;<br>
+       ;<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       return PIGLIT_FAIL;<br>
+}<br>
+<br>
+void piglit_init(int argc, char **argv)<br>
+{<br>
+       GLint max_draw_buffers;<br>
+       GLuint prog;<br>
+       GLuint vs;<br>
+       GLuint fs;<br>
+<br>
+       piglit_require_gl_version(30);<br>
+<br>
+       /* This test needs some number of draw buffers, so make sure the<br>
+        * implementation isn&#39;t broken.  This enables the test to generate a<br>
+        * useful failure message.<br>
+        */<br>
+       glGetIntegerv(GL_MAX_DRAW_BUFFERS, &amp;max_draw_buffers);<br>
+       if (max_draw_buffers &lt; 8) {<br>
+               fprintf(stderr,<br>
+                       &quot;OpenGL 3.0 requires GL_MAX_DRAW_BUFFERS &gt;= 8.  &quot;<br>
+                       &quot;Only got %d!\n&quot;,<br>
+                       max_draw_buffers);<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+       }<br>
+<br>
+       prog = glCreateProgram();<br>
+       vs = piglit_compile_shader_text(GL_VERTEX_SHADER, vs_text);<br>
+       fs = piglit_compile_shader_text(GL_FRAGMENT_SHADER, fs_text);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       /* First, verify that the program will link without making any<br>
+        * location assignments through the API.<br>
+        */<br>
+       printf(&quot;Basic test...\n&quot;);<br>
+<br>
+       glAttachShader(prog, vs);<br>
+       glAttachShader(prog, fs);<br>
+       glLinkProgram(prog);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       if (!piglit_link_check_status(prog)) {<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+       }<br>
+<br>
+       /* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says:<br>
+        *<br>
+        *     &quot;LinkProgram will fail if the assigned binding of a varying out<br>
+        *     variable would cause the GL to reference a non-existant<br>
+        *     fragment color number (one greater than or equal to MAX DRAW<br>
+        *     BUFFERS).&quot;<br>
+        *<br>
+        * The array output has two elements.  Binding it to<br>
+        * GL_MAX_DRAW_BUFFERS - 1 causes a[0] to have a valid location but<br>
+        * a[1] to have an invalid location.<br>
+        *<br>
+        * This should not generate a GL error.  It should only cause linking<br>
+        * to fail.<br>
+        */<br>
+       printf(&quot;Assigning `a&#39; to GL_MAX_DRAW_BUFFERS - 1...\n&quot;);<br>
+<br>
+       glBindFragDataLocation(prog, 0, &quot;v&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+       glBindFragDataLocation(prog, max_draw_buffers - 1, &quot;a&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       glLinkProgram(prog);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       if (piglit_link_check_status(prog)) {<br>
+               fprintf(stderr,<br>
+                       &quot;Linking was successful when it should have failed.\n&quot;);<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+       }<br>
+<br>
+       /* Page 237 (page 253 of the PDF) of the OpenGL 3.0 spec says:<br>
+        *<br>
+        *     &quot;LinkProgram will also fail if more than one varying out<br>
+        *     variable is bound to the same number. This type of aliasing is<br>
+        *     not allowed.&quot;<br>
+        *<br>
+        * Try this by assiging &#39;a[0]&#39; and &#39;v&#39; to the same slot, and also try<br>
+        * assigning &#39;a[1]&#39; and &#39;v&#39; to the same slot.<br>
+        *<br>
+        * This should not generate a GL error.  It should only cause linking<br>
+        * to fail.<br>
+        */<br>
+       printf(&quot;Assigning `a[0]&#39; to `v&#39; to the same slot...\n&quot;);<br></blockquote><div><br>&quot;Assigning `a[0]&#39; and `v&#39; to the same slot&quot;<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

+<br>
+       glBindFragDataLocation(prog, 0, &quot;v&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+       glBindFragDataLocation(prog, 0, &quot;a&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       glLinkProgram(prog);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       if (piglit_link_check_status(prog)) {<br>
+               fprintf(stderr,<br>
+                       &quot;Linking was successful when it should have failed.\n&quot;);<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+       }<br>
+<br>
+       printf(&quot;Assigning `a[1]&#39; to `v&#39; to the same slot...\n&quot;);<br>
+<br>
+       glBindFragDataLocation(prog, 1, &quot;v&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+       glBindFragDataLocation(prog, 0, &quot;a&quot;);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       glLinkProgram(prog);<br>
+       piglit_check_gl_error(GL_NO_ERROR, PIGLIT_FAIL);<br>
+<br>
+       if (piglit_link_check_status(prog)) {<br>
+               fprintf(stderr,<br>
+                       &quot;Linking was successful when it should have failed.\n&quot;);<br>
+               piglit_report_result(PIGLIT_FAIL);<br>
+       }<br>
+<br></blockquote><div><br>For good measure, it might be worth assigning &#39;a&#39; to 0 and &#39;v&#39; to 2, and doing a final link, to verify that:<br>- The implementation correctly computes how many slots &#39;a&#39; takes up<br>
- The implementation is capable of clearing the link error once the assignments are fixed<br>- Linking is successful when locations are assigned in a non-overlapping way.<br> </div><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">

+       piglit_report_result(PIGLIT_PASS);<br>
+}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.7.6.4<br>
<br></font></span></blockquote><div><br>In any case, this patch is:<br><br>Reviewed-by: Paul Berry &lt;<a href="mailto:stereotype441@gmail.com">stereotype441@gmail.com</a>&gt;<br></div></div>