s_stencil.c revision c1f859d4
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#include "main/glheader.h"
27#include "main/context.h"
28#include "main/imports.h"
29
30#include "s_context.h"
31#include "s_depth.h"
32#include "s_stencil.h"
33#include "s_span.h"
34
35
36
37/* Stencil Logic:
38
39IF stencil test fails THEN
40   Apply fail-op to stencil value
41   Don't write the pixel (RGBA,Z)
42ELSE
43   IF doing depth test && depth test fails THEN
44      Apply zfail-op to stencil value
45      Write RGBA and Z to appropriate buffers
46   ELSE
47      Apply zpass-op to stencil value
48ENDIF
49
50*/
51
52
53/**
54 * Apply the given stencil operator to the array of stencil values.
55 * Don't touch stencil[i] if mask[i] is zero.
56 * Input:  n - size of stencil array
57 *         oper - the stencil buffer operator
58 *         face - 0 or 1 for front or back face operation
59 *         stencil - array of stencil values
60 *         mask - array [n] of flag:  1=apply operator, 0=don't apply operator
61 * Output:  stencil - modified values
62 */
63static void
64apply_stencil_op( const GLcontext *ctx, GLenum oper, GLuint face,
65                  GLuint n, GLstencil stencil[], const GLubyte mask[] )
66{
67   const GLstencil ref = ctx->Stencil.Ref[face];
68   const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
69   const GLstencil invmask = (GLstencil) (~wrtmask);
70   const GLstencil stencilMax = (1 << ctx->DrawBuffer->Visual.stencilBits) - 1;
71   GLuint i;
72
73   switch (oper) {
74      case GL_KEEP:
75         /* do nothing */
76         break;
77      case GL_ZERO:
78	 if (invmask==0) {
79	    for (i=0;i<n;i++) {
80	       if (mask[i]) {
81		  stencil[i] = 0;
82	       }
83	    }
84	 }
85	 else {
86	    for (i=0;i<n;i++) {
87	       if (mask[i]) {
88		  stencil[i] = (GLstencil) (stencil[i] & invmask);
89	       }
90	    }
91	 }
92	 break;
93      case GL_REPLACE:
94	 if (invmask==0) {
95	    for (i=0;i<n;i++) {
96	       if (mask[i]) {
97                  stencil[i] = ref;
98	       }
99	    }
100	 }
101	 else {
102	    for (i=0;i<n;i++) {
103	       if (mask[i]) {
104		  GLstencil s = stencil[i];
105		  stencil[i] = (GLstencil) ((invmask & s ) | (wrtmask & ref));
106	       }
107	    }
108	 }
109	 break;
110      case GL_INCR:
111	 if (invmask==0) {
112	    for (i=0;i<n;i++) {
113	       if (mask[i]) {
114		  GLstencil s = stencil[i];
115		  if (s < stencilMax) {
116		     stencil[i] = (GLstencil) (s+1);
117		  }
118	       }
119	    }
120	 }
121	 else {
122	    for (i=0;i<n;i++) {
123	       if (mask[i]) {
124		  /* VERIFY logic of adding 1 to a write-masked value */
125		  GLstencil s = stencil[i];
126		  if (s < stencilMax) {
127		     stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
128		  }
129	       }
130	    }
131	 }
132	 break;
133      case GL_DECR:
134	 if (invmask==0) {
135	    for (i=0;i<n;i++) {
136	       if (mask[i]) {
137		  GLstencil s = stencil[i];
138		  if (s>0) {
139		     stencil[i] = (GLstencil) (s-1);
140		  }
141	       }
142	    }
143	 }
144	 else {
145	    for (i=0;i<n;i++) {
146	       if (mask[i]) {
147		  /* VERIFY logic of subtracting 1 to a write-masked value */
148		  GLstencil s = stencil[i];
149		  if (s>0) {
150		     stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
151		  }
152	       }
153	    }
154	 }
155	 break;
156      case GL_INCR_WRAP_EXT:
157	 if (invmask==0) {
158	    for (i=0;i<n;i++) {
159	       if (mask[i]) {
160                  stencil[i]++;
161	       }
162	    }
163	 }
164	 else {
165	    for (i=0;i<n;i++) {
166	       if (mask[i]) {
167                  GLstencil s = stencil[i];
168                  stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
169	       }
170	    }
171	 }
172	 break;
173      case GL_DECR_WRAP_EXT:
174	 if (invmask==0) {
175	    for (i=0;i<n;i++) {
176	       if (mask[i]) {
177		  stencil[i]--;
178	       }
179	    }
180	 }
181	 else {
182	    for (i=0;i<n;i++) {
183	       if (mask[i]) {
184                  GLstencil s = stencil[i];
185                  stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
186	       }
187	    }
188	 }
189	 break;
190      case GL_INVERT:
191	 if (invmask==0) {
192	    for (i=0;i<n;i++) {
193	       if (mask[i]) {
194		  GLstencil s = stencil[i];
195		  stencil[i] = (GLstencil) ~s;
196	       }
197	    }
198	 }
199	 else {
200	    for (i=0;i<n;i++) {
201	       if (mask[i]) {
202		  GLstencil s = stencil[i];
203		  stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & ~s));
204	       }
205	    }
206	 }
207	 break;
208      default:
209         _mesa_problem(ctx, "Bad stencil op in apply_stencil_op");
210   }
211}
212
213
214
215
216/**
217 * Apply stencil test to an array of stencil values (before depth buffering).
218 * Input:  face - 0 or 1 for front or back-face polygons
219 *         n - number of pixels in the array
220 *         stencil - array of [n] stencil values
221 *         mask - array [n] of flag:  0=skip the pixel, 1=stencil the pixel
222 * Output:  mask - pixels which fail the stencil test will have their
223 *                 mask flag set to 0.
224 *          stencil - updated stencil values (where the test passed)
225 * Return:  GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
226 */
227static GLboolean
228do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
229                 GLubyte mask[] )
230{
231   GLubyte fail[MAX_WIDTH];
232   GLboolean allfail = GL_FALSE;
233   GLuint i;
234   GLstencil r, s;
235   const GLuint valueMask = ctx->Stencil.ValueMask[face];
236
237   ASSERT(n <= MAX_WIDTH);
238
239   /*
240    * Perform stencil test.  The results of this operation are stored
241    * in the fail[] array:
242    *   IF fail[i] is non-zero THEN
243    *       the stencil fail operator is to be applied
244    *   ELSE
245    *       the stencil fail operator is not to be applied
246    *   ENDIF
247    */
248   switch (ctx->Stencil.Function[face]) {
249      case GL_NEVER:
250         /* never pass; always fail */
251         for (i=0;i<n;i++) {
252	    if (mask[i]) {
253	       mask[i] = 0;
254	       fail[i] = 1;
255	    }
256	    else {
257	       fail[i] = 0;
258	    }
259	 }
260	 allfail = GL_TRUE;
261	 break;
262      case GL_LESS:
263	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
264	 for (i=0;i<n;i++) {
265	    if (mask[i]) {
266	       s = (GLstencil) (stencil[i] & valueMask);
267	       if (r < s) {
268		  /* passed */
269		  fail[i] = 0;
270	       }
271	       else {
272		  fail[i] = 1;
273		  mask[i] = 0;
274	       }
275	    }
276	    else {
277	       fail[i] = 0;
278	    }
279	 }
280	 break;
281      case GL_LEQUAL:
282	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
283	 for (i=0;i<n;i++) {
284	    if (mask[i]) {
285	       s = (GLstencil) (stencil[i] & valueMask);
286	       if (r <= s) {
287		  /* pass */
288		  fail[i] = 0;
289	       }
290	       else {
291		  fail[i] = 1;
292		  mask[i] = 0;
293	       }
294	    }
295	    else {
296	       fail[i] = 0;
297	    }
298	 }
299	 break;
300      case GL_GREATER:
301	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
302	 for (i=0;i<n;i++) {
303	    if (mask[i]) {
304	       s = (GLstencil) (stencil[i] & valueMask);
305	       if (r > s) {
306		  /* passed */
307		  fail[i] = 0;
308	       }
309	       else {
310		  fail[i] = 1;
311		  mask[i] = 0;
312	       }
313	    }
314	    else {
315	       fail[i] = 0;
316	    }
317	 }
318	 break;
319      case GL_GEQUAL:
320	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
321	 for (i=0;i<n;i++) {
322	    if (mask[i]) {
323	       s = (GLstencil) (stencil[i] & valueMask);
324	       if (r >= s) {
325		  /* passed */
326		  fail[i] = 0;
327	       }
328	       else {
329		  fail[i] = 1;
330		  mask[i] = 0;
331	       }
332	    }
333	    else {
334	       fail[i] = 0;
335	    }
336	 }
337	 break;
338      case GL_EQUAL:
339	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
340	 for (i=0;i<n;i++) {
341	    if (mask[i]) {
342	       s = (GLstencil) (stencil[i] & valueMask);
343	       if (r == s) {
344		  /* passed */
345		  fail[i] = 0;
346	       }
347	       else {
348		  fail[i] = 1;
349		  mask[i] = 0;
350	       }
351	    }
352	    else {
353	       fail[i] = 0;
354	    }
355	 }
356	 break;
357      case GL_NOTEQUAL:
358	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
359	 for (i=0;i<n;i++) {
360	    if (mask[i]) {
361	       s = (GLstencil) (stencil[i] & valueMask);
362	       if (r != s) {
363		  /* passed */
364		  fail[i] = 0;
365	       }
366	       else {
367		  fail[i] = 1;
368		  mask[i] = 0;
369	       }
370	    }
371	    else {
372	       fail[i] = 0;
373	    }
374	 }
375	 break;
376      case GL_ALWAYS:
377	 /* always pass */
378	 for (i=0;i<n;i++) {
379	    fail[i] = 0;
380	 }
381	 break;
382      default:
383         _mesa_problem(ctx, "Bad stencil func in gl_stencil_span");
384         return 0;
385   }
386
387   if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
388      apply_stencil_op( ctx, ctx->Stencil.FailFunc[face], face, n, stencil, fail );
389   }
390
391   return !allfail;
392}
393
394
395/**
396 * Compute the zpass/zfail masks by comparing the pre- and post-depth test
397 * masks.
398 */
399static INLINE void
400compute_pass_fail_masks(GLuint n, const GLubyte origMask[],
401                        const GLubyte newMask[],
402                        GLubyte passMask[], GLubyte failMask[])
403{
404   GLuint i;
405   for (i = 0; i < n; i++) {
406      ASSERT(newMask[i] == 0 || newMask[i] == 1);
407      passMask[i] = origMask[i] & newMask[i];
408      failMask[i] = origMask[i] & (newMask[i] ^ 1);
409   }
410}
411
412
413/**
414 * Apply stencil and depth testing to the span of pixels.
415 * Both software and hardware stencil buffers are acceptable.
416 * Input:  n - number of pixels in the span
417 *         x, y - location of leftmost pixel in span
418 *         z - array [n] of z values
419 *         mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
420 * Output:  mask - array [n] of flags (1=stencil and depth test passed)
421 * Return: GL_FALSE - all fragments failed the testing
422 *         GL_TRUE - one or more fragments passed the testing
423 *
424 */
425static GLboolean
426stencil_and_ztest_span(GLcontext *ctx, SWspan *span, GLuint face)
427{
428   struct gl_framebuffer *fb = ctx->DrawBuffer;
429   struct gl_renderbuffer *rb = fb->_StencilBuffer;
430   GLstencil stencilRow[MAX_WIDTH];
431   GLstencil *stencil;
432   const GLuint n = span->end;
433   const GLint x = span->x;
434   const GLint y = span->y;
435   GLubyte *mask = span->array->mask;
436
437   ASSERT((span->arrayMask & SPAN_XY) == 0);
438   ASSERT(ctx->Stencil.Enabled);
439   ASSERT(n <= MAX_WIDTH);
440#ifdef DEBUG
441   if (ctx->Depth.Test) {
442      ASSERT(span->arrayMask & SPAN_Z);
443   }
444#endif
445
446   stencil = (GLstencil *) rb->GetPointer(ctx, rb, x, y);
447   if (!stencil) {
448      rb->GetRow(ctx, rb, n, x, y, stencilRow);
449      stencil = stencilRow;
450   }
451
452   /*
453    * Apply the stencil test to the fragments.
454    * failMask[i] is 1 if the stencil test failed.
455    */
456   if (do_stencil_test( ctx, face, n, stencil, mask ) == GL_FALSE) {
457      /* all fragments failed the stencil test, we're done. */
458      span->writeAll = GL_FALSE;
459      if (!rb->GetPointer(ctx, rb, 0, 0)) {
460         /* put updated stencil values into buffer */
461         rb->PutRow(ctx, rb, n, x, y, stencil, NULL);
462      }
463      return GL_FALSE;
464   }
465
466   /*
467    * Some fragments passed the stencil test, apply depth test to them
468    * and apply Zpass and Zfail stencil ops.
469    */
470   if (ctx->Depth.Test == GL_FALSE) {
471      /*
472       * No depth buffer, just apply zpass stencil function to active pixels.
473       */
474      apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, mask );
475   }
476   else {
477      /*
478       * Perform depth buffering, then apply zpass or zfail stencil function.
479       */
480      GLubyte passMask[MAX_WIDTH], failMask[MAX_WIDTH], origMask[MAX_WIDTH];
481
482      /* save the current mask bits */
483      _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
484
485      /* apply the depth test */
486      _swrast_depth_test_span(ctx, span);
487
488      compute_pass_fail_masks(n, origMask, mask, passMask, failMask);
489
490      /* apply the pass and fail operations */
491      if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
492         apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face,
493                           n, stencil, failMask );
494      }
495      if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
496         apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face,
497                           n, stencil, passMask );
498      }
499   }
500
501   /*
502    * Write updated stencil values back into hardware stencil buffer.
503    */
504   if (!rb->GetPointer(ctx, rb, 0, 0)) {
505      rb->PutRow(ctx, rb, n, x, y, stencil, NULL);
506   }
507
508   span->writeAll = GL_FALSE;
509
510   return GL_TRUE;  /* one or more fragments passed both tests */
511}
512
513
514
515/*
516 * Return the address of a stencil buffer value given the window coords:
517 */
518#define STENCIL_ADDRESS(X, Y)  (stencilStart + (Y) * stride + (X))
519
520
521
522/**
523 * Apply the given stencil operator for each pixel in the array whose
524 * mask flag is set.
525 * \note  This is for software stencil buffers only.
526 * Input:  n - number of pixels in the span
527 *         x, y - array of [n] pixels
528 *         operator - the stencil buffer operator
529 *         mask - array [n] of flag:  1=apply operator, 0=don't apply operator
530 */
531static void
532apply_stencil_op_to_pixels( GLcontext *ctx,
533                            GLuint n, const GLint x[], const GLint y[],
534                            GLenum oper, GLuint face, const GLubyte mask[] )
535{
536   struct gl_framebuffer *fb = ctx->DrawBuffer;
537   struct gl_renderbuffer *rb = fb->_StencilBuffer;
538   const GLstencil stencilMax = (1 << fb->Visual.stencilBits) - 1;
539   const GLstencil ref = ctx->Stencil.Ref[face];
540   const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
541   const GLstencil invmask = (GLstencil) (~wrtmask);
542   GLuint i;
543   GLstencil *stencilStart = (GLubyte *) rb->Data;
544   const GLuint stride = rb->Width;
545
546   ASSERT(rb->GetPointer(ctx, rb, 0, 0));
547   ASSERT(sizeof(GLstencil) == 1);
548
549   switch (oper) {
550      case GL_KEEP:
551         /* do nothing */
552         break;
553      case GL_ZERO:
554	 if (invmask==0) {
555	    for (i=0;i<n;i++) {
556	       if (mask[i]) {
557                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
558                  *sptr = 0;
559	       }
560	    }
561	 }
562	 else {
563	    for (i=0;i<n;i++) {
564	       if (mask[i]) {
565                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
566		  *sptr = (GLstencil) (invmask & *sptr);
567	       }
568	    }
569	 }
570	 break;
571      case GL_REPLACE:
572	 if (invmask==0) {
573	    for (i=0;i<n;i++) {
574	       if (mask[i]) {
575                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
576                  *sptr = ref;
577	       }
578	    }
579	 }
580	 else {
581	    for (i=0;i<n;i++) {
582	       if (mask[i]) {
583                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
584		  *sptr = (GLstencil) ((invmask & *sptr ) | (wrtmask & ref));
585	       }
586	    }
587	 }
588	 break;
589      case GL_INCR:
590	 if (invmask==0) {
591	    for (i=0;i<n;i++) {
592	       if (mask[i]) {
593                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
594		  if (*sptr < stencilMax) {
595		     *sptr = (GLstencil) (*sptr + 1);
596		  }
597	       }
598	    }
599	 }
600	 else {
601	    for (i=0;i<n;i++) {
602	       if (mask[i]) {
603                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
604		  if (*sptr < stencilMax) {
605		     *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
606		  }
607	       }
608	    }
609	 }
610	 break;
611      case GL_DECR:
612	 if (invmask==0) {
613	    for (i=0;i<n;i++) {
614	       if (mask[i]) {
615                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
616		  if (*sptr>0) {
617		     *sptr = (GLstencil) (*sptr - 1);
618		  }
619	       }
620	    }
621	 }
622	 else {
623	    for (i=0;i<n;i++) {
624	       if (mask[i]) {
625                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
626		  if (*sptr>0) {
627		     *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
628		  }
629	       }
630	    }
631	 }
632	 break;
633      case GL_INCR_WRAP_EXT:
634	 if (invmask==0) {
635	    for (i=0;i<n;i++) {
636	       if (mask[i]) {
637                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
638                  *sptr = (GLstencil) (*sptr + 1);
639	       }
640	    }
641	 }
642	 else {
643	    for (i=0;i<n;i++) {
644	       if (mask[i]) {
645                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
646                  *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
647	       }
648	    }
649	 }
650	 break;
651      case GL_DECR_WRAP_EXT:
652	 if (invmask==0) {
653	    for (i=0;i<n;i++) {
654	       if (mask[i]) {
655                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
656                  *sptr = (GLstencil) (*sptr - 1);
657	       }
658	    }
659	 }
660	 else {
661	    for (i=0;i<n;i++) {
662	       if (mask[i]) {
663                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
664                  *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
665	       }
666	    }
667	 }
668	 break;
669      case GL_INVERT:
670	 if (invmask==0) {
671	    for (i=0;i<n;i++) {
672	       if (mask[i]) {
673                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
674                  *sptr = (GLstencil) (~*sptr);
675	       }
676	    }
677	 }
678	 else {
679	    for (i=0;i<n;i++) {
680	       if (mask[i]) {
681                  GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
682                  *sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & ~*sptr));
683	       }
684	    }
685	 }
686	 break;
687      default:
688         _mesa_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
689   }
690}
691
692
693
694/**
695 * Apply stencil test to an array of pixels before depth buffering.
696 *
697 * \note Used for software stencil buffer only.
698 * Input:  n - number of pixels in the span
699 *         x, y - array of [n] pixels to stencil
700 *         mask - array [n] of flag:  0=skip the pixel, 1=stencil the pixel
701 * Output:  mask - pixels which fail the stencil test will have their
702 *                 mask flag set to 0.
703 * \return  GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
704 */
705static GLboolean
706stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n,
707                     const GLint x[], const GLint y[], GLubyte mask[] )
708{
709   const struct gl_framebuffer *fb = ctx->DrawBuffer;
710   struct gl_renderbuffer *rb = fb->_StencilBuffer;
711   GLubyte fail[MAX_WIDTH];
712   GLstencil r, s;
713   GLuint i;
714   GLboolean allfail = GL_FALSE;
715   const GLuint valueMask = ctx->Stencil.ValueMask[face];
716   const GLstencil *stencilStart = (GLstencil *) rb->Data;
717   const GLuint stride = rb->Width;
718
719   ASSERT(rb->GetPointer(ctx, rb, 0, 0));
720   ASSERT(sizeof(GLstencil) == 1);
721
722   /*
723    * Perform stencil test.  The results of this operation are stored
724    * in the fail[] array:
725    *   IF fail[i] is non-zero THEN
726    *       the stencil fail operator is to be applied
727    *   ELSE
728    *       the stencil fail operator is not to be applied
729    *   ENDIF
730    */
731
732   switch (ctx->Stencil.Function[face]) {
733      case GL_NEVER:
734         /* always fail */
735         for (i=0;i<n;i++) {
736	    if (mask[i]) {
737	       mask[i] = 0;
738	       fail[i] = 1;
739	    }
740	    else {
741	       fail[i] = 0;
742	    }
743	 }
744	 allfail = GL_TRUE;
745	 break;
746      case GL_LESS:
747	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
748	 for (i=0;i<n;i++) {
749	    if (mask[i]) {
750               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
751	       s = (GLstencil) (*sptr & valueMask);
752	       if (r < s) {
753		  /* passed */
754		  fail[i] = 0;
755	       }
756	       else {
757		  fail[i] = 1;
758		  mask[i] = 0;
759	       }
760	    }
761	    else {
762	       fail[i] = 0;
763	    }
764	 }
765	 break;
766      case GL_LEQUAL:
767	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
768	 for (i=0;i<n;i++) {
769	    if (mask[i]) {
770               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
771	       s = (GLstencil) (*sptr & valueMask);
772	       if (r <= s) {
773		  /* pass */
774		  fail[i] = 0;
775	       }
776	       else {
777		  fail[i] = 1;
778		  mask[i] = 0;
779	       }
780	    }
781	    else {
782	       fail[i] = 0;
783	    }
784	 }
785	 break;
786      case GL_GREATER:
787	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
788	 for (i=0;i<n;i++) {
789	    if (mask[i]) {
790               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
791	       s = (GLstencil) (*sptr & valueMask);
792	       if (r > s) {
793		  /* passed */
794		  fail[i] = 0;
795	       }
796	       else {
797		  fail[i] = 1;
798		  mask[i] = 0;
799	       }
800	    }
801	    else {
802	       fail[i] = 0;
803	    }
804	 }
805	 break;
806      case GL_GEQUAL:
807	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
808	 for (i=0;i<n;i++) {
809	    if (mask[i]) {
810               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
811	       s = (GLstencil) (*sptr & valueMask);
812	       if (r >= s) {
813		  /* passed */
814		  fail[i] = 0;
815	       }
816	       else {
817		  fail[i] = 1;
818		  mask[i] = 0;
819	       }
820	    }
821	    else {
822	       fail[i] = 0;
823	    }
824	 }
825	 break;
826      case GL_EQUAL:
827	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
828	 for (i=0;i<n;i++) {
829	    if (mask[i]) {
830               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
831	       s = (GLstencil) (*sptr & valueMask);
832	       if (r == s) {
833		  /* passed */
834		  fail[i] = 0;
835	       }
836	       else {
837		  fail[i] = 1;
838		  mask[i] = 0;
839	       }
840	    }
841	    else {
842	       fail[i] = 0;
843	    }
844	 }
845	 break;
846      case GL_NOTEQUAL:
847	 r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
848	 for (i=0;i<n;i++) {
849	    if (mask[i]) {
850               const GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
851	       s = (GLstencil) (*sptr & valueMask);
852	       if (r != s) {
853		  /* passed */
854		  fail[i] = 0;
855	       }
856	       else {
857		  fail[i] = 1;
858		  mask[i] = 0;
859	       }
860	    }
861	    else {
862	       fail[i] = 0;
863	    }
864	 }
865	 break;
866      case GL_ALWAYS:
867	 /* always pass */
868	 for (i=0;i<n;i++) {
869	    fail[i] = 0;
870	 }
871	 break;
872      default:
873         _mesa_problem(ctx, "Bad stencil func in gl_stencil_pixels");
874         return 0;
875   }
876
877   if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
878      apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc[face],
879                                  face, fail );
880   }
881
882   return !allfail;
883}
884
885
886
887
888/**
889 * Apply stencil and depth testing to an array of pixels.
890 * This is used both for software and hardware stencil buffers.
891 *
892 * The comments in this function are a bit sparse but the code is
893 * almost identical to stencil_and_ztest_span(), which is well
894 * commented.
895 *
896 * Input:  n - number of pixels in the array
897 *         x, y - array of [n] pixel positions
898 *         z - array [n] of z values
899 *         mask - array [n] of flags  (1=test this pixel, 0=skip the pixel)
900 * Output: mask - array [n] of flags (1=stencil and depth test passed)
901 * Return: GL_FALSE - all fragments failed the testing
902 *         GL_TRUE - one or more fragments passed the testing
903 */
904static GLboolean
905stencil_and_ztest_pixels( GLcontext *ctx, SWspan *span, GLuint face )
906{
907   GLubyte passMask[MAX_WIDTH], failMask[MAX_WIDTH], origMask[MAX_WIDTH];
908   struct gl_framebuffer *fb = ctx->DrawBuffer;
909   struct gl_renderbuffer *rb = fb->_StencilBuffer;
910   const GLuint n = span->end;
911   const GLint *x = span->array->x;
912   const GLint *y = span->array->y;
913   GLubyte *mask = span->array->mask;
914
915   ASSERT(span->arrayMask & SPAN_XY);
916   ASSERT(ctx->Stencil.Enabled);
917   ASSERT(n <= MAX_WIDTH);
918
919   if (!rb->GetPointer(ctx, rb, 0, 0)) {
920      /* No direct access */
921      GLstencil stencil[MAX_WIDTH];
922
923      ASSERT(rb->DataType == GL_UNSIGNED_BYTE);
924      _swrast_get_values(ctx, rb, n, x, y, stencil, sizeof(GLubyte));
925
926      _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
927
928      (void) do_stencil_test(ctx, face, n, stencil, mask);
929
930      if (ctx->Depth.Test == GL_FALSE) {
931         apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
932                          n, stencil, mask);
933      }
934      else {
935         GLubyte tmpMask[MAX_WIDTH];
936         _mesa_memcpy(tmpMask, mask, n * sizeof(GLubyte));
937
938         _swrast_depth_test_span(ctx, span);
939
940         compute_pass_fail_masks(n, tmpMask, mask, passMask, failMask);
941
942         if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
943            apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face,
944                             n, stencil, failMask);
945         }
946         if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
947            apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
948                             n, stencil, passMask);
949         }
950      }
951
952      /* Write updated stencil values into hardware stencil buffer */
953      rb->PutValues(ctx, rb, n, x, y, stencil, origMask);
954
955      return GL_TRUE;
956   }
957   else {
958      /* Direct access to stencil buffer */
959
960      if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) {
961         /* all fragments failed the stencil test, we're done. */
962         return GL_FALSE;
963      }
964
965      if (ctx->Depth.Test==GL_FALSE) {
966         apply_stencil_op_to_pixels(ctx, n, x, y,
967                                    ctx->Stencil.ZPassFunc[face], face, mask);
968      }
969      else {
970         _mesa_memcpy(origMask, mask, n * sizeof(GLubyte));
971
972         _swrast_depth_test_span(ctx, span);
973
974         compute_pass_fail_masks(n, origMask, mask, passMask, failMask);
975
976         if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
977            apply_stencil_op_to_pixels(ctx, n, x, y,
978                                       ctx->Stencil.ZFailFunc[face],
979                                       face, failMask);
980         }
981         if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
982            apply_stencil_op_to_pixels(ctx, n, x, y,
983                                       ctx->Stencil.ZPassFunc[face],
984                                       face, passMask);
985         }
986      }
987
988      return GL_TRUE;  /* one or more fragments passed both tests */
989   }
990}
991
992
993/**
994 * /return GL_TRUE = one or more fragments passed,
995 * GL_FALSE = all fragments failed.
996 */
997GLboolean
998_swrast_stencil_and_ztest_span(GLcontext *ctx, SWspan *span)
999{
1000   const GLuint face = (span->facing == 0) ? 0 : ctx->Stencil._BackFace;
1001
1002   if (span->arrayMask & SPAN_XY)
1003      return stencil_and_ztest_pixels(ctx, span, face);
1004   else
1005      return stencil_and_ztest_span(ctx, span, face);
1006}
1007
1008
1009#if 0
1010GLuint
1011clip_span(GLuint bufferWidth, GLuint bufferHeight,
1012          GLint x, GLint y, GLuint *count)
1013{
1014   GLuint n = *count;
1015   GLuint skipPixels = 0;
1016
1017   if (y < 0 || y >= bufferHeight || x + n <= 0 || x >= bufferWidth) {
1018      /* totally out of bounds */
1019      n = 0;
1020   }
1021   else {
1022      /* left clip */
1023      if (x < 0) {
1024         skipPixels = -x;
1025         x = 0;
1026         n -= skipPixels;
1027      }
1028      /* right clip */
1029      if (x + n > bufferWidth) {
1030         GLint dx = x + n - bufferWidth;
1031         n -= dx;
1032      }
1033   }
1034
1035   *count = n;
1036
1037   return skipPixels;
1038}
1039#endif
1040
1041
1042/**
1043 * Return a span of stencil values from the stencil buffer.
1044 * Used for glRead/CopyPixels
1045 * Input:  n - how many pixels
1046 *         x,y - location of first pixel
1047 * Output:  stencil - the array of stencil values
1048 */
1049void
1050_swrast_read_stencil_span(GLcontext *ctx, struct gl_renderbuffer *rb,
1051                          GLint n, GLint x, GLint y, GLstencil stencil[])
1052{
1053   if (y < 0 || y >= (GLint) rb->Height ||
1054       x + n <= 0 || x >= (GLint) rb->Width) {
1055      /* span is completely outside framebuffer */
1056      return; /* undefined values OK */
1057   }
1058
1059   if (x < 0) {
1060      GLint dx = -x;
1061      x = 0;
1062      n -= dx;
1063      stencil += dx;
1064   }
1065   if (x + n > (GLint) rb->Width) {
1066      GLint dx = x + n - rb->Width;
1067      n -= dx;
1068   }
1069   if (n <= 0) {
1070      return;
1071   }
1072
1073   rb->GetRow(ctx, rb, n, x, y, stencil);
1074}
1075
1076
1077
1078/**
1079 * Write a span of stencil values to the stencil buffer.  This function
1080 * applies the stencil write mask when needed.
1081 * Used for glDraw/CopyPixels
1082 * Input:  n - how many pixels
1083 *         x, y - location of first pixel
1084 *         stencil - the array of stencil values
1085 */
1086void
1087_swrast_write_stencil_span(GLcontext *ctx, GLint n, GLint x, GLint y,
1088                           const GLstencil stencil[] )
1089{
1090   struct gl_framebuffer *fb = ctx->DrawBuffer;
1091   struct gl_renderbuffer *rb = fb->_StencilBuffer;
1092   const GLuint stencilMax = (1 << fb->Visual.stencilBits) - 1;
1093   const GLuint stencilMask = ctx->Stencil.WriteMask[0];
1094
1095   if (y < 0 || y >= (GLint) rb->Height ||
1096       x + n <= 0 || x >= (GLint) rb->Width) {
1097      /* span is completely outside framebuffer */
1098      return; /* undefined values OK */
1099   }
1100   if (x < 0) {
1101      GLint dx = -x;
1102      x = 0;
1103      n -= dx;
1104      stencil += dx;
1105   }
1106   if (x + n > (GLint) rb->Width) {
1107      GLint dx = x + n - rb->Width;
1108      n -= dx;
1109   }
1110   if (n <= 0) {
1111      return;
1112   }
1113
1114   if ((stencilMask & stencilMax) != stencilMax) {
1115      /* need to apply writemask */
1116      GLstencil destVals[MAX_WIDTH], newVals[MAX_WIDTH];
1117      GLint i;
1118      rb->GetRow(ctx, rb, n, x, y, destVals);
1119      for (i = 0; i < n; i++) {
1120         newVals[i]
1121            = (stencil[i] & stencilMask) | (destVals[i] & ~stencilMask);
1122      }
1123      rb->PutRow(ctx, rb, n, x, y, newVals, NULL);
1124   }
1125   else {
1126      rb->PutRow(ctx, rb, n, x, y, stencil, NULL);
1127   }
1128}
1129
1130
1131
1132/**
1133 * Clear the stencil buffer.
1134 */
1135void
1136_swrast_clear_stencil_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
1137{
1138   const GLubyte stencilBits = ctx->DrawBuffer->Visual.stencilBits;
1139   const GLuint mask = ctx->Stencil.WriteMask[0];
1140   const GLuint invMask = ~mask;
1141   const GLuint clearVal = (ctx->Stencil.Clear & mask);
1142   const GLuint stencilMax = (1 << stencilBits) - 1;
1143   GLint x, y, width, height;
1144
1145   if (!rb || mask == 0)
1146      return;
1147
1148   ASSERT(rb->DataType == GL_UNSIGNED_BYTE ||
1149          rb->DataType == GL_UNSIGNED_SHORT);
1150
1151   ASSERT(rb->_BaseFormat == GL_STENCIL_INDEX);
1152
1153   /* compute region to clear */
1154   x = ctx->DrawBuffer->_Xmin;
1155   y = ctx->DrawBuffer->_Ymin;
1156   width  = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
1157   height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
1158
1159   if (rb->GetPointer(ctx, rb, 0, 0)) {
1160      /* Direct buffer access */
1161      if ((mask & stencilMax) != stencilMax) {
1162         /* need to mask the clear */
1163         if (rb->DataType == GL_UNSIGNED_BYTE) {
1164            GLint i, j;
1165            for (i = 0; i < height; i++) {
1166               GLubyte *stencil = (GLubyte*) rb->GetPointer(ctx, rb, x, y + i);
1167               for (j = 0; j < width; j++) {
1168                  stencil[j] = (stencil[j] & invMask) | clearVal;
1169               }
1170            }
1171         }
1172         else {
1173            GLint i, j;
1174            for (i = 0; i < height; i++) {
1175               GLushort *stencil = (GLushort*) rb->GetPointer(ctx, rb, x, y + i);
1176               for (j = 0; j < width; j++) {
1177                  stencil[j] = (stencil[j] & invMask) | clearVal;
1178               }
1179            }
1180         }
1181      }
1182      else {
1183         /* no bit masking */
1184         if (width == (GLint) rb->Width && rb->DataType == GL_UNSIGNED_BYTE) {
1185            /* optimized case */
1186            /* Note: bottom-to-top raster assumed! */
1187            GLubyte *stencil = (GLubyte *) rb->GetPointer(ctx, rb, x, y);
1188            GLuint len = width * height * sizeof(GLubyte);
1189            _mesa_memset(stencil, clearVal, len);
1190         }
1191         else {
1192            /* general case */
1193            GLint i;
1194            for (i = 0; i < height; i++) {
1195               GLvoid *stencil = rb->GetPointer(ctx, rb, x, y + i);
1196               if (rb->DataType == GL_UNSIGNED_BYTE) {
1197                  _mesa_memset(stencil, clearVal, width);
1198               }
1199               else {
1200                  _mesa_memset16((short unsigned int*) stencil, clearVal, width);
1201               }
1202            }
1203         }
1204      }
1205   }
1206   else {
1207      /* no direct access */
1208      if ((mask & stencilMax) != stencilMax) {
1209         /* need to mask the clear */
1210         if (rb->DataType == GL_UNSIGNED_BYTE) {
1211            GLint i, j;
1212            for (i = 0; i < height; i++) {
1213               GLubyte stencil[MAX_WIDTH];
1214               rb->GetRow(ctx, rb, width, x, y + i, stencil);
1215               for (j = 0; j < width; j++) {
1216                  stencil[j] = (stencil[j] & invMask) | clearVal;
1217               }
1218               rb->PutRow(ctx, rb, width, x, y + i, stencil, NULL);
1219            }
1220         }
1221         else {
1222            GLint i, j;
1223            for (i = 0; i < height; i++) {
1224               GLushort stencil[MAX_WIDTH];
1225               rb->GetRow(ctx, rb, width, x, y + i, stencil);
1226               for (j = 0; j < width; j++) {
1227                  stencil[j] = (stencil[j] & invMask) | clearVal;
1228               }
1229               rb->PutRow(ctx, rb, width, x, y + i, stencil, NULL);
1230            }
1231         }
1232      }
1233      else {
1234         /* no bit masking */
1235         const GLubyte clear8 = (GLubyte) clearVal;
1236         const GLushort clear16 = (GLushort) clearVal;
1237         const void *clear;
1238         GLint i;
1239         if (rb->DataType == GL_UNSIGNED_BYTE) {
1240            clear = &clear8;
1241         }
1242         else {
1243            clear = &clear16;
1244         }
1245         for (i = 0; i < height; i++) {
1246            rb->PutMonoRow(ctx, rb, width, x, y + i, clear, NULL);
1247         }
1248      }
1249   }
1250}
1251