add missing _mesa_StencilFuncSeparateATI function
[mesa.git] / src / mesa / main / stencil.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.5.2
4 *
5 * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25
26 /**
27 * \file stencil.c
28 * Stencil operations.
29 *
30 * Note: There's an incompatibility between GL_EXT_stencil_two_side and
31 * OpenGL 2.0's two-sided stencil feature.
32 *
33 * With GL_EXT_stencil_two_side, calling glStencilOp/Func/Mask() only the
34 * front OR back face state (as set by glActiveStencilFaceEXT) is set.
35 *
36 * But with OpenGL 2.0, calling glStencilOp/Func/Mask() sets BOTH the
37 * front AND back state.
38 *
39 * So either we advertise the GL_EXT_stencil_two_side extension, or OpenGL
40 * 2.0, but not both.
41 *
42 * Also, note that GL_ATI_separate_stencil is different as well:
43 * glStencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, ...) vs.
44 * glStencilFuncSeparate(GLenum face, GLenum func, ...).
45 */
46
47
48 #include "glheader.h"
49 #include "imports.h"
50 #include "context.h"
51 #include "macros.h"
52 #include "stencil.h"
53 #include "mtypes.h"
54
55
56 /**
57 * Set the clear value for the stencil buffer.
58 *
59 * \param s clear value.
60 *
61 * \sa glClearStencil().
62 *
63 * Updates gl_stencil_attrib::Clear. On change
64 * flushes the vertices and notifies the driver via
65 * the dd_function_table::ClearStencil callback.
66 */
67 void GLAPIENTRY
68 _mesa_ClearStencil( GLint s )
69 {
70 GET_CURRENT_CONTEXT(ctx);
71 ASSERT_OUTSIDE_BEGIN_END(ctx);
72
73 if (ctx->Stencil.Clear == (GLuint) s)
74 return;
75
76 FLUSH_VERTICES(ctx, _NEW_STENCIL);
77 ctx->Stencil.Clear = (GLuint) s;
78
79 if (ctx->Driver.ClearStencil) {
80 ctx->Driver.ClearStencil( ctx, s );
81 }
82 }
83
84
85 /**
86 * Set the function and reference value for stencil testing.
87 *
88 * \param frontfunc front test function.
89 * \param backfunc back test function.
90 * \param ref front and back reference value.
91 * \param mask front and back bitmask.
92 *
93 * \sa glStencilFunc().
94 *
95 * Verifies the parameters and updates the respective values in
96 * __GLcontextRec::Stencil. On change flushes the vertices and notifies the
97 * driver via the dd_function_table::StencilFunc callback.
98 */
99 void GLAPIENTRY
100 _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask )
101 {
102 GET_CURRENT_CONTEXT(ctx);
103 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
104 ASSERT_OUTSIDE_BEGIN_END(ctx);
105
106 switch (frontfunc) {
107 case GL_NEVER:
108 case GL_LESS:
109 case GL_LEQUAL:
110 case GL_GREATER:
111 case GL_GEQUAL:
112 case GL_EQUAL:
113 case GL_NOTEQUAL:
114 case GL_ALWAYS:
115 break;
116 default:
117 _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI (0x%04x)", frontfunc );
118 return;
119 }
120
121 switch (backfunc) {
122 case GL_NEVER:
123 case GL_LESS:
124 case GL_LEQUAL:
125 case GL_GREATER:
126 case GL_GEQUAL:
127 case GL_EQUAL:
128 case GL_NOTEQUAL:
129 case GL_ALWAYS:
130 break;
131 default:
132 _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFuncSeparateATI (0x%04x)", backfunc );
133 return;
134 }
135
136 ref = CLAMP( ref, 0, stencilMax );
137
138 /* set both front and back state */
139 if (ctx->Stencil.Function[0] == frontfunc &&
140 ctx->Stencil.Function[1] == backfunc &&
141 ctx->Stencil.ValueMask[0] == mask &&
142 ctx->Stencil.ValueMask[1] == mask &&
143 ctx->Stencil.Ref[0] == ref &&
144 ctx->Stencil.Ref[1] == ref)
145 return;
146 FLUSH_VERTICES(ctx, _NEW_STENCIL);
147 ctx->Stencil.Function[0] = frontfunc;
148 ctx->Stencil.Function[1] = backfunc;
149 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
150 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
151 if (ctx->Driver.StencilFuncSeparate) {
152 ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
153 frontfunc, ref, mask);
154 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
155 backfunc, ref, mask);
156 }
157 }
158
159
160 /**
161 * Set the function and reference value for stencil testing.
162 *
163 * \param func test function.
164 * \param ref reference value.
165 * \param mask bitmask.
166 *
167 * \sa glStencilFunc().
168 *
169 * Verifies the parameters and updates the respective values in
170 * __GLcontextRec::Stencil. On change flushes the vertices and notifies the
171 * driver via the dd_function_table::StencilFunc callback.
172 */
173 void GLAPIENTRY
174 _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
175 {
176 GET_CURRENT_CONTEXT(ctx);
177 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
178 ASSERT_OUTSIDE_BEGIN_END(ctx);
179
180 switch (func) {
181 case GL_NEVER:
182 case GL_LESS:
183 case GL_LEQUAL:
184 case GL_GREATER:
185 case GL_GEQUAL:
186 case GL_EQUAL:
187 case GL_NOTEQUAL:
188 case GL_ALWAYS:
189 break;
190 default:
191 _mesa_error( ctx, GL_INVALID_ENUM, "glStencilFunc (0x%04x)", func );
192 return;
193 }
194
195 ref = CLAMP( ref, 0, stencilMax );
196
197 if (ctx->Extensions.ATI_separate_stencil) {
198 /* set both front and back state */
199 if (ctx->Stencil.Function[0] == func &&
200 ctx->Stencil.Function[1] == func &&
201 ctx->Stencil.ValueMask[0] == mask &&
202 ctx->Stencil.ValueMask[1] == mask &&
203 ctx->Stencil.Ref[0] == ref &&
204 ctx->Stencil.Ref[1] == ref)
205 return;
206 FLUSH_VERTICES(ctx, _NEW_STENCIL);
207 ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func;
208 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
209 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
210 if (ctx->Driver.StencilFuncSeparate) {
211 ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT_AND_BACK,
212 func, ref, mask);
213 }
214 }
215 else {
216 /* only set active face state */
217 const GLint face = ctx->Stencil.ActiveFace;
218 if (ctx->Stencil.Function[face] == func &&
219 ctx->Stencil.ValueMask[face] == mask &&
220 ctx->Stencil.Ref[face] == ref)
221 return;
222 FLUSH_VERTICES(ctx, _NEW_STENCIL);
223 ctx->Stencil.Function[face] = func;
224 ctx->Stencil.Ref[face] = ref;
225 ctx->Stencil.ValueMask[face] = mask;
226 if (ctx->Driver.StencilFuncSeparate) {
227 ctx->Driver.StencilFuncSeparate(ctx, face ? GL_BACK : GL_FRONT,
228 func, ref, mask);
229 }
230 }
231 }
232
233
234 /**
235 * Set the stencil writing mask.
236 *
237 * \param mask bit-mask to enable/disable writing of individual bits in the
238 * stencil planes.
239 *
240 * \sa glStencilMask().
241 *
242 * Updates gl_stencil_attrib::WriteMask. On change flushes the vertices and
243 * notifies the driver via the dd_function_table::StencilMask callback.
244 */
245 void GLAPIENTRY
246 _mesa_StencilMask( GLuint mask )
247 {
248 GET_CURRENT_CONTEXT(ctx);
249 ASSERT_OUTSIDE_BEGIN_END(ctx);
250
251 if (ctx->Extensions.ATI_separate_stencil) {
252 /* set both front and back state */
253 if (ctx->Stencil.WriteMask[0] == mask &&
254 ctx->Stencil.WriteMask[1] == mask)
255 return;
256 FLUSH_VERTICES(ctx, _NEW_STENCIL);
257 ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask;
258 if (ctx->Driver.StencilMaskSeparate) {
259 ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT_AND_BACK, mask);
260 }
261 }
262 else {
263 /* only set active face state */
264 const GLint face = ctx->Stencil.ActiveFace;
265 if (ctx->Stencil.WriteMask[face] == mask)
266 return;
267 FLUSH_VERTICES(ctx, _NEW_STENCIL);
268 ctx->Stencil.WriteMask[face] = mask;
269 if (ctx->Driver.StencilMaskSeparate) {
270 ctx->Driver.StencilMaskSeparate(ctx, face ? GL_BACK : GL_FRONT, mask);
271 }
272 }
273 }
274
275
276 /**
277 * Set the stencil test actions.
278 *
279 * \param fail action to take when stencil test fails.
280 * \param zfail action to take when stencil test passes, but depth test fails.
281 * \param zpass action to take when stencil test passes and the depth test
282 * passes (or depth testing is not enabled).
283 *
284 * \sa glStencilOp().
285 *
286 * Verifies the parameters and updates the respective fields in
287 * __GLcontextRec::Stencil. On change flushes the vertices and notifies the
288 * driver via the dd_function_table::StencilOp callback.
289 */
290 void GLAPIENTRY
291 _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
292 {
293 GET_CURRENT_CONTEXT(ctx);
294 ASSERT_OUTSIDE_BEGIN_END(ctx);
295
296 switch (fail) {
297 case GL_KEEP:
298 case GL_ZERO:
299 case GL_REPLACE:
300 case GL_INCR:
301 case GL_DECR:
302 case GL_INVERT:
303 break;
304 case GL_INCR_WRAP_EXT:
305 case GL_DECR_WRAP_EXT:
306 if (ctx->Extensions.EXT_stencil_wrap) {
307 break;
308 }
309 /* FALL-THROUGH */
310 default:
311 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
312 return;
313 }
314 switch (zfail) {
315 case GL_KEEP:
316 case GL_ZERO:
317 case GL_REPLACE:
318 case GL_INCR:
319 case GL_DECR:
320 case GL_INVERT:
321 break;
322 case GL_INCR_WRAP_EXT:
323 case GL_DECR_WRAP_EXT:
324 if (ctx->Extensions.EXT_stencil_wrap) {
325 break;
326 }
327 /* FALL-THROUGH */
328 default:
329 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
330 return;
331 }
332 switch (zpass) {
333 case GL_KEEP:
334 case GL_ZERO:
335 case GL_REPLACE:
336 case GL_INCR:
337 case GL_DECR:
338 case GL_INVERT:
339 break;
340 case GL_INCR_WRAP_EXT:
341 case GL_DECR_WRAP_EXT:
342 if (ctx->Extensions.EXT_stencil_wrap) {
343 break;
344 }
345 /* FALL-THROUGH */
346 default:
347 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp");
348 return;
349 }
350
351 if (ctx->Extensions.ATI_separate_stencil) {
352 /* set both front and back state */
353 if (ctx->Stencil.ZFailFunc[0] == zfail &&
354 ctx->Stencil.ZFailFunc[1] == zfail &&
355 ctx->Stencil.ZPassFunc[0] == zpass &&
356 ctx->Stencil.ZPassFunc[1] == zpass &&
357 ctx->Stencil.FailFunc[0] == fail &&
358 ctx->Stencil.FailFunc[1] == fail)
359 return;
360 FLUSH_VERTICES(ctx, _NEW_STENCIL);
361 ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail;
362 ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass;
363 ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail;
364 if (ctx->Driver.StencilOpSeparate) {
365 ctx->Driver.StencilOpSeparate(ctx, GL_FRONT_AND_BACK,
366 fail, zfail, zpass);
367 }
368 }
369 else {
370 /* only set active face state */
371 const GLint face = ctx->Stencil.ActiveFace;
372 if (ctx->Stencil.ZFailFunc[face] == zfail &&
373 ctx->Stencil.ZPassFunc[face] == zpass &&
374 ctx->Stencil.FailFunc[face] == fail)
375 return;
376 FLUSH_VERTICES(ctx, _NEW_STENCIL);
377 ctx->Stencil.ZFailFunc[face] = zfail;
378 ctx->Stencil.ZPassFunc[face] = zpass;
379 ctx->Stencil.FailFunc[face] = fail;
380 if (ctx->Driver.StencilOpSeparate) {
381 ctx->Driver.StencilOpSeparate(ctx, face ? GL_BACK : GL_FRONT,
382 fail, zfail, zpass);
383 }
384 }
385 }
386
387
388
389 #if _HAVE_FULL_GL
390 /* GL_EXT_stencil_two_side */
391 void GLAPIENTRY
392 _mesa_ActiveStencilFaceEXT(GLenum face)
393 {
394 GET_CURRENT_CONTEXT(ctx);
395 ASSERT_OUTSIDE_BEGIN_END(ctx);
396
397 if (!ctx->Extensions.EXT_stencil_two_side) {
398 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT");
399 return;
400 }
401
402 if (face == GL_FRONT || face == GL_BACK) {
403 FLUSH_VERTICES(ctx, _NEW_STENCIL);
404 ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 1;
405 }
406 else {
407 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)");
408 }
409 }
410 #endif
411
412
413
414 /**
415 * OpenGL 2.0 function.
416 * \todo Make StencilOp() call this function. And eventually remove the
417 * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate
418 * instead.
419 */
420 void GLAPIENTRY
421 _mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
422 {
423 GET_CURRENT_CONTEXT(ctx);
424 ASSERT_OUTSIDE_BEGIN_END(ctx);
425
426 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
427 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)");
428 return;
429 }
430
431 switch (fail) {
432 case GL_KEEP:
433 case GL_ZERO:
434 case GL_REPLACE:
435 case GL_INCR:
436 case GL_DECR:
437 case GL_INVERT:
438 break;
439 case GL_INCR_WRAP_EXT:
440 case GL_DECR_WRAP_EXT:
441 if (ctx->Extensions.EXT_stencil_wrap) {
442 break;
443 }
444 /* FALL-THROUGH */
445 default:
446 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(fail)");
447 return;
448 }
449 switch (zfail) {
450 case GL_KEEP:
451 case GL_ZERO:
452 case GL_REPLACE:
453 case GL_INCR:
454 case GL_DECR:
455 case GL_INVERT:
456 break;
457 case GL_INCR_WRAP_EXT:
458 case GL_DECR_WRAP_EXT:
459 if (ctx->Extensions.EXT_stencil_wrap) {
460 break;
461 }
462 /* FALL-THROUGH */
463 default:
464 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");
465 return;
466 }
467 switch (zpass) {
468 case GL_KEEP:
469 case GL_ZERO:
470 case GL_REPLACE:
471 case GL_INCR:
472 case GL_DECR:
473 case GL_INVERT:
474 break;
475 case GL_INCR_WRAP_EXT:
476 case GL_DECR_WRAP_EXT:
477 if (ctx->Extensions.EXT_stencil_wrap) {
478 break;
479 }
480 /* FALL-THROUGH */
481 default:
482 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");
483 return;
484 }
485
486 FLUSH_VERTICES(ctx, _NEW_STENCIL);
487
488 if (face != GL_BACK) {
489 ctx->Stencil.FailFunc[0] = fail;
490 ctx->Stencil.ZFailFunc[0] = zfail;
491 ctx->Stencil.ZPassFunc[0] = zpass;
492 }
493 if (face != GL_FRONT) {
494 ctx->Stencil.FailFunc[1] = fail;
495 ctx->Stencil.ZFailFunc[1] = zfail;
496 ctx->Stencil.ZPassFunc[1] = zpass;
497 }
498 if (ctx->Driver.StencilOpSeparate) {
499 ctx->Driver.StencilOpSeparate(ctx, face, fail, zfail, zpass);
500 }
501 }
502
503
504 /* OpenGL 2.0 */
505 void GLAPIENTRY
506 _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
507 {
508 GET_CURRENT_CONTEXT(ctx);
509 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
510 ASSERT_OUTSIDE_BEGIN_END(ctx);
511
512 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
513 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)");
514 return;
515 }
516
517 switch (func) {
518 case GL_NEVER:
519 case GL_LESS:
520 case GL_LEQUAL:
521 case GL_GREATER:
522 case GL_GEQUAL:
523 case GL_EQUAL:
524 case GL_NOTEQUAL:
525 case GL_ALWAYS:
526 break;
527 default:
528 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
529 return;
530 }
531
532 ref = CLAMP(ref, 0, stencilMax);
533
534 FLUSH_VERTICES(ctx, _NEW_STENCIL);
535
536 if (face == GL_FRONT || face == GL_FRONT_AND_BACK) {
537 ctx->Stencil.Function[0] = func;
538 ctx->Stencil.Ref[0] = ref;
539 ctx->Stencil.ValueMask[0] = mask;
540 }
541 if (face == GL_BACK || face == GL_FRONT_AND_BACK) {
542 ctx->Stencil.Function[1] = func;
543 ctx->Stencil.Ref[1] = ref;
544 ctx->Stencil.ValueMask[1] = mask;
545 }
546 if (ctx->Driver.StencilFuncSeparate) {
547 ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask);
548 }
549 }
550
551
552 /* OpenGL 2.0 */
553 void GLAPIENTRY
554 _mesa_StencilMaskSeparate(GLenum face, GLuint mask)
555 {
556 GET_CURRENT_CONTEXT(ctx);
557 ASSERT_OUTSIDE_BEGIN_END(ctx);
558
559 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
560 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)");
561 return;
562 }
563
564 FLUSH_VERTICES(ctx, _NEW_STENCIL);
565
566 if (face != GL_BACK) {
567 ctx->Stencil.WriteMask[0] = mask;
568 }
569 if (face != GL_FRONT) {
570 ctx->Stencil.WriteMask[1] = mask;
571 }
572 if (ctx->Driver.StencilMaskSeparate) {
573 ctx->Driver.StencilMaskSeparate(ctx, face, mask);
574 }
575 }
576
577
578 /**
579 * Update derived stencil state.
580 */
581 void
582 _mesa_update_stencil(GLcontext *ctx)
583 {
584 if (ctx->Extensions.EXT_stencil_two_side) {
585 ctx->Stencil._TestTwoSide = ctx->Stencil.TestTwoSide;
586 }
587 else {
588 ctx->Stencil._TestTwoSide =
589 (ctx->Stencil.Function[0] != ctx->Stencil.Function[1] ||
590 ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[1] ||
591 ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[1] ||
592 ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[1] ||
593 ctx->Stencil.Ref[0] != ctx->Stencil.Ref[1] ||
594 ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[1] ||
595 ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[1]);
596 }
597 }
598
599
600 /**
601 * Initialize the context stipple state.
602 *
603 * \param ctx GL context.
604 *
605 * Initializes __GLcontextRec::Stencil attribute group.
606 */
607 void
608 _mesa_init_stencil(GLcontext *ctx)
609 {
610 ctx->Stencil.Enabled = GL_FALSE;
611 ctx->Stencil.TestTwoSide = GL_FALSE;
612 ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 1 = GL_BACK */
613 ctx->Stencil.Function[0] = GL_ALWAYS;
614 ctx->Stencil.Function[1] = GL_ALWAYS;
615 ctx->Stencil.FailFunc[0] = GL_KEEP;
616 ctx->Stencil.FailFunc[1] = GL_KEEP;
617 ctx->Stencil.ZPassFunc[0] = GL_KEEP;
618 ctx->Stencil.ZPassFunc[1] = GL_KEEP;
619 ctx->Stencil.ZFailFunc[0] = GL_KEEP;
620 ctx->Stencil.ZFailFunc[1] = GL_KEEP;
621 ctx->Stencil.Ref[0] = 0;
622 ctx->Stencil.Ref[1] = 0;
623 ctx->Stencil.ValueMask[0] = ~0U;
624 ctx->Stencil.ValueMask[1] = ~0U;
625 ctx->Stencil.WriteMask[0] = ~0U;
626 ctx->Stencil.WriteMask[1] = ~0U;
627 ctx->Stencil.Clear = 0;
628 }