<div dir="ltr"><div><div><div>Hi Juliet,<br><br></div>This looks pretty good overall.  Assorted comments below.<br><br></div>Also, for Piglit we use 8-column tabs, not spaces, for indentation.  Can you fix that too?  Thanks!<br><br></div>-Brian<br><div><br><div><div><div><br>On Fri, Sep 25, 2015 at 4:03 PM, Juliet Fru <span dir="ltr"><<a href="mailto:julietfru@gmail.com" target="_blank">julietfru@gmail.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">This test replaces the original glean tstencil2.cpp test.<br>
---<br>
 tests/spec/gl-2.0/ two-sided-stencil.c | 743 +++++++++++++++++++++++++++++++++<br>
 tests/spec/gl-2.0/CMakeLists.gl.txt    |   1 +<br>
 2 files changed, 744 insertions(+)<br>
 create mode 100644 tests/spec/gl-2.0/ two-sided-stencil.c<br>
<br>
diff --git a/tests/spec/gl-2.0/ two-sided-stencil.c b/tests/spec/gl-2.0/ two-sided-stencil.c<br>
new file mode 100644<br>
index 0000000..7f421af<br>
--- /dev/null<br>
+++ b/tests/spec/gl-2.0/ two-sided-stencil.c<br>
@@ -0,0 +1,743 @@<br>
+/*<br>
+ * BEGIN_COPYRIGHT -*- glean -*-<br>
+ *<br>
+ * Copyright (C) 1999  Allen Akin   All Rights Reserved.<br>
+ * Copyright (C) 2009  VMware, Inc.  All Rights Reserved.<br>
+ * Copyright (C) 2015  Intel Corporation  All Rights Reserved.<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<br>
+ * DEALINGS IN THE SOFTWARE.<br>
+ *<br>
+ * END_COPYRIGHT<br>
+ */<br>
+<br>
+/** @file stencil-extension.c<br></blockquote><div><br></div><div>Let's update the filename there.<br><br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ *<br>
+ *  Test two-sided stencil extensions<br>
+ *<br>
+ *     This test could be better:<br>
+ *     1. Generate random state vectors, render and compare to expected values<br>
+ *     2. Exercise separate front/back reference values and masks for the<br>
+ *     EXT and GL2 variations.WriteMask<br></blockquote><div><br></div><div>remove stray "WriteMask".<br><br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+ *<br>
+ *     Note: Must check writeMask of set_stencil_state to make sure it's correct<br>
+ *<br>
+ *     Authors:<br>
+ *             Brian Paul <<a href="mailto:brianp@valinux.com">brianp@valinux.com</a>><br>
+ *             Adapted to Piglit by Juliet Fru <<a href="mailto:julietfru@gmail.com">julietfru@gmail.com</a>>, September 2015.<br>
+ */<br>
+<br>
+#include "piglit-util-gl.h"<br>
+<br>
+#include <assert.h><br>
+#include <string.h><br>
+<br>
+#define window_size 100<br></blockquote><div><br></div><div>We should be able to remove that macro and use piglit_width and piglit_height instead below.<br><br></div><div>Also, we should have the usual piglit config section here:<br><br></div><div>PIGLIT_GL_TEST_CONFIG_BEGIN<br>config.supports_gl_compat_version = 20;<br>config.window_visual = PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH | PIGLIT_GL_VISUAL_STENCIL;<br>PIGLIT_GL_TEST_CONFIG_END<br><br><br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+<br>
+/*  two-sided methods. */<br>
+#define ATI 1<br>
+#define EXT 2<br>
+#define GL2 3<br>
+<br>
+GLint stencil_bits, stencil_max;<br>
+<br>
+static bool<br>
+have_stencil_wrap(void)<br>
+{<br>
+       if (piglit_get_gl_version() >= 2.0) {<br>
+               return true;<br>
+       } else if (piglit_is_extension_supported("GL_EXT_stencil_wrap")) {<br>
+               return true;<br>
+       }<br>
+       return false;<br>
+}<br>
+<br>
+<br>
+/* Draw four quads:<br>
+ * Bottom row uses GL_CCW<br>
+ * Top row uses GL_CW<br>
+ * Left column is front-facing<br>
+ * Right column is back-facing<br>
+ * Check the values in the stencil buffer to see if they match<br>
+ * the expected values.<br>
+ */<br>
+static bool<br>
+render_test(GLuint expectedFront, GLuint expectedBack)<br>
+{<br>
+       GLint x0 = 0;<br>
+       GLint x1 = window_size / 2;<br>
+       GLint x2 = window_size;<br></blockquote><div><br></div><div>GLint x1 = piglit_width / 2;<br></div><div>GLint x2 = piglit_width;<br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       GLint y0 = 0;<br>
+       GLint y1 = window_size / 2;<br>
+       GLint y2 = window_size;<br>
</blockquote><div><br></div><div>GLint y1 = piglit_height / 2;<br></div><div>GLint y2 = piglit_height;<br><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">+<br>
+       glFrontFace(GL_CCW);    /* this the GL default */<br>
+<br>
+       /* lower left quad = front-facing */<br>
+       glBegin(GL_TRIANGLE_FAN);<br>
+       glVertex2f(x0, y0);<br>
+       glVertex2f(x1, y0);<br>
+       glVertex2f(x1, y1);<br>
+       glVertex2f(x0, y1);<br>
+       glEnd();<br>
+<br>
+       /* lower right quad = back-facing */<br>
+       glBegin(GL_TRIANGLE_FAN);<br>
+       glVertex2f(x1, y0);<br>
+       glVertex2f(x1, y1);<br>
+       glVertex2f(x2, y1);<br>
+       glVertex2f(x2, y0);<br>
+       glEnd();<br>
+<br>
+       glFrontFace(GL_CW);<br>
+<br>
+       /* upper left quad = front-facing */<br>
+       glBegin(GL_TRIANGLE_FAN);<br>
+       glVertex2f(x0, y1);<br>
+       glVertex2f(x0, y2);<br>
+       glVertex2f(x1, y2);<br>
+       glVertex2f(x1, y1);<br>
+       glEnd();<br>
+<br>
+       /* upper right quad = back-facing */<br>
+       glBegin(GL_TRIANGLE_FAN);<br>
+       glVertex2f(x1, y1);<br>
+       glVertex2f(x2, y1);<br>
+       glVertex2f(x2, y2);<br>
+       glVertex2f(x1, y2);<br>
+       glEnd();<br>
+<br>
+       GLint midXleft = (x0  x1) / 2;<br>
+       GLint midXright = (x1  x2) / 2;<br>
+       GLint midYlower = (y0  y1) / 2;<br>
+       GLint midYupper = (y1  y2) / 2;<br></blockquote><div><br></div><div>It appears that the '+' operator is missing in those statements.<br><br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       GLuint lowerLeftVal, lowerRightVal;<br>
+       GLuint upperLeftVal, upperRightVal;<br>
+<br>
+       glReadPixels(midXleft, midYlower, 1, 1,<br>
+                    GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerLeftVal);<br>
+       glReadPixels(midXright, midYlower, 1, 1,<br>
+                    GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerRightVal);<br>
+<br>
+       glReadPixels(midXleft, midYupper, 1, 1,<br>
+                    GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperLeftVal);<br>
+       glReadPixels(midXright, midYupper, 1, 1,<br>
+                    GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperRightVal);<br>
+<br>
+       if (lowerLeftVal != upperLeftVal) {<br>
+               printf(" FAIL:\n"<br>
+                      "\tLower-left value (%d) doesn't match upper-left "<br>
+                      "value (%d).\n \t Looks like a front/back "<br>
+                      "orientation bug.\n", lowerLeftVal, upperLeftVal);<br>
+               return false;<br>
+       }<br>
+<br>
+       if (lowerRightVal != upperRightVal) {<br>
+               printf(" FAIL:\n\tLower-right value (%d) doesn't match"<br>
+                      " upper-right value (%d).\n\tLooks like "<br>
+                      "a front/back-face orientation bug.\n", lowerRightVal,<br>
+                      upperRightVal);<br>
+               return false;<br>
+       }<br>
+<br>
+<br>
+       if (lowerLeftVal != expectedFront) {<br>
+               printf("FAIL:\n\tExpected front-face stencil value is "<br>
+                      "%d but found %d \n", expectedFront, lowerLeftVal);<br>
+               return false;<br>
+       } else if (lowerRightVal != expectedBack) {<br>
+               printf("FAIL:\n\tExpected back-face stencil value is "<br>
+                      "%d but found %d \n", expectedBack, lowerRightVal);<br>
+               return false;<br>
+       } else {<br>
+               return true;<br>
+       }<br>
+}<br>
+<br>
+<br>
+static bool<br>
+compare_state(int method, GLenum found, GLenum expected, const char *msg)<br>
+{<br>
+       if (found != expected) {<br>
+               printf(" FAIL:\n\tQuery of %s state failed for ", msg);<br>
+               switch (method) {<br>
+               case ATI:<br>
+                       printf("GL_ATI_separate_stencil\n");<br>
+                       break;<br>
+               case EXT:<br>
+                       printf("GL_EXT_stencil_two_side\n");<br>
+                       break;<br>
+               case GL2:<br>
+                       printf("GL 2.x two-sided stencil\n");<br>
+                       break;<br>
+               default:<br>
+                       printf("\n");<br>
+                       assert(0);<br>
+               }<br>
+<br>
+               printf("\tFound 0x%x, expected 0x%x\n", found, expected);<br>
+               return false;<br>
+       }<br>
+       return true;<br>
+}<br>
+<br>
+<br>
+/* Set stencil state, plus read it back and check that it's correct.<br>
+ * Note: we only test with one reference value and one mask value<br>
+ * even though EXT and GL2 support separate front/back refs/masks<br>
+ */<br>
+static bool<br>
+set_stencil_state(int method,<br>
+                 GLenum frontStencilFail,<br>
+                 GLenum backStencilFail,<br>
+                 GLenum frontZFail,<br>
+                 GLenum backZFail,<br>
+                 GLenum frontZPass,<br>
+                 GLenum backZPass,<br>
+                 GLenum frontFunc,<br>
+                 GLenum backFunc,<br>
+                 GLint frontRef,<br>
+                 GLint backRef,<br>
+                 GLuint frontMask,<br>
+                 GLuint backMask,<br>
+                 GLuint frontWriteMask, GLuint backWriteMask)<br>
+{<br>
+       GLint get_frontStencilFail;<br>
+       GLint get_backStencilFail;<br>
+       GLint get_frontZFail;<br>
+       GLint get_backZFail;<br>
+       GLint get_frontZPass;<br>
+       GLint get_backZPass;<br>
+       GLint get_frontFunc;<br>
+       GLint get_backFunc;<br>
+       GLint get_frontRef;<br>
+       GLint get_backRef;<br>
+       GLint get_frontMask;<br>
+       GLint get_backMask;<br>
+       GLint get_frontWriteMask;<br>
+       GLint get_backWriteMask;<br>
+       GLint twoEnabled;<br>
+<br>
+       switch (method) {<br>
+       case ATI:<br>
+               assert(frontRef == backRef);<br>
+               assert(frontMask == backMask);<br>
+               assert(frontWriteMask == backWriteMask);<br>
+<br>
+               /* set state */<br>
+               glStencilOpSeparateATI(GL_FRONT,<br>
+                                      frontStencilFail,<br>
+                                      frontZFail, frontZPass);<br>
+<br>
+               glStencilOpSeparateATI(GL_BACK,<br>
+                                      backStencilFail, backZFail, backZPass);<br>
+<br>
+               glStencilFuncSeparateATI(frontFunc, backFunc, frontRef,<br>
+                                        frontMask);<br>
+<br>
+               glStencilMask(frontWriteMask);<br>
+<br>
+               /* get state */<br>
+               glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);<br>
+               glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);<br>
+               glGetIntegerv(GL_STENCIL_REF, &get_frontRef);<br>
+               glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);<br>
+               glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);<br>
+<br>
+               glGetIntegerv(GL_STENCIL_BACK_FUNC_ATI, &get_backFunc);<br>
+               glGetIntegerv(GL_STENCIL_BACK_FAIL_ATI, &get_backStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI,<br>
+                             &get_backZFail);<br>
+               glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI,<br>
+                             &get_backZPass);<br>
+               get_backRef = get_frontRef;<br>
+               get_backMask = get_frontMask;<br>
+               get_backWriteMask = get_frontWriteMask;<br>
+               twoEnabled = GL_TRUE;<br>
+               break;<br>
+<br>
+       case EXT:<br>
+               /* set state */<br>
+               glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);<br>
+<br>
+               glActiveStencilFaceEXT(GL_FRONT);<br>
+               glStencilOp(frontStencilFail, frontZFail, frontZPass);<br>
+               glStencilFunc(frontFunc, frontRef, frontMask);<br>
+               glStencilMask(frontWriteMask);<br>
+<br>
+               glActiveStencilFaceEXT(GL_BACK);<br>
+               glStencilOp(backStencilFail, backZFail, backZPass);<br>
+               glStencilFunc(backFunc, backRef, backMask);<br>
+               glStencilMask(backWriteMask);<br>
+<br>
+               /* get state */<br>
+               glActiveStencilFaceEXT(GL_FRONT);<br>
+               glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);<br>
+               glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);<br>
+               glGetIntegerv(GL_STENCIL_REF, &get_frontRef);<br>
+               glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);<br>
+               glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);<br>
+               glActiveStencilFaceEXT(GL_BACK);<br>
+               glGetIntegerv(GL_STENCIL_FAIL, &get_backStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_backZFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_backZPass);<br>
+               glGetIntegerv(GL_STENCIL_FUNC, &get_backFunc);<br>
+               glGetIntegerv(GL_STENCIL_REF, &get_backRef);<br>
+               glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_backMask);<br>
+               glGetIntegerv(GL_STENCIL_WRITEMASK, &get_backWriteMask);<br>
+               glGetIntegerv(GL_STENCIL_TEST_TWO_SIDE_EXT, &twoEnabled);<br>
+               break;<br>
+<br>
+       case GL2:<br>
+               /* set state */<br>
+               glStencilOpSeparate(GL_FRONT,<br>
+                                   frontStencilFail, frontZFail, frontZPass);<br>
+               glStencilOpSeparate(GL_BACK,<br>
+                                   backStencilFail, backZFail, backZPass);<br>
+               glStencilFuncSeparate(GL_FRONT, frontFunc, frontRef,<br>
+                                     frontMask);<br>
+               glStencilFuncSeparate(GL_BACK, backFunc, backRef, backMask);<br>
+               glStencilMaskSeparate(GL_FRONT, frontWriteMask);<br>
+               glStencilMaskSeparate(GL_BACK, backWriteMask);<br>
+<br>
+               /* get state */<br>
+               glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);<br>
+               glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);<br>
+               glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);<br>
+               glGetIntegerv(GL_STENCIL_REF, &get_frontRef);<br>
+               glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);<br>
+               glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);<br>
+<br>
+               glGetIntegerv(GL_STENCIL_BACK_FUNC, &get_backFunc);<br>
+               glGetIntegerv(GL_STENCIL_BACK_FAIL, &get_backStencilFail);<br>
+               glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL,<br>
+                             &get_backZFail);<br>
+               glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS,<br>
+                             &get_backZPass);<br>
+               glGetIntegerv(GL_STENCIL_BACK_REF, &get_backRef);<br>
+               glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &get_backMask);<br>
+               glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &get_backWriteMask);<br>
+               twoEnabled = GL_TRUE;<br>
+               break;<br>
+<br>
+       default:<br>
+               assert(0);<br>
+       }<br>
+<br>
+       /* mask off bits we don't care about */<br>
+       get_frontMask &= stencil_max;<br>
+       frontMask &= stencil_max;<br>
+       get_backMask &= stencil_max;<br>
+       backMask &= stencil_max;<br>
+       get_frontWriteMask &= stencil_max;<br>
+       frontWriteMask &= stencil_max;<br>
+       get_backWriteMask &= stencil_max;<br>
+       backWriteMask &= stencil_max;<br>
+<br>
+<br>
+       if (!piglit_check_gl_error(GL_NO_ERROR)) {<br>
+               printf(" FAIL:\n\tGL error  %d detected.\n", GL_NO_ERROR);<br></blockquote><div><br></div><div>You can remove that printf() since the piglit_check_gl_error() function will print a message if the check fails.<br><br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+               return false;<br>
+       }<br>
+<br>
+       /* see if state-get matches state-set */<br>
+<br>
+       if (!compare_state(method, get_frontStencilFail, frontStencilFail,<br>
+                          "front stencil fail"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backStencilFail, backStencilFail,<br>
+                          "back stencil fail"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontZFail, frontZFail,<br>
+                          "front Z fail"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backZFail, backZFail, "back Z fail"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontZPass, frontZPass,<br>
+                          "front Z pass"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backZPass, backZPass, "back Z pass"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontFunc, frontFunc,<br>
+                          "front stencil func"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backFunc, backFunc,<br>
+                          "back stencil func"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontRef, frontRef,<br>
+                          "front stencil ref"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backRef, backRef, "back stencil ref"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontMask, frontMask,<br>
+                          "front stencil mask"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backMask, backMask,<br>
+                          "back stencil mask"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_frontWriteMask, frontWriteMask,<br>
+                          "front stencil writemask"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, get_backWriteMask, backWriteMask,<br>
+                          "back stencil writemask"))<br>
+               return false;<br>
+<br>
+       if (!compare_state(method, twoEnabled, GL_TRUE, "two-side enable"))<br>
+               return false;<br>
+<br>
+       return true;<br>
+}<br>
+<br>
+<br>
+static bool<br>
+set_stencil_state2(int method,<br>
+                  GLenum frontStencilFail,<br>
+                  GLenum backStencilFail,<br>
+                  GLenum frontZFail,<br>
+                  GLenum backZFail,<br>
+                  GLenum frontZPass,<br>
+                  GLenum backZPass,<br>
+                  GLenum frontFunc,<br>
+                  GLenum backFunc, GLint ref, GLuint mask, GLuint writeMask)<br>
+{<br>
+       return set_stencil_state(method, frontStencilFail, backStencilFail, frontZFail, backZFail, frontZPass, backZPass, frontFunc, backFunc, ref,     /* frontRef */<br>
+                                ref,   /* backRef */<br>
+                                mask,  /* frontMask */<br>
+                                mask,  /* backMask */<br>
+                                writeMask,     /* frontWriteMask */<br>
+                                writeMask);    /* backWriteMask */<br>
+}<br>
+<br>
+<br>
+void<br>
+reset_stencil_state(int method)<br>
+{<br>
+       switch (method) {<br>
+       case ATI:<br>
+               break;<br>
+       case EXT:<br>
+               glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);<br>
+               glActiveStencilFaceEXT(GL_FRONT);<br>
+               break;<br>
+       case GL2:<br>
+               break;<br>
+       default:<br>
+               assert(0);<br>
+       }<br>
+}<br>
+<br>
+<br>
+static bool<br>
+test_stencil(int method)<br>
+{<br>
+       bool pass;<br>
+<br>
+       glEnable(GL_STENCIL_TEST);<br>
+<br>
+       /**<br>
+        * No depth testing<br>
+        */<br>
+       glDisable(GL_DEPTH_TEST);<br>
+<br>
+       glClear(GL_COLOR_BUFFER_BIT |<br>
+               GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br>
+<br>
+<br>
+       /* set stencil buffer vals to 5 */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_REPLACE, GL_REPLACE,       /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 5, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(5, 5);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+       /* incr front val to 6, decr back val to 4 */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_INCR, GL_DECR,     /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 5, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(6, 4);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+       /* if front==6, keep<br>
+        * if back<6, replace with zero<br>
+        * final: front=6, back=0<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_ZERO,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z pass */<br>
+                                 GL_EQUAL, GL_LESS,    /* stencil func */<br>
+                                 6, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(6, 0);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+       /* if front!=10, keep, else decr<br>
+        * if back<10, keep, else incr<br>
+        * final: front=6, back=1<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_DECR, GL_INCR,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z pass */<br>
+                                 GL_NOTEQUAL, GL_LESS, /* stencil func */<br>
+                                 10, ~0, ~0);  /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(6, 1);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+       if (method != ATI) {<br>
+               /* if front!=10, keep, else decr<br>
+                * if back<10, keep, else incr<br>
+                * final: front=6, back=1<br>
+                */<br>
+               pass = set_stencil_state(method, GL_DECR, GL_INCR,      /* stencil fail */<br>
+                                        GL_KEEP, GL_KEEP,      /* z fail */<br>
+                                        GL_REPLACE, GL_REPLACE,        /* z pass */<br>
+                                        GL_ALWAYS, GL_ALWAYS,  /* stencil func */<br>
+                                        0xf6, 0xf1,    /* ref */<br>
+                                        0xff, 0xff,    /* mask */<br>
+                                        0x60, 0x10);   /* writeMask */<br>
+               if (pass)<br>
+                       pass = render_test(0x66, 0x11);<br>
+               reset_stencil_state(method);<br>
+               if (!pass)<br>
+                       return false;<br>
+       }<br>
+<br>
+       /* reset write mask for clear */<br>
+       set_stencil_state(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                         GL_KEEP, GL_KEEP,     /* z fail */<br>
+                         GL_REPLACE, GL_REPLACE,       /* z pass */<br>
+                         GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                         0, 0, ~0, ~0, ~0, ~0);<br>
+<br>
+       /* ============================================================<br>
+        * Now begin tests with depth test<br>
+        */<br>
+       glEnable(GL_DEPTH_TEST);<br>
+       glDepthFunc(GL_LESS);<br>
+<br>
+       glClear(GL_COLOR_BUFFER_BIT |<br>
+               GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br>
+<br>
+       /* set stencil buffer vals to 7, set Z values */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_REPLACE, GL_REPLACE,       /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 7, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(7, 7);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* GL_LESS test should fail everywhere<br>
+        * decr front to 5, incr back to 2<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_DECR, GL_INCR,     /* z fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 99, ~0, ~0);  /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(6, 8);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* set depth test = GL_EQUAL<br>
+        * Z test should pass everywhere<br>
+        * set front to 3<br>
+        * decr back to 7<br>
+        */<br>
+       glDepthFunc(GL_EQUAL);<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_REPLACE, GL_DECR,  /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 3, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(3, 7);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* incr front to 4 (by z pass), decr back to 6 (by stencil fail) */<br>
+       pass = set_stencil_state2(method, GL_DECR, GL_DECR,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_INCR, GL_REPLACE,  /* z pass */<br>
+                                 GL_EQUAL, GL_EQUAL,   /* stencil func */<br>
+                                 3, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(4, 6);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* ============================================================<br>
+        * Disable depth test<br>
+        */<br>
+       glDisable(GL_DEPTH_TEST);<br>
+<br>
+       /* test stencil value mask<br>
+        * only test bit 1 in stencil values<br>
+        * if !(front&0x2 == 15&0x2), decr to 3 (should happen)<br>
+        * if !(back&0x2 == 15&0x2), incr to 7 (should not happen)<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_DECR, GL_INCR,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z pass */<br>
+                                 GL_EQUAL, GL_EQUAL,   /* stencil func */<br>
+                                 15, 0x2, ~0); /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(3, 6);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* ============================================================<br>
+        * Test common two-sided stencil modes for shadow volume rendering<br>
+        * Requires stencil /- wrap feature.<br>
+        */<br>
+<br>
+       if (!have_stencil_wrap())<br>
+               return true;<br>
+<br>
+       glClear(GL_COLOR_BUFFER_BIT |<br>
+               GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);<br>
+<br>
+       glEnable(GL_DEPTH_TEST);<br>
+       glDepthFunc(GL_LESS);<br>
+<br>
+       /* "traditional / Z-pass" method:<br>
+        * front face: incr on zpass<br>
+        * back face: decr on zpass<br>
+        * both front and back Z-test should pass here<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z fail */<br>
+                                 GL_INCR_WRAP_EXT, GL_DECR_WRAP_EXT,   /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 0, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(1, stencil_max);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br>
+       /* "Z-fail" method:<br>
+        * front face: decr on zfail<br>
+        * back face: incr on zfail<br>
+        * both front and back Z-test should fail here<br>
+        */<br>
+       pass = set_stencil_state2(method, GL_KEEP, GL_KEEP,     /* stencil fail */<br>
+                                 GL_DECR_WRAP_EXT, GL_INCR_WRAP_EXT,   /* z fail */<br>
+                                 GL_KEEP, GL_KEEP,     /* z pass */<br>
+                                 GL_ALWAYS, GL_ALWAYS, /* stencil func */<br>
+                                 0, ~0, ~0);   /* ref, mask, set white_mask to ~0 */<br>
+       if (pass)<br>
+               pass = render_test(0, 0);<br>
+       reset_stencil_state(method);<br>
+       if (!pass)<br>
+               return false;<br>
+<br>
+<br></blockquote><div><br></div><div>One empty line there is enough.<br><br> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
+       return true;<br>
+}<br>
+<br>
+<br>
+void<br>
+piglit_init(int argc, char **argv)<br>
+{<br>
+<br>
+       /* Common setup, work done in piglit_display<br>
+        * piglit_ortho_projection(window_size, window_size, GL_FALSE);<br>
+        */<br></blockquote><div><br></div><div>I think you can replace that comment with:<br><br> /* no initialization */<br><br></div><div>Or, you could move the glGetIntegerv(GL_STENCIL_BITS) call here from below.<br><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">+}<br>
+<br>
+<br>
+<br>
+enum piglit_result<br>
+piglit_display(void)<br>
+{<br>
+       bool pass = true;<br>
+<br>
+       /* how many stencil bits (we assume at least 8 above) */<br>
+       glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);<br>
+       stencil_max = (1 << stencil_bits) - 1;<br>
+       assert(stencil_bits >= 8);<br>
+<br>
+       glViewport(0, 0, window_size, window_size);<br>
+       glMatrixMode(GL_PROJECTION);<br>
+       glLoadIdentity();<br>
+       glOrtho(0, window_size, 0, window_size, -1, 1);<br>
+       glMatrixMode(GL_MODELVIEW);<br>
+       glLoadIdentity();<br>
+<br>
+       if (piglit_is_extension_supported("GL_ATI_separate_stencil")) {<br>
+               pass = test_stencil(ATI) && pass;<br>
+       }<br>
+<br>
+       if (piglit_is_extension_supported("GL_EXT_stencil_two_side")) {<br>
+               pass = test_stencil(EXT) && pass;<br>
+       }<br>
+<br>
+       if (piglit_get_gl_version() >= 2.0) {<br>
+               pass = test_stencil(GL2) && pass;<br>
+       }<br>
+<br>
+       return pass ? PIGLIT_PASS : PIGLIT_FAIL;<br>
+}<br>
diff --git a/tests/spec/gl-2.0/CMakeLists.gl.txt b/tests/spec/gl-2.0/CMakeLists.gl.txt<br>
index 9461a03..bc25688 100644<br>
--- a/tests/spec/gl-2.0/CMakeLists.gl.txt<br>
+++ b/tests/spec/gl-2.0/CMakeLists.gl.txt<br>
@@ -14,6 +14,7 @@ piglit_add_executable (vertex-program-two-side vertex-program-two-side.c)<br>
 piglit_add_executable (gl-2.0-edgeflag edgeflag.c)<br>
 piglit_add_executable (gl-2.0-edgeflag-immediate edgeflag-immediate.c)<br>
 piglit_add_executable (gl-2.0-large-point-fs large-point-fs.c)<br>
+piglit_add_executable (gl-2.0-two-sided-stencil two-sided-stencil.c)<br>
 piglit_add_executable (gl-2.0-vertexattribpointer vertexattribpointer.c)<br>
 piglit_add_executable (gl-2.0-vertex-const-attr vertex-const-attr.c)<br>
 piglit_add_executable (gl-2.0-reuse_fragment_shader reuse_fragment_shader.c)<br>
<span class=""><font color="#888888">--<br>
2.4.3<br>
<br>
</font></span></blockquote></div><br></div></div></div></div></div></div>