mesa: Restore 78-column wrapping of license text in C-style comments.
[mesa.git] / src / mesa / main / stencil.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.1
4 *
5 * Copyright (C) 1999-2007 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 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26
27 /**
28 * \file stencil.c
29 * Stencil operations.
30 *
31 * Note: There's some conflict between GL_EXT_stencil_two_side and
32 * OpenGL 2.0's two-sided stencil feature.
33 *
34 * With GL_EXT_stencil_two_side, calling glStencilOp/Func/Mask() only the
35 * front OR back face state (as set by glActiveStencilFaceEXT) is set.
36 *
37 * But with OpenGL 2.0, calling glStencilOp/Func/Mask() sets BOTH the
38 * front AND back state.
39 *
40 * Also, note that GL_ATI_separate_stencil is different as well:
41 * glStencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, ...) vs.
42 * glStencilFuncSeparate(GLenum face, GLenum func, ...).
43 *
44 * This problem is solved by keeping three sets of stencil state:
45 * state[0] = GL_FRONT state.
46 * state[1] = OpenGL 2.0 / GL_ATI_separate_stencil GL_BACK state.
47 * state[2] = GL_EXT_stencil_two_side GL_BACK state.
48 */
49
50
51 #include "glheader.h"
52 #include "imports.h"
53 #include "context.h"
54 #include "macros.h"
55 #include "stencil.h"
56 #include "mtypes.h"
57
58
59 static GLboolean
60 validate_stencil_op(struct gl_context *ctx, GLenum op)
61 {
62 switch (op) {
63 case GL_KEEP:
64 case GL_ZERO:
65 case GL_REPLACE:
66 case GL_INCR:
67 case GL_DECR:
68 case GL_INVERT:
69 case GL_INCR_WRAP:
70 case GL_DECR_WRAP:
71 return GL_TRUE;
72 default:
73 return GL_FALSE;
74 }
75 }
76
77
78 static GLboolean
79 validate_stencil_func(struct gl_context *ctx, GLenum func)
80 {
81 switch (func) {
82 case GL_NEVER:
83 case GL_LESS:
84 case GL_LEQUAL:
85 case GL_GREATER:
86 case GL_GEQUAL:
87 case GL_EQUAL:
88 case GL_NOTEQUAL:
89 case GL_ALWAYS:
90 return GL_TRUE;
91 default:
92 return GL_FALSE;
93 }
94 }
95
96
97 /**
98 * Set the clear value for the stencil buffer.
99 *
100 * \param s clear value.
101 *
102 * \sa glClearStencil().
103 *
104 * Updates gl_stencil_attrib::Clear. On change
105 * flushes the vertices and notifies the driver via
106 * the dd_function_table::ClearStencil callback.
107 */
108 void GLAPIENTRY
109 _mesa_ClearStencil( GLint s )
110 {
111 GET_CURRENT_CONTEXT(ctx);
112
113 ctx->Stencil.Clear = (GLuint) s;
114 }
115
116
117 /**
118 * Set the function and reference value for stencil testing.
119 *
120 * \param frontfunc front test function.
121 * \param backfunc back test function.
122 * \param ref front and back reference value.
123 * \param mask front and back bitmask.
124 *
125 * \sa glStencilFunc().
126 *
127 * Verifies the parameters and updates the respective values in
128 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the
129 * driver via the dd_function_table::StencilFunc callback.
130 */
131 void GLAPIENTRY
132 _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask )
133 {
134 GET_CURRENT_CONTEXT(ctx);
135 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
136
137 if (MESA_VERBOSE & VERBOSE_API)
138 _mesa_debug(ctx, "glStencilFuncSeparateATI()\n");
139
140 if (!validate_stencil_func(ctx, frontfunc)) {
141 _mesa_error(ctx, GL_INVALID_ENUM,
142 "glStencilFuncSeparateATI(frontfunc)");
143 return;
144 }
145 if (!validate_stencil_func(ctx, backfunc)) {
146 _mesa_error(ctx, GL_INVALID_ENUM,
147 "glStencilFuncSeparateATI(backfunc)");
148 return;
149 }
150
151 ref = CLAMP( ref, 0, stencilMax );
152
153 /* set both front and back state */
154 if (ctx->Stencil.Function[0] == frontfunc &&
155 ctx->Stencil.Function[1] == backfunc &&
156 ctx->Stencil.ValueMask[0] == mask &&
157 ctx->Stencil.ValueMask[1] == mask &&
158 ctx->Stencil.Ref[0] == ref &&
159 ctx->Stencil.Ref[1] == ref)
160 return;
161 FLUSH_VERTICES(ctx, _NEW_STENCIL);
162 ctx->Stencil.Function[0] = frontfunc;
163 ctx->Stencil.Function[1] = backfunc;
164 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
165 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
166 if (ctx->Driver.StencilFuncSeparate) {
167 ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT,
168 frontfunc, ref, mask);
169 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK,
170 backfunc, ref, mask);
171 }
172 }
173
174
175 /**
176 * Set the function and reference value for stencil testing.
177 *
178 * \param func test function.
179 * \param ref reference value.
180 * \param mask bitmask.
181 *
182 * \sa glStencilFunc().
183 *
184 * Verifies the parameters and updates the respective values in
185 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the
186 * driver via the dd_function_table::StencilFunc callback.
187 */
188 void GLAPIENTRY
189 _mesa_StencilFunc( GLenum func, GLint ref, GLuint mask )
190 {
191 GET_CURRENT_CONTEXT(ctx);
192 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
193 const GLint face = ctx->Stencil.ActiveFace;
194
195 if (MESA_VERBOSE & VERBOSE_API)
196 _mesa_debug(ctx, "glStencilFunc()\n");
197
198 if (!validate_stencil_func(ctx, func)) {
199 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)");
200 return;
201 }
202
203 ref = CLAMP( ref, 0, stencilMax );
204
205 if (face != 0) {
206 if (ctx->Stencil.Function[face] == func &&
207 ctx->Stencil.ValueMask[face] == mask &&
208 ctx->Stencil.Ref[face] == ref)
209 return;
210 FLUSH_VERTICES(ctx, _NEW_STENCIL);
211 ctx->Stencil.Function[face] = func;
212 ctx->Stencil.Ref[face] = ref;
213 ctx->Stencil.ValueMask[face] = mask;
214
215 /* Only propagate the change to the driver if EXT_stencil_two_side
216 * is enabled.
217 */
218 if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) {
219 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask);
220 }
221 }
222 else {
223 /* set both front and back state */
224 if (ctx->Stencil.Function[0] == func &&
225 ctx->Stencil.Function[1] == func &&
226 ctx->Stencil.ValueMask[0] == mask &&
227 ctx->Stencil.ValueMask[1] == mask &&
228 ctx->Stencil.Ref[0] == ref &&
229 ctx->Stencil.Ref[1] == ref)
230 return;
231 FLUSH_VERTICES(ctx, _NEW_STENCIL);
232 ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func;
233 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref;
234 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask;
235 if (ctx->Driver.StencilFuncSeparate) {
236 ctx->Driver.StencilFuncSeparate(ctx,
237 ((ctx->Stencil.TestTwoSide)
238 ? GL_FRONT : GL_FRONT_AND_BACK),
239 func, ref, mask);
240 }
241 }
242 }
243
244
245 /**
246 * Set the stencil writing mask.
247 *
248 * \param mask bit-mask to enable/disable writing of individual bits in the
249 * stencil planes.
250 *
251 * \sa glStencilMask().
252 *
253 * Updates gl_stencil_attrib::WriteMask. On change flushes the vertices and
254 * notifies the driver via the dd_function_table::StencilMask callback.
255 */
256 void GLAPIENTRY
257 _mesa_StencilMask( GLuint mask )
258 {
259 GET_CURRENT_CONTEXT(ctx);
260 const GLint face = ctx->Stencil.ActiveFace;
261
262 if (MESA_VERBOSE & VERBOSE_API)
263 _mesa_debug(ctx, "glStencilMask()\n");
264
265 if (face != 0) {
266 /* Only modify the EXT_stencil_two_side back-face state.
267 */
268 if (ctx->Stencil.WriteMask[face] == mask)
269 return;
270 FLUSH_VERTICES(ctx, _NEW_STENCIL);
271 ctx->Stencil.WriteMask[face] = mask;
272
273 /* Only propagate the change to the driver if EXT_stencil_two_side
274 * is enabled.
275 */
276 if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) {
277 ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask);
278 }
279 }
280 else {
281 /* set both front and back state */
282 if (ctx->Stencil.WriteMask[0] == mask &&
283 ctx->Stencil.WriteMask[1] == mask)
284 return;
285 FLUSH_VERTICES(ctx, _NEW_STENCIL);
286 ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask;
287 if (ctx->Driver.StencilMaskSeparate) {
288 ctx->Driver.StencilMaskSeparate(ctx,
289 ((ctx->Stencil.TestTwoSide)
290 ? GL_FRONT : GL_FRONT_AND_BACK),
291 mask);
292 }
293 }
294 }
295
296
297 /**
298 * Set the stencil test actions.
299 *
300 * \param fail action to take when stencil test fails.
301 * \param zfail action to take when stencil test passes, but depth test fails.
302 * \param zpass action to take when stencil test passes and the depth test
303 * passes (or depth testing is not enabled).
304 *
305 * \sa glStencilOp().
306 *
307 * Verifies the parameters and updates the respective fields in
308 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the
309 * driver via the dd_function_table::StencilOp callback.
310 */
311 void GLAPIENTRY
312 _mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
313 {
314 GET_CURRENT_CONTEXT(ctx);
315 const GLint face = ctx->Stencil.ActiveFace;
316
317 if (MESA_VERBOSE & VERBOSE_API)
318 _mesa_debug(ctx, "glStencilOp()\n");
319
320 if (!validate_stencil_op(ctx, fail)) {
321 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(sfail)");
322 return;
323 }
324 if (!validate_stencil_op(ctx, zfail)) {
325 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zfail)");
326 return;
327 }
328 if (!validate_stencil_op(ctx, zpass)) {
329 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)");
330 return;
331 }
332
333 if (face != 0) {
334 /* only set active face state */
335 if (ctx->Stencil.ZFailFunc[face] == zfail &&
336 ctx->Stencil.ZPassFunc[face] == zpass &&
337 ctx->Stencil.FailFunc[face] == fail)
338 return;
339 FLUSH_VERTICES(ctx, _NEW_STENCIL);
340 ctx->Stencil.ZFailFunc[face] = zfail;
341 ctx->Stencil.ZPassFunc[face] = zpass;
342 ctx->Stencil.FailFunc[face] = fail;
343
344 /* Only propagate the change to the driver if EXT_stencil_two_side
345 * is enabled.
346 */
347 if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) {
348 ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass);
349 }
350 }
351 else {
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,
366 ((ctx->Stencil.TestTwoSide)
367 ? GL_FRONT : GL_FRONT_AND_BACK),
368 fail, zfail, zpass);
369 }
370 }
371 }
372
373
374
375 /* GL_EXT_stencil_two_side */
376 void GLAPIENTRY
377 _mesa_ActiveStencilFaceEXT(GLenum face)
378 {
379 GET_CURRENT_CONTEXT(ctx);
380
381 if (MESA_VERBOSE & VERBOSE_API)
382 _mesa_debug(ctx, "glActiveStencilFaceEXT()\n");
383
384 if (!ctx->Extensions.EXT_stencil_two_side) {
385 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT");
386 return;
387 }
388
389 if (face == GL_FRONT || face == GL_BACK) {
390 ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 2;
391 }
392 else {
393 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)");
394 }
395 }
396
397
398
399 /**
400 * OpenGL 2.0 function.
401 * \todo Make StencilOp() call this function. And eventually remove the
402 * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate
403 * instead.
404 */
405 void GLAPIENTRY
406 _mesa_StencilOpSeparate(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass)
407 {
408 GLboolean set = GL_FALSE;
409 GET_CURRENT_CONTEXT(ctx);
410
411 if (MESA_VERBOSE & VERBOSE_API)
412 _mesa_debug(ctx, "glStencilOpSeparate()\n");
413
414 if (!validate_stencil_op(ctx, sfail)) {
415 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(sfail)");
416 return;
417 }
418 if (!validate_stencil_op(ctx, zfail)) {
419 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)");
420 return;
421 }
422 if (!validate_stencil_op(ctx, zpass)) {
423 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)");
424 return;
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 if (face != GL_BACK) {
432 /* set front */
433 if (ctx->Stencil.ZFailFunc[0] != zfail ||
434 ctx->Stencil.ZPassFunc[0] != zpass ||
435 ctx->Stencil.FailFunc[0] != sfail){
436 FLUSH_VERTICES(ctx, _NEW_STENCIL);
437 ctx->Stencil.ZFailFunc[0] = zfail;
438 ctx->Stencil.ZPassFunc[0] = zpass;
439 ctx->Stencil.FailFunc[0] = sfail;
440 set = GL_TRUE;
441 }
442 }
443 if (face != GL_FRONT) {
444 /* set back */
445 if (ctx->Stencil.ZFailFunc[1] != zfail ||
446 ctx->Stencil.ZPassFunc[1] != zpass ||
447 ctx->Stencil.FailFunc[1] != sfail) {
448 FLUSH_VERTICES(ctx, _NEW_STENCIL);
449 ctx->Stencil.ZFailFunc[1] = zfail;
450 ctx->Stencil.ZPassFunc[1] = zpass;
451 ctx->Stencil.FailFunc[1] = sfail;
452 set = GL_TRUE;
453 }
454 }
455 if (set && ctx->Driver.StencilOpSeparate) {
456 ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass);
457 }
458 }
459
460
461 /* OpenGL 2.0 */
462 void GLAPIENTRY
463 _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
464 {
465 GET_CURRENT_CONTEXT(ctx);
466 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
467
468 if (MESA_VERBOSE & VERBOSE_API)
469 _mesa_debug(ctx, "glStencilFuncSeparate()\n");
470
471 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
472 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)");
473 return;
474 }
475 if (!validate_stencil_func(ctx, func)) {
476 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)");
477 return;
478 }
479
480 ref = CLAMP(ref, 0, stencilMax);
481
482 FLUSH_VERTICES(ctx, _NEW_STENCIL);
483
484 if (face != GL_BACK) {
485 /* set front */
486 ctx->Stencil.Function[0] = func;
487 ctx->Stencil.Ref[0] = ref;
488 ctx->Stencil.ValueMask[0] = mask;
489 }
490 if (face != GL_FRONT) {
491 /* set back */
492 ctx->Stencil.Function[1] = func;
493 ctx->Stencil.Ref[1] = ref;
494 ctx->Stencil.ValueMask[1] = mask;
495 }
496 if (ctx->Driver.StencilFuncSeparate) {
497 ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask);
498 }
499 }
500
501
502 /* OpenGL 2.0 */
503 void GLAPIENTRY
504 _mesa_StencilMaskSeparate(GLenum face, GLuint mask)
505 {
506 GET_CURRENT_CONTEXT(ctx);
507
508 if (MESA_VERBOSE & VERBOSE_API)
509 _mesa_debug(ctx, "glStencilMaskSeparate()\n");
510
511 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) {
512 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)");
513 return;
514 }
515
516 FLUSH_VERTICES(ctx, _NEW_STENCIL);
517
518 if (face != GL_BACK) {
519 ctx->Stencil.WriteMask[0] = mask;
520 }
521 if (face != GL_FRONT) {
522 ctx->Stencil.WriteMask[1] = mask;
523 }
524 if (ctx->Driver.StencilMaskSeparate) {
525 ctx->Driver.StencilMaskSeparate(ctx, face, mask);
526 }
527 }
528
529
530 /**
531 * Update derived stencil state.
532 */
533 void
534 _mesa_update_stencil(struct gl_context *ctx)
535 {
536 const GLint face = ctx->Stencil._BackFace;
537
538 ctx->Stencil._Enabled = (ctx->Stencil.Enabled &&
539 ctx->DrawBuffer->Visual.stencilBits > 0);
540
541 ctx->Stencil._TestTwoSide =
542 ctx->Stencil._Enabled &&
543 (ctx->Stencil.Function[0] != ctx->Stencil.Function[face] ||
544 ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] ||
545 ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] ||
546 ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[face] ||
547 ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] ||
548 ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] ||
549 ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]);
550
551 ctx->Stencil._WriteEnabled =
552 ctx->Stencil._Enabled &&
553 (ctx->Stencil.WriteMask[0] != 0 ||
554 (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[face] != 0));
555 }
556
557
558 /**
559 * Initialize the context stipple state.
560 *
561 * \param ctx GL context.
562 *
563 * Initializes __struct gl_contextRec::Stencil attribute group.
564 */
565 void
566 _mesa_init_stencil(struct gl_context *ctx)
567 {
568 ctx->Stencil.Enabled = GL_FALSE;
569 ctx->Stencil.TestTwoSide = GL_FALSE;
570 ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 2 = GL_BACK */
571 ctx->Stencil.Function[0] = GL_ALWAYS;
572 ctx->Stencil.Function[1] = GL_ALWAYS;
573 ctx->Stencil.Function[2] = GL_ALWAYS;
574 ctx->Stencil.FailFunc[0] = GL_KEEP;
575 ctx->Stencil.FailFunc[1] = GL_KEEP;
576 ctx->Stencil.FailFunc[2] = GL_KEEP;
577 ctx->Stencil.ZPassFunc[0] = GL_KEEP;
578 ctx->Stencil.ZPassFunc[1] = GL_KEEP;
579 ctx->Stencil.ZPassFunc[2] = GL_KEEP;
580 ctx->Stencil.ZFailFunc[0] = GL_KEEP;
581 ctx->Stencil.ZFailFunc[1] = GL_KEEP;
582 ctx->Stencil.ZFailFunc[2] = GL_KEEP;
583 ctx->Stencil.Ref[0] = 0;
584 ctx->Stencil.Ref[1] = 0;
585 ctx->Stencil.Ref[2] = 0;
586 ctx->Stencil.ValueMask[0] = ~0U;
587 ctx->Stencil.ValueMask[1] = ~0U;
588 ctx->Stencil.ValueMask[2] = ~0U;
589 ctx->Stencil.WriteMask[0] = ~0U;
590 ctx->Stencil.WriteMask[1] = ~0U;
591 ctx->Stencil.WriteMask[2] = ~0U;
592 ctx->Stencil.Clear = 0;
593 ctx->Stencil._BackFace = 1;
594 }