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