[Piglit] [PATCH v3] Porting the two sided stencil extension tests from Glean to Piglit.
Brian Paul
brianp at vmware.com
Thu Oct 1 15:16:04 PDT 2015
Looks good except for some minor formatting/comment issues below...
I tested with llvmpipe and it passes. With NVIDIA's driver, something
weird is going on. It passes with -pbo or no options, but fails with
the -auto option. I think we've seen that before with some tests so you
don't have to investigate that.
-Brian
On 10/01/2015 12:02 PM, Juliet Fru wrote:
> This test replaces the original glean tstencil2.cpp test.
> ---
> tests/all.py | 1 +
> tests/spec/gl-2.0/CMakeLists.gl.txt | 1 +
> tests/spec/gl-2.0/two-sided-stencil.c | 745 ++++++++++++++++++++++++++++++++++
> 3 files changed, 747 insertions(+)
> create mode 100644 tests/spec/gl-2.0/two-sided-stencil.c
>
> diff --git a/tests/all.py b/tests/all.py
> index fe088f5..e9d7f9b 100644
> --- a/tests/all.py
> +++ b/tests/all.py
> @@ -1076,6 +1076,7 @@ with profile.group_manager(
> g(['gl-2.0-edgeflag'])
> g(['gl-2.0-edgeflag-immediate'])
> g(['gl-2.0-large-point-fs'])
> + g(['gl-2.0-two-sided-stencil'])
> g(['gl-2.0-vertexattribpointer'])
> g(['gl-2.0-vertex-const-attr'])
> g(['gl-2.0-reuse_fragment_shader'])
> diff --git a/tests/spec/gl-2.0/CMakeLists.gl.txt b/tests/spec/gl-2.0/CMakeLists.gl.txt
> index 9461a03..bc25688 100644
> --- a/tests/spec/gl-2.0/CMakeLists.gl.txt
> +++ b/tests/spec/gl-2.0/CMakeLists.gl.txt
> @@ -14,6 +14,7 @@ piglit_add_executable (vertex-program-two-side vertex-program-two-side.c)
> piglit_add_executable (gl-2.0-edgeflag edgeflag.c)
> piglit_add_executable (gl-2.0-edgeflag-immediate edgeflag-immediate.c)
> piglit_add_executable (gl-2.0-large-point-fs large-point-fs.c)
> +piglit_add_executable (gl-2.0-two-sided-stencil two-sided-stencil.c)
> piglit_add_executable (gl-2.0-vertexattribpointer vertexattribpointer.c)
> piglit_add_executable (gl-2.0-vertex-const-attr vertex-const-attr.c)
> piglit_add_executable (gl-2.0-reuse_fragment_shader reuse_fragment_shader.c)
> diff --git a/tests/spec/gl-2.0/two-sided-stencil.c b/tests/spec/gl-2.0/two-sided-stencil.c
> new file mode 100644
> index 0000000..debbfab
> --- /dev/null
> +++ b/tests/spec/gl-2.0/two-sided-stencil.c
> @@ -0,0 +1,745 @@
> +/*
> + * BEGIN_COPYRIGHT -*- glean -*-
> + *
> + * Copyright (C) 1999 Allen Akin All Rights Reserved.
> + * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
> + * Copyright (C) 2015 Intel Corporation All Rights Reserved.
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the "Software"),
> + * to deal in the Software without restriction, including without limitation
> + * the rights to use, copy, modify, merge, publish, distribute, sublicense,
> + * and/or sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the next
> + * paragraph) shall be included in all copies or substantial portions of the
> + * Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
> + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
> + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
> + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
> + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
> + * DEALINGS IN THE SOFTWARE.
> + *
> + * END_COPYRIGHT
> + */
> +
> +/** @file two-sided-stencil.c
> + *
> + * Test two-sided stencil extensions
> + *
> + * This test could be better:
> + * 1. Generate random state vectors, render and compare to expected values
> + * 2. Exercise separate front/back reference values and masks for the
> + * EXT and GL2 variations.
> + *
> + * Note: Must check writeMask of set_stencil_state to make sure it's correct
> + *
> + * Authors:
> + * Brian Paul <brianp at valinux.com>
> + * Adapted to Piglit by Juliet Fru <julietfru at gmail.com>, September 2015.
> + */
> +
> +#include "piglit-util-gl.h"
> +
> +#include <assert.h>
> +#include <string.h>
> +
> +
> +PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 20;
> +
> +config.window_visual =
> + PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH |
> + PIGLIT_GL_VISUAL_STENCIL;
> +
> +PIGLIT_GL_TEST_CONFIG_END
> +
> +/* two-sided methods. */
> +#define ATI 1
> +#define EXT 2
> +#define GL2 3
> +
> +GLint stencil_bits, stencil_max;
> +
> +
> +static bool
> +have_stencil_wrap(void)
> +{
> + if (piglit_get_gl_version() >= 2.0) {
> + return true;
> + } else if (piglit_is_extension_supported("GL_EXT_stencil_wrap")) {
> + return true;
> + }
> + return false;
> +}
> +
> +
> +/* Draw four quads:
> + * Bottom row uses GL_CCW
> + * Top row uses GL_CW
> + * Left column is front-facing
> + * Right column is back-facing
> + * Check the values in the stencil buffer to see if they match
> + * the expected values.
> + */
> +static bool
> +render_test(GLuint expectedFront, GLuint expectedBack)
> +{
> + GLint x0 = 0;
> + GLint x1 = piglit_width / 2;
> + GLint x2 = piglit_width;
> + GLint y0 = 0;
> + GLint y1 = piglit_width / 2;
> + GLint y2 = piglit_width;
> +
> + glFrontFace(GL_CCW); /* this the GL default */
> +
> + /* lower left quad = front-facing */
> + glBegin(GL_TRIANGLE_FAN);
> + glVertex2f(x0, y0);
> + glVertex2f(x1, y0);
> + glVertex2f(x1, y1);
> + glVertex2f(x0, y1);
> + glEnd();
> +
> + /* lower right quad = back-facing */
> + glBegin(GL_TRIANGLE_FAN);
> + glVertex2f(x1, y0);
> + glVertex2f(x1, y1);
> + glVertex2f(x2, y1);
> + glVertex2f(x2, y0);
> + glEnd();
> +
> + glFrontFace(GL_CW);
> +
> + /* upper left quad = front-facing */
> + glBegin(GL_TRIANGLE_FAN);
> + glVertex2f(x0, y1);
> + glVertex2f(x0, y2);
> + glVertex2f(x1, y2);
> + glVertex2f(x1, y1);
> + glEnd();
> +
> + /* upper right quad = back-facing */
> + glBegin(GL_TRIANGLE_FAN);
> + glVertex2f(x1, y1);
> + glVertex2f(x2, y1);
> + glVertex2f(x2, y2);
> + glVertex2f(x1, y2);
> + glEnd();
> +
> + GLint midXleft = (x0 + x1) / 2;
> + GLint midXright = (x1 + x2) / 2;
> + GLint midYlower = (y0 + y1) / 2;
> + GLint midYupper = (y1 + y2) / 2;
> + GLuint lowerLeftVal, lowerRightVal;
> + GLuint upperLeftVal, upperRightVal;
> +
> + glReadPixels(midXleft, midYlower, 1, 1,
> + GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerLeftVal);
> + glReadPixels(midXright, midYlower, 1, 1,
> + GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerRightVal);
> +
> + glReadPixels(midXleft, midYupper, 1, 1,
> + GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperLeftVal);
> + glReadPixels(midXright, midYupper, 1, 1,
> + GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperRightVal);
> +
> + if (lowerLeftVal != upperLeftVal) {
> + printf(" FAIL:\n"
> + "\tLower-left value (%d) doesn't match upper-left "
> + "value (%d).\n \t Looks like a front/back "
> + "orientation bug.\n", lowerLeftVal, upperLeftVal);
> + return false;
> + }
> +
> + if (lowerRightVal != upperRightVal) {
> + printf(" FAIL:\n\tLower-right value (%d) doesn't match"
> + " upper-right value (%d).\n\tLooks like "
> + "a front/back-face orientation bug.\n", lowerRightVal,
> + upperRightVal);
> + return false;
> + }
> +
> +
> + if (lowerLeftVal != expectedFront) {
> + printf("FAIL:\n\tExpected front-face stencil value is "
> + "%d but found %d \n", expectedFront, lowerLeftVal);
> + return false;
> + } else if (lowerRightVal != expectedBack) {
> + printf("FAIL:\n\tExpected back-face stencil value is "
> + "%d but found %d \n", expectedBack, lowerRightVal);
> + return false;
> + } else {
> + return true;
> + }
> +}
> +
> +
> +static bool
> +compare_state(int method, GLenum found, GLenum expected, const char *msg)
> +{
> + if (found != expected) {
> + printf(" FAIL:\n\tQuery of %s state failed for ", msg);
> + switch (method) {
> + case ATI:
> + printf("GL_ATI_separate_stencil\n");
> + break;
> + case EXT:
> + printf("GL_EXT_stencil_two_side\n");
> + break;
> + case GL2:
> + printf("GL 2.x two-sided stencil\n");
> + break;
> + default:
> + printf("\n");
> + assert(0);
> + }
> +
> + printf("\tFound 0x%x, expected 0x%x\n", found, expected);
> + return false;
> + }
> + return true;
> +}
> +
> +
> +/* Set stencil state, plus read it back and check that it's correct.
> + * Note: we only test with one reference value and one mask value
> + * even though EXT and GL2 support separate front/back refs/masks
> + */
> +static bool
> +set_stencil_state(int method,
> + GLenum frontStencilFail,
> + GLenum backStencilFail,
> + GLenum frontZFail,
> + GLenum backZFail,
> + GLenum frontZPass,
> + GLenum backZPass,
> + GLenum frontFunc,
> + GLenum backFunc,
> + GLint frontRef,
> + GLint backRef,
> + GLuint frontMask,
> + GLuint backMask,
> + GLuint frontWriteMask, GLuint backWriteMask)
> +{
> + GLint get_frontStencilFail;
> + GLint get_backStencilFail;
> + GLint get_frontZFail;
> + GLint get_backZFail;
> + GLint get_frontZPass;
> + GLint get_backZPass;
> + GLint get_frontFunc;
> + GLint get_backFunc;
> + GLint get_frontRef;
> + GLint get_backRef;
> + GLint get_frontMask;
> + GLint get_backMask;
> + GLint get_frontWriteMask;
> + GLint get_backWriteMask;
> + GLint twoEnabled;
> +
> + switch (method) {
> + case ATI:
> + assert(frontRef == backRef);
> + assert(frontMask == backMask);
> + assert(frontWriteMask == backWriteMask);
> +
> + /* set state */
> + glStencilOpSeparateATI(GL_FRONT,
> + frontStencilFail,
> + frontZFail, frontZPass);
> +
> + glStencilOpSeparateATI(GL_BACK,
> + backStencilFail, backZFail, backZPass);
> +
> + glStencilFuncSeparateATI(frontFunc, backFunc, frontRef,
> + frontMask);
> +
> + glStencilMask(frontWriteMask);
> +
> + /* get state */
> + glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
> + glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
> + glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
> + glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
> + glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
> +
> + glGetIntegerv(GL_STENCIL_BACK_FUNC_ATI, &get_backFunc);
> + glGetIntegerv(GL_STENCIL_BACK_FAIL_ATI, &get_backStencilFail);
> + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI,
> + &get_backZFail);
> + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI,
> + &get_backZPass);
> + get_backRef = get_frontRef;
> + get_backMask = get_frontMask;
> + get_backWriteMask = get_frontWriteMask;
> + twoEnabled = GL_TRUE;
> + break;
> +
> + case EXT:
> + /* set state */
> + glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
> +
> + glActiveStencilFaceEXT(GL_FRONT);
> + glStencilOp(frontStencilFail, frontZFail, frontZPass);
> + glStencilFunc(frontFunc, frontRef, frontMask);
> + glStencilMask(frontWriteMask);
> +
> + glActiveStencilFaceEXT(GL_BACK);
> + glStencilOp(backStencilFail, backZFail, backZPass);
> + glStencilFunc(backFunc, backRef, backMask);
> + glStencilMask(backWriteMask);
> +
> + /* get state */
> + glActiveStencilFaceEXT(GL_FRONT);
> + glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
> + glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
> + glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
> + glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
> + glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
> + glActiveStencilFaceEXT(GL_BACK);
> + glGetIntegerv(GL_STENCIL_FAIL, &get_backStencilFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_backZFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_backZPass);
> + glGetIntegerv(GL_STENCIL_FUNC, &get_backFunc);
> + glGetIntegerv(GL_STENCIL_REF, &get_backRef);
> + glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_backMask);
> + glGetIntegerv(GL_STENCIL_WRITEMASK, &get_backWriteMask);
> + glGetIntegerv(GL_STENCIL_TEST_TWO_SIDE_EXT, &twoEnabled);
> + break;
> +
> + case GL2:
> + /* set state */
> + glStencilOpSeparate(GL_FRONT,
> + frontStencilFail, frontZFail, frontZPass);
> + glStencilOpSeparate(GL_BACK,
> + backStencilFail, backZFail, backZPass);
> + glStencilFuncSeparate(GL_FRONT, frontFunc, frontRef,
> + frontMask);
> + glStencilFuncSeparate(GL_BACK, backFunc, backRef, backMask);
> + glStencilMaskSeparate(GL_FRONT, frontWriteMask);
> + glStencilMaskSeparate(GL_BACK, backWriteMask);
> +
> + /* get state */
> + glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
> + glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
> + glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
> + glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
> + glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
> + glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
> +
> + glGetIntegerv(GL_STENCIL_BACK_FUNC, &get_backFunc);
> + glGetIntegerv(GL_STENCIL_BACK_FAIL, &get_backStencilFail);
> + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL,
> + &get_backZFail);
> + glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS,
> + &get_backZPass);
> + glGetIntegerv(GL_STENCIL_BACK_REF, &get_backRef);
> + glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &get_backMask);
> + glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &get_backWriteMask);
> + twoEnabled = GL_TRUE;
> + break;
> +
> + default:
> + assert(0);
> + }
> +
> + /* mask off bits we don't care about */
> + get_frontMask &= stencil_max;
> + frontMask &= stencil_max;
> + get_backMask &= stencil_max;
> + backMask &= stencil_max;
> + get_frontWriteMask &= stencil_max;
> + frontWriteMask &= stencil_max;
> + get_backWriteMask &= stencil_max;
> + backWriteMask &= stencil_max;
> +
> +
> + if (!piglit_check_gl_error(GL_NO_ERROR)) {
> + return false;
> + }
> +
> + /* see if state-get matches state-set */
> +
> + if (!compare_state(method, get_frontStencilFail, frontStencilFail,
> + "front stencil fail"))
> + return false;
> +
> + if (!compare_state(method, get_backStencilFail, backStencilFail,
> + "back stencil fail"))
> + return false;
> +
> + if (!compare_state(method, get_frontZFail, frontZFail,
> + "front Z fail"))
> + return false;
> +
> + if (!compare_state(method, get_backZFail, backZFail, "back Z fail"))
> + return false;
> +
> + if (!compare_state(method, get_frontZPass, frontZPass,
> + "front Z pass"))
> + return false;
> +
> + if (!compare_state(method, get_backZPass, backZPass, "back Z pass"))
> + return false;
> +
> + if (!compare_state(method, get_frontFunc, frontFunc,
> + "front stencil func"))
> + return false;
> +
> + if (!compare_state(method, get_backFunc, backFunc,
> + "back stencil func"))
> + return false;
> +
> + if (!compare_state(method, get_frontRef, frontRef,
> + "front stencil ref"))
> + return false;
> +
> + if (!compare_state(method, get_backRef, backRef, "back stencil ref"))
> + return false;
> +
> + if (!compare_state(method, get_frontMask, frontMask,
> + "front stencil mask"))
> + return false;
> +
> + if (!compare_state(method, get_backMask, backMask,
> + "back stencil mask"))
> + return false;
> +
> + if (!compare_state(method, get_frontWriteMask, frontWriteMask,
> + "front stencil writemask"))
> + return false;
> +
> + if (!compare_state(method, get_backWriteMask, backWriteMask,
> + "back stencil writemask"))
> + return false;
> +
> + if (!compare_state(method, twoEnabled, GL_TRUE, "two-side enable"))
> + return false;
> +
> + return true;
> +}
> +
> +
> +static bool
> +set_stencil_state2(int method,
> + GLenum frontStencilFail,
> + GLenum backStencilFail,
> + GLenum frontZFail,
> + GLenum backZFail,
> + GLenum frontZPass,
> + GLenum backZPass,
> + GLenum frontFunc,
> + GLenum backFunc, GLint ref, GLuint mask, GLuint writeMask)
One parameter per line, for consistency.
> +{
> + return set_stencil_state(method, frontStencilFail, backStencilFail, frontZFail, backZFail, frontZPass, backZPass, frontFunc, backFunc, ref, /* frontRef */
> + ref, /* backRef */
> + mask, /* frontMask */
> + mask, /* backMask */
> + writeMask, /* frontWriteMask */
> + writeMask); /* backWriteMask */
The formatting of those function call arguments could be cleaned up.
The first line is way too long.
> +}
> +
> +
> +void
> +reset_stencil_state(int method)
> +{
> + switch (method) {
> + case ATI:
> + break;
> + case EXT:
> + glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
> + glActiveStencilFaceEXT(GL_FRONT);
> + break;
> + case GL2:
> + break;
> + default:
> + assert(0);
> + }
> +}
> +
> +
> +static bool
> +test_stencil(int method)
> +{
> + bool pass;
> +
> + glEnable(GL_STENCIL_TEST);
> +
> + /**
> + * No depth testing
> + */
> + glDisable(GL_DEPTH_TEST);
> +
> + glClear(GL_COLOR_BUFFER_BIT |
> + GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> +
> + /* set stencil buffer vals to 5 */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_REPLACE, GL_REPLACE, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 5, ~0, ~0); /* ref, mask, set white_mask to ~0 */
white_mask -> write_mask, here and below
> + if (pass)
> + pass = render_test(5, 5);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> + /* incr front val to 6, decr back val to 4 */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_INCR, GL_DECR, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 5, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(6, 4);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> + /* if front==6, keep
> + * if back<6, replace with zero
> + * final: front=6, back=0
> + */
> + pass = set_stencil_state2(method, GL_KEEP, GL_ZERO, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_KEEP, GL_KEEP, /* z pass */
> + GL_EQUAL, GL_LESS, /* stencil func */
> + 6, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(6, 0);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> + /* if front!=10, keep, else decr
> + * if back<10, keep, else incr
> + * final: front=6, back=1
> + */
> + pass = set_stencil_state2(method, GL_DECR, GL_INCR, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_KEEP, GL_KEEP, /* z pass */
> + GL_NOTEQUAL, GL_LESS, /* stencil func */
> + 10, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(6, 1);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> + if (method != ATI) {
> + /* if front!=10, keep, else decr
> + * if back<10, keep, else incr
> + * final: front=6, back=1
> + */
> + pass = set_stencil_state(method, GL_DECR, GL_INCR, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_REPLACE, GL_REPLACE, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 0xf6, 0xf1, /* ref */
> + 0xff, 0xff, /* mask */
> + 0x60, 0x10); /* writeMask */
> + if (pass)
> + pass = render_test(0x66, 0x11);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> + }
> +
> + /* reset write mask for clear */
> + set_stencil_state(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_REPLACE, GL_REPLACE, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 0, 0, ~0, ~0, ~0, ~0);
> +
> + /* ============================================================
> + * Now begin tests with depth test
> + */
> + glEnable(GL_DEPTH_TEST);
> + glDepthFunc(GL_LESS);
> +
> + glClear(GL_COLOR_BUFFER_BIT |
> + GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> + /* set stencil buffer vals to 7, set Z values */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_REPLACE, GL_REPLACE, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 7, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(7, 7);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + /* GL_LESS test should fail everywhere
> + * decr front to 5, incr back to 2
> + */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_DECR, GL_INCR, /* z fail */
> + GL_KEEP, GL_KEEP, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 99, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(6, 8);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + /* set depth test = GL_EQUAL
> + * Z test should pass everywhere
> + * set front to 3
> + * decr back to 7
> + */
> + glDepthFunc(GL_EQUAL);
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_REPLACE, GL_DECR, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 3, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(3, 7);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + /* incr front to 4 (by z pass), decr back to 6 (by stencil fail) */
> + pass = set_stencil_state2(method, GL_DECR, GL_DECR, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_INCR, GL_REPLACE, /* z pass */
> + GL_EQUAL, GL_EQUAL, /* stencil func */
> + 3, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(4, 6);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + /* ============================================================
> + * Disable depth test
> + */
> + glDisable(GL_DEPTH_TEST);
> +
> + /* test stencil value mask
> + * only test bit 1 in stencil values
> + * if !(front&0x2 == 15&0x2), decr to 3 (should happen)
> + * if !(back&0x2 == 15&0x2), incr to 7 (should not happen)
> + */
> + pass = set_stencil_state2(method, GL_DECR, GL_INCR, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_KEEP, GL_KEEP, /* z pass */
> + GL_EQUAL, GL_EQUAL, /* stencil func */
> + 15, 0x2, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(3, 6);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> + /* ============================================================
> + * Test common two-sided stencil modes for shadow volume rendering
> + * Requires stencil /- wrap feature.
> + */
> +
> + if (!have_stencil_wrap())
> + return true;
> +
> + glClear(GL_COLOR_BUFFER_BIT |
> + GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
> +
> + glEnable(GL_DEPTH_TEST);
> + glDepthFunc(GL_LESS);
> +
> + /* "traditional / Z-pass" method:
> + * front face: incr on zpass
> + * back face: decr on zpass
> + * both front and back Z-test should pass here
> + */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_KEEP, GL_KEEP, /* z fail */
> + GL_INCR_WRAP_EXT, GL_DECR_WRAP_EXT, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 0, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(1, stencil_max);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + /* "Z-fail" method:
> + * front face: decr on zfail
> + * back face: incr on zfail
> + * both front and back Z-test should fail here
> + */
> + pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
> + GL_DECR_WRAP_EXT, GL_INCR_WRAP_EXT, /* z fail */
> + GL_KEEP, GL_KEEP, /* z pass */
> + GL_ALWAYS, GL_ALWAYS, /* stencil func */
> + 0, ~0, ~0); /* ref, mask, set white_mask to ~0 */
> + if (pass)
> + pass = render_test(0, 0);
> + reset_stencil_state(method);
> + if (!pass)
> + return false;
> +
> +
> + return true;
> +}
> +
> +
> +void
> +piglit_init(int argc, char **argv)
> +{
> + /* no initialization */
> +}
> +
> +
> +enum piglit_result
> +piglit_display(void)
> +{
> + bool pass = true;
> +
> + /* how many stencil bits (we assume at least 8 above) */
> + glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
> + stencil_max = (1 << stencil_bits) - 1;
> + assert(stencil_bits >= 8);
> +
> + glViewport(0, 0, piglit_width, piglit_width);
> + glMatrixMode(GL_PROJECTION);
> + glLoadIdentity();
> + glOrtho(0, piglit_width, 0, piglit_width, -1, 1);
> + glMatrixMode(GL_MODELVIEW);
> + glLoadIdentity();
> +
> + if (piglit_is_extension_supported("GL_ATI_separate_stencil")) {
> + pass = test_stencil(ATI) && pass;
> + }
> +
> + if (piglit_is_extension_supported("GL_EXT_stencil_two_side")) {
> + pass = test_stencil(EXT) && pass;
> + }
> +
> + if (piglit_get_gl_version() >= 2.0) {
> + pass = test_stencil(GL2) && pass;
> + }
> +
> + return pass ? PIGLIT_PASS : PIGLIT_FAIL;
> +}
>
More information about the Piglit
mailing list