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