stencil.c revision 3975f52eb4ddd2d879fda934f31da033af095dd9
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 112 ctx->Stencil.Clear = (GLuint) s; 113} 114 115 116/** 117 * Set the function and reference value for stencil testing. 118 * 119 * \param frontfunc front test function. 120 * \param backfunc back test function. 121 * \param ref front and back reference value. 122 * \param mask front and back bitmask. 123 * 124 * \sa glStencilFunc(). 125 * 126 * Verifies the parameters and updates the respective values in 127 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 128 * driver via the dd_function_table::StencilFunc callback. 129 */ 130void GLAPIENTRY 131_mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask ) 132{ 133 GET_CURRENT_CONTEXT(ctx); 134 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 135 136 if (MESA_VERBOSE & VERBOSE_API) 137 _mesa_debug(ctx, "glStencilFuncSeparateATI()\n"); 138 139 if (!validate_stencil_func(ctx, frontfunc)) { 140 _mesa_error(ctx, GL_INVALID_ENUM, 141 "glStencilFuncSeparateATI(frontfunc)"); 142 return; 143 } 144 if (!validate_stencil_func(ctx, backfunc)) { 145 _mesa_error(ctx, GL_INVALID_ENUM, 146 "glStencilFuncSeparateATI(backfunc)"); 147 return; 148 } 149 150 ref = CLAMP( ref, 0, stencilMax ); 151 152 /* set both front and back state */ 153 if (ctx->Stencil.Function[0] == frontfunc && 154 ctx->Stencil.Function[1] == backfunc && 155 ctx->Stencil.ValueMask[0] == mask && 156 ctx->Stencil.ValueMask[1] == mask && 157 ctx->Stencil.Ref[0] == ref && 158 ctx->Stencil.Ref[1] == ref) 159 return; 160 FLUSH_VERTICES(ctx, _NEW_STENCIL); 161 ctx->Stencil.Function[0] = frontfunc; 162 ctx->Stencil.Function[1] = backfunc; 163 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; 164 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; 165 if (ctx->Driver.StencilFuncSeparate) { 166 ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, 167 frontfunc, ref, mask); 168 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, 169 backfunc, ref, mask); 170 } 171} 172 173 174/** 175 * Set the function and reference value for stencil testing. 176 * 177 * \param func test function. 178 * \param ref reference value. 179 * \param mask bitmask. 180 * 181 * \sa glStencilFunc(). 182 * 183 * Verifies the parameters and updates the respective values in 184 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 185 * driver via the dd_function_table::StencilFunc callback. 186 */ 187void GLAPIENTRY 188_mesa_StencilFunc( GLenum func, GLint ref, GLuint mask ) 189{ 190 GET_CURRENT_CONTEXT(ctx); 191 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 192 const GLint face = ctx->Stencil.ActiveFace; 193 194 if (MESA_VERBOSE & VERBOSE_API) 195 _mesa_debug(ctx, "glStencilFunc()\n"); 196 197 if (!validate_stencil_func(ctx, func)) { 198 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFunc(func)"); 199 return; 200 } 201 202 ref = CLAMP( ref, 0, stencilMax ); 203 204 if (face != 0) { 205 if (ctx->Stencil.Function[face] == func && 206 ctx->Stencil.ValueMask[face] == mask && 207 ctx->Stencil.Ref[face] == ref) 208 return; 209 FLUSH_VERTICES(ctx, _NEW_STENCIL); 210 ctx->Stencil.Function[face] = func; 211 ctx->Stencil.Ref[face] = ref; 212 ctx->Stencil.ValueMask[face] = mask; 213 214 /* Only propagate the change to the driver if EXT_stencil_two_side 215 * is enabled. 216 */ 217 if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) { 218 ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask); 219 } 220 } 221 else { 222 /* set both front and back state */ 223 if (ctx->Stencil.Function[0] == func && 224 ctx->Stencil.Function[1] == func && 225 ctx->Stencil.ValueMask[0] == mask && 226 ctx->Stencil.ValueMask[1] == mask && 227 ctx->Stencil.Ref[0] == ref && 228 ctx->Stencil.Ref[1] == ref) 229 return; 230 FLUSH_VERTICES(ctx, _NEW_STENCIL); 231 ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func; 232 ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; 233 ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; 234 if (ctx->Driver.StencilFuncSeparate) { 235 ctx->Driver.StencilFuncSeparate(ctx, 236 ((ctx->Stencil.TestTwoSide) 237 ? GL_FRONT : GL_FRONT_AND_BACK), 238 func, ref, mask); 239 } 240 } 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 */ 255void GLAPIENTRY 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, _NEW_STENCIL); 270 ctx->Stencil.WriteMask[face] = mask; 271 272 /* Only propagate the change to the driver if EXT_stencil_two_side 273 * is enabled. 274 */ 275 if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) { 276 ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask); 277 } 278 } 279 else { 280 /* set both front and back state */ 281 if (ctx->Stencil.WriteMask[0] == mask && 282 ctx->Stencil.WriteMask[1] == mask) 283 return; 284 FLUSH_VERTICES(ctx, _NEW_STENCIL); 285 ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; 286 if (ctx->Driver.StencilMaskSeparate) { 287 ctx->Driver.StencilMaskSeparate(ctx, 288 ((ctx->Stencil.TestTwoSide) 289 ? GL_FRONT : GL_FRONT_AND_BACK), 290 mask); 291 } 292 } 293} 294 295 296/** 297 * Set the stencil test actions. 298 * 299 * \param fail action to take when stencil test fails. 300 * \param zfail action to take when stencil test passes, but depth test fails. 301 * \param zpass action to take when stencil test passes and the depth test 302 * passes (or depth testing is not enabled). 303 * 304 * \sa glStencilOp(). 305 * 306 * Verifies the parameters and updates the respective fields in 307 * __struct gl_contextRec::Stencil. On change flushes the vertices and notifies the 308 * driver via the dd_function_table::StencilOp callback. 309 */ 310void GLAPIENTRY 311_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) 312{ 313 GET_CURRENT_CONTEXT(ctx); 314 const GLint face = ctx->Stencil.ActiveFace; 315 316 if (MESA_VERBOSE & VERBOSE_API) 317 _mesa_debug(ctx, "glStencilOp()\n"); 318 319 if (!validate_stencil_op(ctx, fail)) { 320 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(sfail)"); 321 return; 322 } 323 if (!validate_stencil_op(ctx, zfail)) { 324 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zfail)"); 325 return; 326 } 327 if (!validate_stencil_op(ctx, zpass)) { 328 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOp(zpass)"); 329 return; 330 } 331 332 if (face != 0) { 333 /* only set active face state */ 334 if (ctx->Stencil.ZFailFunc[face] == zfail && 335 ctx->Stencil.ZPassFunc[face] == zpass && 336 ctx->Stencil.FailFunc[face] == fail) 337 return; 338 FLUSH_VERTICES(ctx, _NEW_STENCIL); 339 ctx->Stencil.ZFailFunc[face] = zfail; 340 ctx->Stencil.ZPassFunc[face] = zpass; 341 ctx->Stencil.FailFunc[face] = fail; 342 343 /* Only propagate the change to the driver if EXT_stencil_two_side 344 * is enabled. 345 */ 346 if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) { 347 ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass); 348 } 349 } 350 else { 351 /* set both front and back state */ 352 if (ctx->Stencil.ZFailFunc[0] == zfail && 353 ctx->Stencil.ZFailFunc[1] == zfail && 354 ctx->Stencil.ZPassFunc[0] == zpass && 355 ctx->Stencil.ZPassFunc[1] == zpass && 356 ctx->Stencil.FailFunc[0] == fail && 357 ctx->Stencil.FailFunc[1] == fail) 358 return; 359 FLUSH_VERTICES(ctx, _NEW_STENCIL); 360 ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail; 361 ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass; 362 ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail; 363 if (ctx->Driver.StencilOpSeparate) { 364 ctx->Driver.StencilOpSeparate(ctx, 365 ((ctx->Stencil.TestTwoSide) 366 ? GL_FRONT : GL_FRONT_AND_BACK), 367 fail, zfail, zpass); 368 } 369 } 370} 371 372 373 374/* GL_EXT_stencil_two_side */ 375void GLAPIENTRY 376_mesa_ActiveStencilFaceEXT(GLenum face) 377{ 378 GET_CURRENT_CONTEXT(ctx); 379 380 if (MESA_VERBOSE & VERBOSE_API) 381 _mesa_debug(ctx, "glActiveStencilFaceEXT()\n"); 382 383 if (!ctx->Extensions.EXT_stencil_two_side) { 384 _mesa_error(ctx, GL_INVALID_OPERATION, "glActiveStencilFaceEXT"); 385 return; 386 } 387 388 if (face == GL_FRONT || face == GL_BACK) { 389 ctx->Stencil.ActiveFace = (face == GL_FRONT) ? 0 : 2; 390 } 391 else { 392 _mesa_error(ctx, GL_INVALID_ENUM, "glActiveStencilFaceEXT(face)"); 393 } 394} 395 396 397 398/** 399 * OpenGL 2.0 function. 400 * \todo Make StencilOp() call this function. And eventually remove the 401 * ctx->Driver.StencilOp function and use ctx->Driver.StencilOpSeparate 402 * instead. 403 */ 404void GLAPIENTRY 405_mesa_StencilOpSeparate(GLenum face, GLenum sfail, GLenum zfail, GLenum zpass) 406{ 407 GLboolean set = GL_FALSE; 408 GET_CURRENT_CONTEXT(ctx); 409 410 if (MESA_VERBOSE & VERBOSE_API) 411 _mesa_debug(ctx, "glStencilOpSeparate()\n"); 412 413 if (!validate_stencil_op(ctx, sfail)) { 414 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(sfail)"); 415 return; 416 } 417 if (!validate_stencil_op(ctx, zfail)) { 418 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zfail)"); 419 return; 420 } 421 if (!validate_stencil_op(ctx, zpass)) { 422 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(zpass)"); 423 return; 424 } 425 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 426 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilOpSeparate(face)"); 427 return; 428 } 429 430 if (face != GL_BACK) { 431 /* set front */ 432 if (ctx->Stencil.ZFailFunc[0] != zfail || 433 ctx->Stencil.ZPassFunc[0] != zpass || 434 ctx->Stencil.FailFunc[0] != sfail){ 435 FLUSH_VERTICES(ctx, _NEW_STENCIL); 436 ctx->Stencil.ZFailFunc[0] = zfail; 437 ctx->Stencil.ZPassFunc[0] = zpass; 438 ctx->Stencil.FailFunc[0] = sfail; 439 set = GL_TRUE; 440 } 441 } 442 if (face != GL_FRONT) { 443 /* set back */ 444 if (ctx->Stencil.ZFailFunc[1] != zfail || 445 ctx->Stencil.ZPassFunc[1] != zpass || 446 ctx->Stencil.FailFunc[1] != sfail) { 447 FLUSH_VERTICES(ctx, _NEW_STENCIL); 448 ctx->Stencil.ZFailFunc[1] = zfail; 449 ctx->Stencil.ZPassFunc[1] = zpass; 450 ctx->Stencil.FailFunc[1] = sfail; 451 set = GL_TRUE; 452 } 453 } 454 if (set && ctx->Driver.StencilOpSeparate) { 455 ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass); 456 } 457} 458 459 460/* OpenGL 2.0 */ 461void GLAPIENTRY 462_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) 463{ 464 GET_CURRENT_CONTEXT(ctx); 465 const GLint stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1; 466 467 if (MESA_VERBOSE & VERBOSE_API) 468 _mesa_debug(ctx, "glStencilFuncSeparate()\n"); 469 470 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 471 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(face)"); 472 return; 473 } 474 if (!validate_stencil_func(ctx, func)) { 475 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilFuncSeparate(func)"); 476 return; 477 } 478 479 ref = CLAMP(ref, 0, stencilMax); 480 481 FLUSH_VERTICES(ctx, _NEW_STENCIL); 482 483 if (face != GL_BACK) { 484 /* set front */ 485 ctx->Stencil.Function[0] = func; 486 ctx->Stencil.Ref[0] = ref; 487 ctx->Stencil.ValueMask[0] = mask; 488 } 489 if (face != GL_FRONT) { 490 /* set back */ 491 ctx->Stencil.Function[1] = func; 492 ctx->Stencil.Ref[1] = ref; 493 ctx->Stencil.ValueMask[1] = mask; 494 } 495 if (ctx->Driver.StencilFuncSeparate) { 496 ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); 497 } 498} 499 500 501/* OpenGL 2.0 */ 502void GLAPIENTRY 503_mesa_StencilMaskSeparate(GLenum face, GLuint mask) 504{ 505 GET_CURRENT_CONTEXT(ctx); 506 507 if (MESA_VERBOSE & VERBOSE_API) 508 _mesa_debug(ctx, "glStencilMaskSeparate()\n"); 509 510 if (face != GL_FRONT && face != GL_BACK && face != GL_FRONT_AND_BACK) { 511 _mesa_error(ctx, GL_INVALID_ENUM, "glStencilaMaskSeparate(face)"); 512 return; 513 } 514 515 FLUSH_VERTICES(ctx, _NEW_STENCIL); 516 517 if (face != GL_BACK) { 518 ctx->Stencil.WriteMask[0] = mask; 519 } 520 if (face != GL_FRONT) { 521 ctx->Stencil.WriteMask[1] = mask; 522 } 523 if (ctx->Driver.StencilMaskSeparate) { 524 ctx->Driver.StencilMaskSeparate(ctx, face, mask); 525 } 526} 527 528 529/** 530 * Update derived stencil state. 531 */ 532void 533_mesa_update_stencil(struct gl_context *ctx) 534{ 535 const GLint face = ctx->Stencil._BackFace; 536 537 ctx->Stencil._Enabled = (ctx->Stencil.Enabled && 538 ctx->DrawBuffer->Visual.stencilBits > 0); 539 540 ctx->Stencil._TestTwoSide = 541 ctx->Stencil._Enabled && 542 (ctx->Stencil.Function[0] != ctx->Stencil.Function[face] || 543 ctx->Stencil.FailFunc[0] != ctx->Stencil.FailFunc[face] || 544 ctx->Stencil.ZPassFunc[0] != ctx->Stencil.ZPassFunc[face] || 545 ctx->Stencil.ZFailFunc[0] != ctx->Stencil.ZFailFunc[face] || 546 ctx->Stencil.Ref[0] != ctx->Stencil.Ref[face] || 547 ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[face] || 548 ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[face]); 549 550 ctx->Stencil._WriteEnabled = 551 ctx->Stencil._Enabled && 552 (ctx->Stencil.WriteMask[0] != 0 || 553 (ctx->Stencil._TestTwoSide && ctx->Stencil.WriteMask[face] != 0)); 554} 555 556 557/** 558 * Initialize the context stipple state. 559 * 560 * \param ctx GL context. 561 * 562 * Initializes __struct gl_contextRec::Stencil attribute group. 563 */ 564void 565_mesa_init_stencil(struct gl_context *ctx) 566{ 567 ctx->Stencil.Enabled = GL_FALSE; 568 ctx->Stencil.TestTwoSide = GL_FALSE; 569 ctx->Stencil.ActiveFace = 0; /* 0 = GL_FRONT, 2 = GL_BACK */ 570 ctx->Stencil.Function[0] = GL_ALWAYS; 571 ctx->Stencil.Function[1] = GL_ALWAYS; 572 ctx->Stencil.Function[2] = GL_ALWAYS; 573 ctx->Stencil.FailFunc[0] = GL_KEEP; 574 ctx->Stencil.FailFunc[1] = GL_KEEP; 575 ctx->Stencil.FailFunc[2] = GL_KEEP; 576 ctx->Stencil.ZPassFunc[0] = GL_KEEP; 577 ctx->Stencil.ZPassFunc[1] = GL_KEEP; 578 ctx->Stencil.ZPassFunc[2] = GL_KEEP; 579 ctx->Stencil.ZFailFunc[0] = GL_KEEP; 580 ctx->Stencil.ZFailFunc[1] = GL_KEEP; 581 ctx->Stencil.ZFailFunc[2] = GL_KEEP; 582 ctx->Stencil.Ref[0] = 0; 583 ctx->Stencil.Ref[1] = 0; 584 ctx->Stencil.Ref[2] = 0; 585 ctx->Stencil.ValueMask[0] = ~0U; 586 ctx->Stencil.ValueMask[1] = ~0U; 587 ctx->Stencil.ValueMask[2] = ~0U; 588 ctx->Stencil.WriteMask[0] = ~0U; 589 ctx->Stencil.WriteMask[1] = ~0U; 590 ctx->Stencil.WriteMask[2] = ~0U; 591 ctx->Stencil.Clear = 0; 592 ctx->Stencil._BackFace = 1; 593} 594