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