Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

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