1 /* $Id: stencil.c,v 1.11 1999/12/04 21:23:55 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
44 _mesa_ClearStencil( GLint s
)
46 GET_CURRENT_CONTEXT(ctx
);
47 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glClearStencil");
48 ctx
->Stencil
.Clear
= (GLstencil
) s
;
50 if (ctx
->Driver
.ClearStencil
) {
51 (*ctx
->Driver
.ClearStencil
)( ctx
, s
);
58 _mesa_StencilFunc( GLenum func
, GLint ref
, GLuint mask
)
60 GET_CURRENT_CONTEXT(ctx
);
63 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glStencilFunc");
74 ctx
->Stencil
.Function
= func
;
77 gl_error( ctx
, GL_INVALID_ENUM
, "glStencilFunc" );
81 maxref
= (1 << STENCIL_BITS
) - 1;
82 ctx
->Stencil
.Ref
= (GLstencil
) CLAMP( ref
, 0, maxref
);
83 ctx
->Stencil
.ValueMask
= (GLstencil
) mask
;
85 if (ctx
->Driver
.StencilFunc
) {
86 (*ctx
->Driver
.StencilFunc
)( ctx
, func
, ctx
->Stencil
.Ref
, mask
);
93 _mesa_StencilMask( GLuint mask
)
95 GET_CURRENT_CONTEXT(ctx
);
96 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glStencilMask");
97 ctx
->Stencil
.WriteMask
= (GLstencil
) mask
;
99 if (ctx
->Driver
.StencilMask
) {
100 (*ctx
->Driver
.StencilMask
)( ctx
, mask
);
107 _mesa_StencilOp( GLenum fail
, GLenum zfail
, GLenum zpass
)
109 GET_CURRENT_CONTEXT(ctx
);
110 ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx
, "glStencilOp");
118 case GL_INCR_WRAP_EXT
:
119 case GL_DECR_WRAP_EXT
:
120 ctx
->Stencil
.FailFunc
= fail
;
123 gl_error( ctx
, GL_INVALID_ENUM
, "glStencilOp" );
133 case GL_INCR_WRAP_EXT
:
134 case GL_DECR_WRAP_EXT
:
135 ctx
->Stencil
.ZFailFunc
= zfail
;
138 gl_error( ctx
, GL_INVALID_ENUM
, "glStencilOp" );
148 case GL_INCR_WRAP_EXT
:
149 case GL_DECR_WRAP_EXT
:
150 ctx
->Stencil
.ZPassFunc
= zpass
;
153 gl_error( ctx
, GL_INVALID_ENUM
, "glStencilOp" );
157 if (ctx
->Driver
.StencilOp
) {
158 (*ctx
->Driver
.StencilOp
)( ctx
, fail
, zfail
, zpass
);
166 IF stencil test fails THEN
167 Apply fail-op to stencil value
168 Don't write the pixel (RGBA,Z)
170 IF doing depth test && depth test fails THEN
171 Apply zfail-op to stencil value
172 Write RGBA and Z to appropriate buffers
174 Apply zpass-op to stencil value
183 * Return the address of a stencil buffer value given the window coords:
185 #define STENCIL_ADDRESS(X,Y) \
186 (ctx->DrawBuffer->Stencil + ctx->DrawBuffer->Width * (Y) + (X))
191 * Apply the given stencil operator to the array of stencil values.
192 * Don't touch stencil[i] if mask[i] is zero.
193 * Input: n - number of pixels in the span
194 * oper - the stencil buffer operator
195 * stencil - array of stencil values
196 * mask - array [n] of flag: 1=apply operator, 0=don't apply operator
198 static void apply_stencil_op( GLcontext
*ctx
, GLenum oper
,
199 GLuint n
, GLstencil stencil
[], GLubyte mask
[] )
201 const GLstencil ref
= ctx
->Stencil
.Ref
;
202 const GLstencil wrtmask
= ctx
->Stencil
.WriteMask
;
203 const GLstencil invmask
= (GLstencil
) (~ctx
->Stencil
.WriteMask
);
221 stencil
[i
] = (GLstencil
) (stencil
[i
] & invmask
);
237 GLstencil s
= stencil
[i
];
238 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& ref
));
247 GLstencil s
= stencil
[i
];
248 if (s
< STENCIL_MAX
) {
249 stencil
[i
] = (GLstencil
) (s
+1);
257 /* VERIFY logic of adding 1 to a write-masked value */
258 GLstencil s
= stencil
[i
];
259 if (s
< STENCIL_MAX
) {
260 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& (s
+1)));
270 GLstencil s
= stencil
[i
];
272 stencil
[i
] = (GLstencil
) (s
-1);
280 /* VERIFY logic of subtracting 1 to a write-masked value */
281 GLstencil s
= stencil
[i
];
283 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& (s
-1)));
289 case GL_INCR_WRAP_EXT
:
300 GLstencil s
= stencil
[i
];
301 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& (stencil
[i
]+1)));
306 case GL_DECR_WRAP_EXT
:
317 GLstencil s
= stencil
[i
];
318 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& (stencil
[i
]-1)));
327 GLstencil s
= stencil
[i
];
328 stencil
[i
] = (GLstencil
) ~s
;
335 GLstencil s
= stencil
[i
];
336 stencil
[i
] = (GLstencil
) ((invmask
& s
) | (wrtmask
& ~s
));
342 gl_problem(ctx
, "Bad stencil op in apply_stencil_op");
350 * Apply stencil test to a span of pixels before depth buffering.
351 * Input: n - number of pixels in the span
352 * x, y - coordinate of left-most pixel in the span
353 * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
354 * Output: mask - pixels which fail the stencil test will have their
355 * mask flag set to 0.
356 * Return: 0 = all pixels failed, 1 = zero or more pixels passed.
358 GLint
gl_stencil_span( GLcontext
*ctx
,
359 GLuint n
, GLint x
, GLint y
, GLubyte mask
[] )
361 GLubyte fail
[MAX_WIDTH
];
367 stencil
= STENCIL_ADDRESS( x
, y
);
370 * Perform stencil test. The results of this operation are stored
371 * in the fail[] array:
372 * IF fail[i] is non-zero THEN
373 * the stencil fail operator is to be applied
375 * the stencil fail operator is not to be applied
378 switch (ctx
->Stencil
.Function
) {
393 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
396 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
412 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
415 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
431 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
434 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
450 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
453 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
469 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
472 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
488 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
491 s
= (GLstencil
) (stencil
[i
] & ctx
->Stencil
.ValueMask
);
513 gl_problem(ctx
, "Bad stencil func in gl_stencil_span");
517 if (ctx
->Stencil
.FailFunc
!= GL_KEEP
) {
518 apply_stencil_op( ctx
, ctx
->Stencil
.FailFunc
, n
, stencil
, fail
);
521 return (allfail
) ? 0 : 1;
528 * Apply the combination depth-buffer/stencil operator to a span of pixels.
529 * Input: n - number of pixels in the span
530 * x, y - location of leftmost pixel in span
531 * z - array [n] of z values
532 * Input: mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
533 * Output: mask - array [n] of flags (1=depth test passed, 0=failed)
535 void gl_depth_stencil_span( GLcontext
*ctx
,
536 GLuint n
, GLint x
, GLint y
, const GLdepth z
[],
539 GLstencil
*stencil
= STENCIL_ADDRESS(x
, y
);
541 if (ctx
->Depth
.Test
==GL_FALSE
) {
543 * No depth buffer, just apply zpass stencil function to active pixels.
545 apply_stencil_op( ctx
, ctx
->Stencil
.ZPassFunc
, n
, stencil
, mask
);
549 * Perform depth buffering, then apply zpass or zfail stencil function.
551 GLubyte passmask
[MAX_WIDTH
], failmask
[MAX_WIDTH
], oldmask
[MAX_WIDTH
];
554 /* save the current mask bits */
555 MEMCPY(oldmask
, mask
, n
* sizeof(GLubyte
));
557 /* apply the depth test */
558 if (ctx
->Driver
.DepthTestSpan
)
559 (*ctx
->Driver
.DepthTestSpan
)( ctx
, n
, x
, y
, z
, mask
);
561 /* Set the stencil pass/fail flags according to result of depth testing.
562 * if oldmask[i] == 0 then
563 * Don't touch the stencil value
564 * else if oldmask[i] and newmask[i] then
567 * assert(oldmask[i] && !newmask[i])
572 ASSERT(mask
[i
] == 0 || mask
[i
] == 1);
573 passmask
[i
] = oldmask
[i
] & mask
[i
];
574 failmask
[i
] = oldmask
[i
] & (mask
[i
] ^ 1);
577 /* apply the pass and fail operations */
578 if (ctx
->Stencil
.ZFailFunc
!= GL_KEEP
) {
579 apply_stencil_op( ctx
, ctx
->Stencil
.ZFailFunc
, n
, stencil
, failmask
);
581 if (ctx
->Stencil
.ZPassFunc
!= GL_KEEP
) {
582 apply_stencil_op( ctx
, ctx
->Stencil
.ZPassFunc
, n
, stencil
, passmask
);
591 * Apply the given stencil operator for each pixel in the array whose
593 * Input: n - number of pixels in the span
594 * x, y - array of [n] pixels
595 * operator - the stencil buffer operator
596 * mask - array [n] of flag: 1=apply operator, 0=don't apply operator
598 static void apply_stencil_op_to_pixels( GLcontext
*ctx
,
599 GLuint n
, const GLint x
[],
601 GLenum oper
, GLubyte mask
[] )
605 GLstencil wrtmask
, invmask
;
607 wrtmask
= ctx
->Stencil
.WriteMask
;
608 invmask
= (GLstencil
) (~ctx
->Stencil
.WriteMask
);
610 ref
= ctx
->Stencil
.Ref
;
620 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
628 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
629 *sptr
= (GLstencil
) (invmask
& *sptr
);
638 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
646 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
647 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& ref
));
656 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
657 if (*sptr
< STENCIL_MAX
) {
658 *sptr
= (GLstencil
) (*sptr
+ 1);
666 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
667 if (*sptr
< STENCIL_MAX
) {
668 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& (*sptr
+1)));
678 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
680 *sptr
= (GLstencil
) (*sptr
- 1);
688 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
690 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& (*sptr
-1)));
696 case GL_INCR_WRAP_EXT
:
700 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
701 *sptr
= (GLstencil
) (*sptr
+ 1);
708 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
709 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& (*sptr
+1)));
714 case GL_DECR_WRAP_EXT
:
718 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
719 *sptr
= (GLstencil
) (*sptr
- 1);
726 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
727 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& (*sptr
-1)));
736 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
737 *sptr
= (GLstencil
) (~*sptr
);
744 GLstencil
*sptr
= STENCIL_ADDRESS( x
[i
], y
[i
] );
745 *sptr
= (GLstencil
) ((invmask
& *sptr
) | (wrtmask
& ~*sptr
));
751 gl_problem(ctx
, "Bad stencilop in apply_stencil_op_to_pixels");
758 * Apply stencil test to an array of pixels before depth buffering.
759 * Input: n - number of pixels in the span
760 * x, y - array of [n] pixels to stencil
761 * mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
762 * Output: mask - pixels which fail the stencil test will have their
763 * mask flag set to 0.
764 * Return: 0 = all pixels failed, 1 = zero or more pixels passed.
766 GLint
gl_stencil_pixels( GLcontext
*ctx
,
767 GLuint n
, const GLint x
[], const GLint y
[],
770 GLubyte fail
[PB_SIZE
];
776 * Perform stencil test. The results of this operation are stored
777 * in the fail[] array:
778 * IF fail[i] is non-zero THEN
779 * the stencil fail operator is to be applied
781 * the stencil fail operator is not to be applied
785 switch (ctx
->Stencil
.Function
) {
800 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
803 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
804 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
820 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
823 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
824 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
840 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
843 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
844 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
860 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
863 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
864 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
880 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
883 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
884 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
900 r
= (GLstencil
) (ctx
->Stencil
.Ref
& ctx
->Stencil
.ValueMask
);
903 GLstencil
*sptr
= STENCIL_ADDRESS(x
[i
],y
[i
]);
904 s
= (GLstencil
) (*sptr
& ctx
->Stencil
.ValueMask
);
926 gl_problem(ctx
, "Bad stencil func in gl_stencil_pixels");
930 apply_stencil_op_to_pixels( ctx
, n
, x
, y
, ctx
->Stencil
.FailFunc
, fail
);
932 return (allfail
) ? 0 : 1;
939 * Apply the combination depth-buffer/stencil operator to a span of pixels.
940 * Input: n - number of pixels in the span
941 * x, y - array of [n] pixels to stencil
942 * z - array [n] of z values
943 * Input: mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
944 * Output: mask - array [n] of flags (1=depth test passed, 0=failed)
946 void gl_depth_stencil_pixels( GLcontext
*ctx
,
947 GLuint n
, const GLint x
[], const GLint y
[],
948 const GLdepth z
[], GLubyte mask
[] )
950 if (ctx
->Depth
.Test
==GL_FALSE
) {
952 * No depth buffer, just apply zpass stencil function to active pixels.
954 apply_stencil_op_to_pixels( ctx
, n
, x
, y
, ctx
->Stencil
.ZPassFunc
, mask
);
958 * Perform depth buffering, then apply zpass or zfail stencil function.
960 GLubyte passmask
[PB_SIZE
], failmask
[PB_SIZE
], oldmask
[PB_SIZE
];
963 /* save the current mask bits */
964 MEMCPY(oldmask
, mask
, n
* sizeof(GLubyte
));
966 /* apply the depth test */
967 if (ctx
->Driver
.DepthTestPixels
)
968 (*ctx
->Driver
.DepthTestPixels
)( ctx
, n
, x
, y
, z
, mask
);
970 /* Set the stencil pass/fail flags according to result of depth testing.
971 * if oldmask[i] == 0 then
972 * Don't touch the stencil value
973 * else if oldmask[i] and newmask[i] then
976 * assert(oldmask[i] && !newmask[i])
981 ASSERT(mask
[i
] == 0 || mask
[i
] == 1);
982 passmask
[i
] = oldmask
[i
] & mask
[i
];
983 failmask
[i
] = oldmask
[i
] & (mask
[i
] ^ 1);
986 /* apply the pass and fail operations */
987 apply_stencil_op_to_pixels( ctx
, n
, x
, y
,
988 ctx
->Stencil
.ZFailFunc
, failmask
);
989 apply_stencil_op_to_pixels( ctx
, n
, x
, y
,
990 ctx
->Stencil
.ZPassFunc
, passmask
);
998 * Return a span of stencil values from the stencil buffer.
999 * Input: n - how many pixels
1000 * x,y - location of first pixel
1001 * Output: stencil - the array of stencil values
1003 void gl_read_stencil_span( GLcontext
*ctx
,
1004 GLuint n
, GLint x
, GLint y
, GLstencil stencil
[] )
1006 if (ctx
->DrawBuffer
->Stencil
) {
1007 const GLstencil
*s
= STENCIL_ADDRESS( x
, y
);
1008 #if STENCIL_BITS == 8
1009 MEMCPY( stencil
, s
, n
* sizeof(GLstencil
) );
1021 * Write a span of stencil values to the stencil buffer.
1022 * Input: n - how many pixels
1023 * x,y - location of first pixel
1024 * stencil - the array of stencil values
1026 void gl_write_stencil_span( GLcontext
*ctx
,
1027 GLuint n
, GLint x
, GLint y
,
1028 const GLstencil stencil
[] )
1030 if (ctx
->DrawBuffer
->Stencil
) {
1031 GLstencil
*s
= STENCIL_ADDRESS( x
, y
);
1032 #if STENCIL_BITS == 8
1033 MEMCPY( s
, stencil
, n
* sizeof(GLstencil
) );
1045 * Allocate a new stencil buffer. If there's an old one it will be
1046 * deallocated first. The new stencil buffer will be uninitialized.
1048 void gl_alloc_stencil_buffer( GLcontext
*ctx
)
1050 GLuint buffersize
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
1052 /* deallocate current stencil buffer if present */
1053 if (ctx
->DrawBuffer
->Stencil
) {
1054 FREE(ctx
->DrawBuffer
->Stencil
);
1055 ctx
->DrawBuffer
->Stencil
= NULL
;
1058 /* allocate new stencil buffer */
1059 ctx
->DrawBuffer
->Stencil
= (GLstencil
*) MALLOC(buffersize
* sizeof(GLstencil
));
1060 if (!ctx
->DrawBuffer
->Stencil
) {
1062 _mesa_set_enable( ctx
, GL_STENCIL_TEST
, GL_FALSE
);
1063 gl_error( ctx
, GL_OUT_OF_MEMORY
, "gl_alloc_stencil_buffer" );
1070 void gl_clear_stencil_buffer( GLcontext
*ctx
)
1072 if (ctx
->Visual
->StencilBits
==0 || !ctx
->DrawBuffer
->Stencil
) {
1073 /* no stencil buffer */
1077 if (ctx
->Scissor
.Enabled
) {
1078 /* clear scissor region only */
1079 const GLint width
= ctx
->DrawBuffer
->Xmax
- ctx
->DrawBuffer
->Xmin
+ 1;
1080 if (ctx
->Stencil
.WriteMask
!= STENCIL_MAX
) {
1081 /* must apply mask to the clear */
1083 for (y
=ctx
->DrawBuffer
->Ymin
; y
<=ctx
->DrawBuffer
->Ymax
; y
++) {
1084 GLstencil
*ptr
= STENCIL_ADDRESS( ctx
->DrawBuffer
->Xmin
, y
);
1086 const GLstencil mask
= ctx
->Stencil
.WriteMask
;
1087 const GLstencil invMask
= ~mask
;
1088 const GLstencil clearVal
= (ctx
->Stencil
.Clear
& mask
);
1089 for (x
= 0; x
< width
; x
++) {
1090 ptr
[x
] = (ptr
[x
] & invMask
) | clearVal
;
1097 for (y
=ctx
->DrawBuffer
->Ymin
; y
<=ctx
->DrawBuffer
->Ymax
; y
++) {
1098 GLstencil
*ptr
= STENCIL_ADDRESS( ctx
->DrawBuffer
->Xmin
, y
);
1100 MEMSET( ptr
, ctx
->Stencil
.Clear
, width
* sizeof(GLstencil
) );
1103 for (x
= 0; x
< width
; x
++)
1104 ptr
[x
] = ctx
->Stencil
.Clear
;
1110 /* clear whole stencil buffer */
1111 if (ctx
->Stencil
.WriteMask
!= STENCIL_MAX
) {
1112 /* must apply mask to the clear */
1113 const GLuint n
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
1114 GLstencil
*buffer
= ctx
->DrawBuffer
->Stencil
;
1115 const GLstencil mask
= ctx
->Stencil
.WriteMask
;
1116 const GLstencil invMask
= ~mask
;
1117 const GLstencil clearVal
= (ctx
->Stencil
.Clear
& mask
);
1119 for (i
= 0; i
< n
; i
++) {
1120 buffer
[i
] = (buffer
[i
] & invMask
) | clearVal
;
1124 /* clear whole buffer without masking */
1125 const GLuint n
= ctx
->DrawBuffer
->Width
* ctx
->DrawBuffer
->Height
;
1126 GLstencil
*buffer
= ctx
->DrawBuffer
->Stencil
;
1129 MEMSET(buffer
, ctx
->Stencil
.Clear
, n
* sizeof(GLstencil
) );
1132 for (i
= 0; i
< n
; i
++) {
1133 buffer
[i
] = ctx
->Stencil
.Clear
;