conversion-explicit: use a different value for normalized +/- min
[piglit.git] / tests / spec / gl-2.0 / two-sided-stencil.c
blob66284c6b9c7d9af6c7e172509a71105e7205389a
1 /*
2 * BEGIN_COPYRIGHT -*- glean -*-
4 * Copyright (C) 1999 Allen Akin All Rights Reserved.
5 * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
6 * Copyright (C) 2015 Intel Corporation All Rights Reserved.
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
27 * END_COPYRIGHT
30 /** @file two-sided-stencil.c
32 * Test two-sided stencil extensions
34 * This test could be better:
35 * 1. Generate random state vectors, render and compare to expected values
36 * 2. Exercise separate front/back reference values and masks for the
37 * EXT and GL2 variations.
39 * Note: Must check writeMask of set_stencil_state to make sure it's correct
41 * Authors:
42 * Brian Paul <brianp@valinux.com>
43 * Adapted to Piglit by Juliet Fru <julietfru@gmail.com>, September 2015.
46 #include "piglit-util-gl.h"
48 #include <assert.h>
49 #include <string.h>
52 PIGLIT_GL_TEST_CONFIG_BEGIN config.supports_gl_compat_version = 20;
54 config.window_visual =
55 PIGLIT_GL_VISUAL_RGBA | PIGLIT_GL_VISUAL_DEPTH |
56 PIGLIT_GL_VISUAL_STENCIL;
57 config.khr_no_error_support = PIGLIT_NO_ERRORS;
59 PIGLIT_GL_TEST_CONFIG_END
61 /* two-sided methods. */
62 #define ATI 1
63 #define EXT 2
64 #define GL2 3
66 GLint stencil_bits, stencil_max;
69 static bool
70 have_stencil_wrap(void)
72 if (piglit_get_gl_version() >= 2.0) {
73 return true;
74 } else if (piglit_is_extension_supported("GL_EXT_stencil_wrap")) {
75 return true;
77 return false;
81 /* Draw four quads:
82 * Bottom row uses GL_CCW
83 * Top row uses GL_CW
84 * Left column is front-facing
85 * Right column is back-facing
86 * Check the values in the stencil buffer to see if they match
87 * the expected values.
89 static bool
90 render_test(GLuint expectedFront, GLuint expectedBack)
92 GLint x0 = 0;
93 GLint x1 = piglit_width / 2;
94 GLint x2 = piglit_width;
95 GLint y0 = 0;
96 GLint y1 = piglit_width / 2;
97 GLint y2 = piglit_width;
99 glFrontFace(GL_CCW); /* this the GL default */
101 /* lower left quad = front-facing */
102 glBegin(GL_TRIANGLE_FAN);
103 glVertex2f(x0, y0);
104 glVertex2f(x1, y0);
105 glVertex2f(x1, y1);
106 glVertex2f(x0, y1);
107 glEnd();
109 /* lower right quad = back-facing */
110 glBegin(GL_TRIANGLE_FAN);
111 glVertex2f(x1, y0);
112 glVertex2f(x1, y1);
113 glVertex2f(x2, y1);
114 glVertex2f(x2, y0);
115 glEnd();
117 glFrontFace(GL_CW);
119 /* upper left quad = front-facing */
120 glBegin(GL_TRIANGLE_FAN);
121 glVertex2f(x0, y1);
122 glVertex2f(x0, y2);
123 glVertex2f(x1, y2);
124 glVertex2f(x1, y1);
125 glEnd();
127 /* upper right quad = back-facing */
128 glBegin(GL_TRIANGLE_FAN);
129 glVertex2f(x1, y1);
130 glVertex2f(x2, y1);
131 glVertex2f(x2, y2);
132 glVertex2f(x1, y2);
133 glEnd();
135 GLint midXleft = (x0 + x1) / 2;
136 GLint midXright = (x1 + x2) / 2;
137 GLint midYlower = (y0 + y1) / 2;
138 GLint midYupper = (y1 + y2) / 2;
139 GLuint lowerLeftVal, lowerRightVal;
140 GLuint upperLeftVal, upperRightVal;
142 glReadPixels(midXleft, midYlower, 1, 1,
143 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerLeftVal);
144 glReadPixels(midXright, midYlower, 1, 1,
145 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &lowerRightVal);
147 glReadPixels(midXleft, midYupper, 1, 1,
148 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperLeftVal);
149 glReadPixels(midXright, midYupper, 1, 1,
150 GL_STENCIL_INDEX, GL_UNSIGNED_INT, &upperRightVal);
152 if (lowerLeftVal != upperLeftVal) {
153 printf(" FAIL:\n"
154 "\tLower-left value (%d) doesn't match upper-left "
155 "value (%d).\n \t Looks like a front/back "
156 "orientation bug.\n", lowerLeftVal, upperLeftVal);
157 return false;
160 if (lowerRightVal != upperRightVal) {
161 printf(" FAIL:\n\tLower-right value (%d) doesn't match"
162 " upper-right value (%d).\n\tLooks like "
163 "a front/back-face orientation bug.\n", lowerRightVal,
164 upperRightVal);
165 return false;
169 if (lowerLeftVal != expectedFront) {
170 printf("FAIL:\n\tExpected front-face stencil value is "
171 "%d but found %d \n", expectedFront, lowerLeftVal);
172 return false;
173 } else if (lowerRightVal != expectedBack) {
174 printf("FAIL:\n\tExpected back-face stencil value is "
175 "%d but found %d \n", expectedBack, lowerRightVal);
176 return false;
177 } else {
178 return true;
183 static bool
184 compare_state(int method, GLenum found, GLenum expected, const char *msg)
186 if (found != expected) {
187 printf(" FAIL:\n\tQuery of %s state failed for ", msg);
188 switch (method) {
189 case ATI:
190 printf("GL_ATI_separate_stencil\n");
191 break;
192 case EXT:
193 printf("GL_EXT_stencil_two_side\n");
194 break;
195 case GL2:
196 printf("GL 2.x two-sided stencil\n");
197 break;
198 default:
199 printf("\n");
200 assert(0);
203 printf("\tFound 0x%x, expected 0x%x\n", found, expected);
204 return false;
206 return true;
210 /* Set stencil state, plus read it back and check that it's correct.
211 * Note: we only test with one reference value and one mask value
212 * even though EXT and GL2 support separate front/back refs/masks
214 static bool
215 set_stencil_state(int method,
216 GLenum frontStencilFail,
217 GLenum backStencilFail,
218 GLenum frontZFail,
219 GLenum backZFail,
220 GLenum frontZPass,
221 GLenum backZPass,
222 GLenum frontFunc,
223 GLenum backFunc,
224 GLint frontRef,
225 GLint backRef,
226 GLuint frontMask,
227 GLuint backMask,
228 GLuint frontWriteMask, GLuint backWriteMask)
230 GLint get_frontStencilFail;
231 GLint get_backStencilFail;
232 GLint get_frontZFail;
233 GLint get_backZFail;
234 GLint get_frontZPass;
235 GLint get_backZPass;
236 GLint get_frontFunc;
237 GLint get_backFunc;
238 GLint get_frontRef;
239 GLint get_backRef;
240 GLint get_frontMask;
241 GLint get_backMask;
242 GLint get_frontWriteMask;
243 GLint get_backWriteMask;
244 GLint twoEnabled;
246 switch (method) {
247 case ATI:
248 assert(frontRef == backRef);
249 assert(frontMask == backMask);
250 assert(frontWriteMask == backWriteMask);
252 /* set state */
253 glStencilOpSeparateATI(GL_FRONT,
254 frontStencilFail,
255 frontZFail, frontZPass);
257 glStencilOpSeparateATI(GL_BACK,
258 backStencilFail, backZFail, backZPass);
260 glStencilFuncSeparateATI(frontFunc, backFunc, frontRef,
261 frontMask);
263 glStencilMask(frontWriteMask);
265 /* get state */
266 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
267 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
268 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
269 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
270 glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
271 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
272 glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
274 glGetIntegerv(GL_STENCIL_BACK_FUNC_ATI, &get_backFunc);
275 glGetIntegerv(GL_STENCIL_BACK_FAIL_ATI, &get_backStencilFail);
276 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI,
277 &get_backZFail);
278 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI,
279 &get_backZPass);
280 get_backRef = get_frontRef;
281 get_backMask = get_frontMask;
282 get_backWriteMask = get_frontWriteMask;
283 twoEnabled = GL_TRUE;
284 break;
286 case EXT:
287 /* set state */
288 glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
290 glActiveStencilFaceEXT(GL_FRONT);
291 glStencilOp(frontStencilFail, frontZFail, frontZPass);
292 glStencilFunc(frontFunc, frontRef, frontMask);
293 glStencilMask(frontWriteMask);
295 glActiveStencilFaceEXT(GL_BACK);
296 glStencilOp(backStencilFail, backZFail, backZPass);
297 glStencilFunc(backFunc, backRef, backMask);
298 glStencilMask(backWriteMask);
300 /* get state */
301 glActiveStencilFaceEXT(GL_FRONT);
302 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
303 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
304 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
305 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
306 glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
307 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
308 glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
309 glActiveStencilFaceEXT(GL_BACK);
310 glGetIntegerv(GL_STENCIL_FAIL, &get_backStencilFail);
311 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_backZFail);
312 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_backZPass);
313 glGetIntegerv(GL_STENCIL_FUNC, &get_backFunc);
314 glGetIntegerv(GL_STENCIL_REF, &get_backRef);
315 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_backMask);
316 glGetIntegerv(GL_STENCIL_WRITEMASK, &get_backWriteMask);
317 glGetIntegerv(GL_STENCIL_TEST_TWO_SIDE_EXT, &twoEnabled);
318 break;
320 case GL2:
321 /* set state */
322 glStencilOpSeparate(GL_FRONT,
323 frontStencilFail, frontZFail, frontZPass);
324 glStencilOpSeparate(GL_BACK,
325 backStencilFail, backZFail, backZPass);
326 glStencilFuncSeparate(GL_FRONT, frontFunc, frontRef,
327 frontMask);
328 glStencilFuncSeparate(GL_BACK, backFunc, backRef, backMask);
329 glStencilMaskSeparate(GL_FRONT, frontWriteMask);
330 glStencilMaskSeparate(GL_BACK, backWriteMask);
332 /* get state */
333 glGetIntegerv(GL_STENCIL_FAIL, &get_frontStencilFail);
334 glGetIntegerv(GL_STENCIL_PASS_DEPTH_FAIL, &get_frontZFail);
335 glGetIntegerv(GL_STENCIL_PASS_DEPTH_PASS, &get_frontZPass);
336 glGetIntegerv(GL_STENCIL_FUNC, &get_frontFunc);
337 glGetIntegerv(GL_STENCIL_REF, &get_frontRef);
338 glGetIntegerv(GL_STENCIL_VALUE_MASK, &get_frontMask);
339 glGetIntegerv(GL_STENCIL_WRITEMASK, &get_frontWriteMask);
341 glGetIntegerv(GL_STENCIL_BACK_FUNC, &get_backFunc);
342 glGetIntegerv(GL_STENCIL_BACK_FAIL, &get_backStencilFail);
343 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_FAIL,
344 &get_backZFail);
345 glGetIntegerv(GL_STENCIL_BACK_PASS_DEPTH_PASS,
346 &get_backZPass);
347 glGetIntegerv(GL_STENCIL_BACK_REF, &get_backRef);
348 glGetIntegerv(GL_STENCIL_BACK_VALUE_MASK, &get_backMask);
349 glGetIntegerv(GL_STENCIL_BACK_WRITEMASK, &get_backWriteMask);
350 twoEnabled = GL_TRUE;
351 break;
353 default:
354 assert(0);
357 /* mask off bits we don't care about */
358 get_frontMask &= stencil_max;
359 frontMask &= stencil_max;
360 get_backMask &= stencil_max;
361 backMask &= stencil_max;
362 get_frontWriteMask &= stencil_max;
363 frontWriteMask &= stencil_max;
364 get_backWriteMask &= stencil_max;
365 backWriteMask &= stencil_max;
368 if (!piglit_check_gl_error(GL_NO_ERROR)) {
369 return false;
372 /* see if state-get matches state-set */
374 if (!compare_state(method, get_frontStencilFail, frontStencilFail,
375 "front stencil fail"))
376 return false;
378 if (!compare_state(method, get_backStencilFail, backStencilFail,
379 "back stencil fail"))
380 return false;
382 if (!compare_state(method, get_frontZFail, frontZFail,
383 "front Z fail"))
384 return false;
386 if (!compare_state(method, get_backZFail, backZFail, "back Z fail"))
387 return false;
389 if (!compare_state(method, get_frontZPass, frontZPass,
390 "front Z pass"))
391 return false;
393 if (!compare_state(method, get_backZPass, backZPass, "back Z pass"))
394 return false;
396 if (!compare_state(method, get_frontFunc, frontFunc,
397 "front stencil func"))
398 return false;
400 if (!compare_state(method, get_backFunc, backFunc,
401 "back stencil func"))
402 return false;
404 if (!compare_state(method, get_frontRef, frontRef,
405 "front stencil ref"))
406 return false;
408 if (!compare_state(method, get_backRef, backRef, "back stencil ref"))
409 return false;
411 if (!compare_state(method, get_frontMask, frontMask,
412 "front stencil mask"))
413 return false;
415 if (!compare_state(method, get_backMask, backMask,
416 "back stencil mask"))
417 return false;
419 if (!compare_state(method, get_frontWriteMask, frontWriteMask,
420 "front stencil writemask"))
421 return false;
423 if (!compare_state(method, get_backWriteMask, backWriteMask,
424 "back stencil writemask"))
425 return false;
427 if (!compare_state(method, twoEnabled, GL_TRUE, "two-side enable"))
428 return false;
430 return true;
434 static bool
435 set_stencil_state2(int method,
436 GLenum frontStencilFail,
437 GLenum backStencilFail,
438 GLenum frontZFail,
439 GLenum backZFail,
440 GLenum frontZPass,
441 GLenum backZPass,
442 GLenum frontFunc,
443 GLenum backFunc,
444 GLint ref,
445 GLuint mask,
446 GLuint writeMask)
448 return set_stencil_state(method, frontStencilFail,
449 backStencilFail, frontZFail, backZFail,
450 frontZPass, backZPass, frontFunc, backFunc,
451 ref, /* frontRef */
452 ref, /* backRef */
453 mask, /* frontMask */
454 mask, /* backMask */
455 writeMask, /* frontWriteMask */
456 writeMask); /* backWriteMask */
460 void
461 reset_stencil_state(int method)
463 switch (method) {
464 case ATI:
465 break;
466 case EXT:
467 glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
468 glActiveStencilFaceEXT(GL_FRONT);
469 break;
470 case GL2:
471 break;
472 default:
473 assert(0);
478 static bool
479 test_stencil(int method)
481 bool pass;
483 glEnable(GL_STENCIL_TEST);
486 * No depth testing
488 glDisable(GL_DEPTH_TEST);
490 glClear(GL_COLOR_BUFFER_BIT |
491 GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
494 /* set stencil buffer vals to 5 */
495 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
496 GL_KEEP, GL_KEEP, /* z fail */
497 GL_REPLACE, GL_REPLACE, /* z pass */
498 GL_ALWAYS, GL_ALWAYS, /* stencil func */
499 5, ~0, ~0); /* ref, mask, set write_mask to ~0 */
500 if (pass)
501 pass = render_test(5, 5);
502 reset_stencil_state(method);
503 if (!pass)
504 return false;
506 /* incr front val to 6, decr back val to 4 */
507 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
508 GL_KEEP, GL_KEEP, /* z fail */
509 GL_INCR, GL_DECR, /* z pass */
510 GL_ALWAYS, GL_ALWAYS, /* stencil func */
511 5, ~0, ~0); /* ref, mask, set write_mask to ~0 */
512 if (pass)
513 pass = render_test(6, 4);
514 reset_stencil_state(method);
515 if (!pass)
516 return false;
518 /* if front==6, keep
519 * if back<6, replace with zero
520 * final: front=6, back=0
522 pass = set_stencil_state2(method, GL_KEEP, GL_ZERO, /* stencil fail */
523 GL_KEEP, GL_KEEP, /* z fail */
524 GL_KEEP, GL_KEEP, /* z pass */
525 GL_EQUAL, GL_LESS, /* stencil func */
526 6, ~0, ~0); /* ref, mask, set write_mask to ~0 */
527 if (pass)
528 pass = render_test(6, 0);
529 reset_stencil_state(method);
530 if (!pass)
531 return false;
533 /* if front!=10, keep, else decr
534 * if back<10, keep, else incr
535 * final: front=6, back=1
537 pass = set_stencil_state2(method, GL_DECR, GL_INCR, /* stencil fail */
538 GL_KEEP, GL_KEEP, /* z fail */
539 GL_KEEP, GL_KEEP, /* z pass */
540 GL_NOTEQUAL, GL_LESS, /* stencil func */
541 10, ~0, ~0); /* ref, mask, set write_mask to ~0 */
542 if (pass)
543 pass = render_test(6, 1);
544 reset_stencil_state(method);
545 if (!pass)
546 return false;
548 if (method != ATI) {
549 /* if front!=10, keep, else decr
550 * if back<10, keep, else incr
551 * final: front=6, back=1
553 pass = set_stencil_state(method, GL_DECR, GL_INCR, /* stencil fail */
554 GL_KEEP, GL_KEEP, /* z fail */
555 GL_REPLACE, GL_REPLACE, /* z pass */
556 GL_ALWAYS, GL_ALWAYS, /* stencil func */
557 0xf6, 0xf1, /* ref */
558 0xff, 0xff, /* mask */
559 0x60, 0x10); /* writeMask */
560 if (pass)
561 pass = render_test(0x66, 0x11);
562 reset_stencil_state(method);
563 if (!pass)
564 return false;
567 /* reset write mask for clear */
568 set_stencil_state(method, GL_KEEP, GL_KEEP, /* stencil fail */
569 GL_KEEP, GL_KEEP, /* z fail */
570 GL_REPLACE, GL_REPLACE, /* z pass */
571 GL_ALWAYS, GL_ALWAYS, /* stencil func */
572 0, 0, ~0, ~0, ~0, ~0);
574 /* ============================================================
575 * Now begin tests with depth test
577 glEnable(GL_DEPTH_TEST);
578 glDepthFunc(GL_LESS);
580 glClear(GL_COLOR_BUFFER_BIT |
581 GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
583 /* set stencil buffer vals to 7, set Z values */
584 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
585 GL_KEEP, GL_KEEP, /* z fail */
586 GL_REPLACE, GL_REPLACE, /* z pass */
587 GL_ALWAYS, GL_ALWAYS, /* stencil func */
588 7, ~0, ~0); /* ref, mask, set write_mask to ~0 */
589 if (pass)
590 pass = render_test(7, 7);
591 reset_stencil_state(method);
592 if (!pass)
593 return false;
596 /* GL_LESS test should fail everywhere
597 * decr front to 5, incr back to 2
599 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
600 GL_DECR, GL_INCR, /* z fail */
601 GL_KEEP, GL_KEEP, /* z pass */
602 GL_ALWAYS, GL_ALWAYS, /* stencil func */
603 99, ~0, ~0); /* ref, mask, set write_mask to ~0 */
604 if (pass)
605 pass = render_test(6, 8);
606 reset_stencil_state(method);
607 if (!pass)
608 return false;
611 /* set depth test = GL_EQUAL
612 * Z test should pass everywhere
613 * set front to 3
614 * decr back to 7
616 glDepthFunc(GL_EQUAL);
617 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
618 GL_KEEP, GL_KEEP, /* z fail */
619 GL_REPLACE, GL_DECR, /* z pass */
620 GL_ALWAYS, GL_ALWAYS, /* stencil func */
621 3, ~0, ~0); /* ref, mask, set write_mask to ~0 */
622 if (pass)
623 pass = render_test(3, 7);
624 reset_stencil_state(method);
625 if (!pass)
626 return false;
629 /* incr front to 4 (by z pass), decr back to 6 (by stencil fail) */
630 pass = set_stencil_state2(method, GL_DECR, GL_DECR, /* stencil fail */
631 GL_KEEP, GL_KEEP, /* z fail */
632 GL_INCR, GL_REPLACE, /* z pass */
633 GL_EQUAL, GL_EQUAL, /* stencil func */
634 3, ~0, ~0); /* ref, mask, set write_mask to ~0 */
635 if (pass)
636 pass = render_test(4, 6);
637 reset_stencil_state(method);
638 if (!pass)
639 return false;
642 /* ============================================================
643 * Disable depth test
645 glDisable(GL_DEPTH_TEST);
647 /* test stencil value mask
648 * only test bit 1 in stencil values
649 * if !(front&0x2 == 15&0x2), decr to 3 (should happen)
650 * if !(back&0x2 == 15&0x2), incr to 7 (should not happen)
652 pass = set_stencil_state2(method, GL_DECR, GL_INCR, /* stencil fail */
653 GL_KEEP, GL_KEEP, /* z fail */
654 GL_KEEP, GL_KEEP, /* z pass */
655 GL_EQUAL, GL_EQUAL, /* stencil func */
656 15, 0x2, ~0); /* ref, mask, set write_mask to ~0 */
657 if (pass)
658 pass = render_test(3, 6);
659 reset_stencil_state(method);
660 if (!pass)
661 return false;
663 /* ============================================================
664 * Test common two-sided stencil modes for shadow volume rendering
665 * Requires stencil /- wrap feature.
668 if (!have_stencil_wrap())
669 return true;
671 glClear(GL_COLOR_BUFFER_BIT |
672 GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
674 glEnable(GL_DEPTH_TEST);
675 glDepthFunc(GL_LESS);
677 /* "traditional / Z-pass" method:
678 * front face: incr on zpass
679 * back face: decr on zpass
680 * both front and back Z-test should pass here
682 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
683 GL_KEEP, GL_KEEP, /* z fail */
684 GL_INCR_WRAP_EXT, GL_DECR_WRAP_EXT, /* z pass */
685 GL_ALWAYS, GL_ALWAYS, /* stencil func */
686 0, ~0, ~0); /* ref, mask, set write_mask to ~0 */
687 if (pass)
688 pass = render_test(1, stencil_max);
689 reset_stencil_state(method);
690 if (!pass)
691 return false;
694 /* "Z-fail" method:
695 * front face: decr on zfail
696 * back face: incr on zfail
697 * both front and back Z-test should fail here
699 pass = set_stencil_state2(method, GL_KEEP, GL_KEEP, /* stencil fail */
700 GL_DECR_WRAP_EXT, GL_INCR_WRAP_EXT, /* z fail */
701 GL_KEEP, GL_KEEP, /* z pass */
702 GL_ALWAYS, GL_ALWAYS, /* stencil func */
703 0, ~0, ~0); /* ref, mask, set write_mask to ~0 */
704 if (pass)
705 pass = render_test(0, 0);
706 reset_stencil_state(method);
707 if (!pass)
708 return false;
711 return true;
715 void
716 piglit_init(int argc, char **argv)
718 /* no initialization */
722 enum piglit_result
723 piglit_display(void)
725 bool pass = true;
727 /* how many stencil bits (we assume at least 8 above) */
728 glGetIntegerv(GL_STENCIL_BITS, &stencil_bits);
729 stencil_max = (1 << stencil_bits) - 1;
730 assert(stencil_bits >= 8);
732 glViewport(0, 0, piglit_width, piglit_width);
733 glMatrixMode(GL_PROJECTION);
734 glLoadIdentity();
735 glOrtho(0, piglit_width, 0, piglit_width, -1, 1);
736 glMatrixMode(GL_MODELVIEW);
737 glLoadIdentity();
739 if (piglit_is_extension_supported("GL_ATI_separate_stencil")) {
740 pass = test_stencil(ATI) && pass;
743 if (piglit_is_extension_supported("GL_EXT_stencil_two_side")) {
744 pass = test_stencil(EXT) && pass;
747 if (piglit_get_gl_version() >= 2.0) {
748 pass = test_stencil(GL2) && pass;
751 return pass ? PIGLIT_PASS : PIGLIT_FAIL;