<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>