- gl_problem(ctx, "Bad stencil func in gl_stencil_pixels");
- return 0;
- }
-
- if (ctx->Stencil.FailFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc, fail );
- }
-
- return !allfail;
-}
-
-
-
-
-/*
- * Apply stencil and depth testing to an array of pixels.
- * This is used both for software and hardware stencil buffers.
- *
- * The comments in this function are a bit sparse but the code is
- * almost identical to stencil_and_depth_test_span(), which is well
- * commented.
- *
- * Input: n - number of pixels in the array
- * x, y - array of [n] pixel positions
- * z - array [n] of z values
- * mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
- * Output: mask - array [n] of flags (1=stencil and depth test passed)
- * Return: GL_TRUE - all fragments failed the testing
- * GL_FALSE - one or more fragments passed the testing
- */
-GLboolean
-gl_stencil_and_depth_test_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLdepth z[], GLubyte mask[] )
-{
- ASSERT(ctx->Stencil.Enabled);
- ASSERT(n <= PB_SIZE);
-
- if (ctx->Driver.WriteStencilPixels) {
- /*** Hardware stencil buffer ***/
- GLstencil stencil[PB_SIZE];
- GLubyte mask[PB_SIZE];
-
- ASSERT(ctx->Driver.ReadStencilPixels);
- (*ctx->Driver.ReadStencilPixels)(ctx, n, x, y, stencil);
-
-
- if (do_stencil_test( ctx, n, stencil, mask ) == GL_FALSE) {
- /* all fragments failed the stencil test, we're done. */
- return GL_FALSE;
- }
-
- if (ctx->Depth.Test == GL_FALSE) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, mask );
- }
- else {
- GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
- GLuint i;
-
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
-
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
-
- for (i=0;i<n;i++) {
- ASSERT(mask[i] == 0 || mask[i] == 1);
- passmask[i] = oldmask[i] & mask[i];
- failmask[i] = oldmask[i] & (mask[i] ^ 1);
- }
-
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZFailFunc, n, stencil, failmask );
- }
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op( ctx, ctx->Stencil.ZPassFunc, n, stencil, passmask );
- }
- }
-
- /* Write updated stencil values into hardware stencil buffer */
- (ctx->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, mask );
-
- return GL_TRUE;
-
- }
- else {
- /*** Software stencil buffer ***/
-
- if (stencil_test_pixels(ctx, n, x, y, mask) == GL_FALSE) {
- /* all fragments failed the stencil test, we're done. */
- return GL_FALSE;
- }
-
-
- if (ctx->Depth.Test==GL_FALSE) {
- apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.ZPassFunc, mask );
- }
- else {
- GLubyte passmask[PB_SIZE], failmask[PB_SIZE], oldmask[PB_SIZE];
- GLuint i;
-
- MEMCPY(oldmask, mask, n * sizeof(GLubyte));
-
- _mesa_depth_test_pixels(ctx, n, x, y, z, mask);
-
- for (i=0;i<n;i++) {
- ASSERT(mask[i] == 0 || mask[i] == 1);
- passmask[i] = oldmask[i] & mask[i];
- failmask[i] = oldmask[i] & (mask[i] ^ 1);
- }
-
- if (ctx->Stencil.ZFailFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y,
- ctx->Stencil.ZFailFunc, failmask );
- }
- if (ctx->Stencil.ZPassFunc != GL_KEEP) {
- apply_stencil_op_to_pixels( ctx, n, x, y,
- ctx->Stencil.ZPassFunc, passmask );
- }
- }
-
- return GL_TRUE; /* one or more fragments passed both tests */