Bug #1028: Add hardware-accelerated stencil support to r128. Testing with
authorEric Anholt <anholt@FreeBSD.org>
Thu, 27 Oct 2005 20:26:24 +0000 (20:26 +0000)
committerEric Anholt <anholt@FreeBSD.org>
Thu, 27 Oct 2005 20:26:24 +0000 (20:26 +0000)
stencilwrap reported many issues with various modes.  Some of these were
complicated by the fact that spans are broken (Bug #1615), but some appear to be
real bugs.  However, while spans remain broken, I found that visual results were
better by avoiding fallbacks rather than avoiding just a broken stencil
implementation.  Note that this required changing the depth spans at 24+8bpp
into read-modify-write cycles.  It would be nicer as a single write with
a mask, but the kernel span blits turn off masking.

Reviewed by: ajax

src/mesa/drivers/dri/r128/r128_dd.c
src/mesa/drivers/dri/r128/r128_ioctl.c
src/mesa/drivers/dri/r128/r128_screen.c
src/mesa/drivers/dri/r128/r128_span.c
src/mesa/drivers/dri/r128/r128_state.c
src/mesa/drivers/dri/r128/server/r128_reg.h

index a60d2a689327b7b7ea52ddfc023437bb1c7dcee4..4f0bb4761cd6bf8a1cd4b706c4cca6809404a30b 100644 (file)
@@ -44,7 +44,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "utils.h"
 
-#define DRIVER_DATE    "20051026"
+#define DRIVER_DATE    "20051027"
 
 
 /* Return the width and height of the current color buffer.
index 8f148548872b5a8ca63358473c51ac17d7ebd1bb..3b34d9fbb2d107896a337734584914da17bd2dac 100644 (file)
@@ -408,6 +408,7 @@ static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
    GLuint flags = 0;
    GLint i;
    GLint ret;
+   GLuint depthmask = 0;
 
    if ( R128_DEBUG & DEBUG_VERBOSE_API ) {
       fprintf( stderr, "%s:\n", __FUNCTION__ );
@@ -438,15 +439,17 @@ static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
 
    if ( ( mask & BUFFER_BIT_DEPTH ) && ctx->Depth.Mask ) {
       flags |= R128_DEPTH;
+      /* if we're at 16 bits, extra plane mask won't hurt */
+      depthmask |= 0x00ffffff;
       mask &= ~BUFFER_BIT_DEPTH;
    }
-#if 0
-   /* FIXME: Add stencil support */
-   if ( mask & BUFFER_BIT_STENCIL ) {
-      flags |= DRM_R128_DEPTH_BUFFER;
+
+   if ( mask & BUFFER_BIT_STENCIL &&
+       (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) ) {
+      flags |= R128_DEPTH;
+      depthmask |= ctx->Stencil.WriteMask[0] << 24;
       mask &= ~BUFFER_BIT_STENCIL;
    }
-#endif
 
    if ( flags ) {
 
@@ -511,7 +514,7 @@ static void r128Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
          clear.clear_color = rmesa->ClearColor;
          clear.clear_depth = rmesa->ClearDepth;
          clear.color_mask = rmesa->setup.plane_3d_mask_c;
-         clear.depth_mask = ~0;
+         clear.depth_mask = depthmask;
 
          ret = drmCommandWrite( rmesa->driFd, DRM_R128_CLEAR,
                                 &clear, sizeof(clear) );
index 5d1b6e42d6f333b5b55c204d58dedf1c7fa2ebfe..c91f9fdbf7a8ad39dd7c1e1ba651e387a2fb3aa5 100644 (file)
@@ -271,6 +271,11 @@ r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
       return GL_FALSE; /* not implemented */
    }
    else {
+      const GLboolean swDepth = GL_FALSE;
+      const GLboolean swAlpha = GL_FALSE;
+      const GLboolean swAccum = mesaVis->accumRedBits > 0;
+      const GLboolean swStencil = mesaVis->stencilBits > 0 &&
+         mesaVis->depthBits != 24;
       struct gl_framebuffer *fb = _mesa_create_framebuffer(mesaVis);
 
       {
@@ -316,12 +321,23 @@ r128CreateBuffer( __DRIscreenPrivate *driScrnPriv,
          _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &depthRb->Base);
       }
 
+      if (mesaVis->stencilBits > 0 && !swStencil) {
+         driRenderbuffer *stencilRb
+            = driNewRenderbuffer(GL_STENCIL_INDEX8_EXT,
+                                 NULL,
+                                 screen->cpp,
+                                 screen->depthOffset, screen->depthPitch,
+                                 driDrawPriv);
+         r128SetSpanFunctions(stencilRb, mesaVis);
+         _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &stencilRb->Base);
+      }
+
       _mesa_add_soft_renderbuffers(fb,
                                    GL_FALSE, /* color */
-                                   GL_FALSE, /* depth */
-                                   mesaVis->stencilBits > 0,
-                                   mesaVis->accumRedBits > 0,
-                                   GL_FALSE, /* alpha */
+                                   swDepth,
+                                   swStencil,
+                                   swAccum,
+                                   swAlpha,
                                    GL_FALSE /* aux */);
       driDrawPriv->driverPrivate = (void *) fb;
 
index 76f80efb7784653903f90773d27ced960f8bf406..a24e63c9b675dcb82799a637cdb834ec6287f40e 100644 (file)
@@ -46,6 +46,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define HAVE_HW_DEPTH_SPANS    1
 #define HAVE_HW_DEPTH_PIXELS   1
+#define HAVE_HW_STENCIL_SPANS  1
+#define HAVE_HW_STENCIL_PIXELS 1
 
 #define LOCAL_VARS                                                     \
    r128ContextPtr rmesa = R128_CONTEXT(ctx);                           \
@@ -101,6 +103,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
      + ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
 #include "spantmp2.h"
 
+/* Idling in the depth/stencil span functions:
+ * For writes, the kernel reads from the given user-space buffer at dispatch
+ * time, and then writes to the depth buffer asynchronously.
+ * For reads, the kernel reads from the depth buffer and writes to the span
+ * temporary asynchronously.
+ * So, if we're going to read from the span temporary, we need to idle before
+ * doing so.  But we don't need to idle after write, because the CPU won't
+ * be accessing the destination, only the accelerator (through 3d rendering or
+ * depth span reads)
+ * However, due to interactions from pixel cache between 2d (what we do with
+ * depth) and 3d (all other parts of the system), we idle at the begin and end
+ * of a set of span operations, which should cover the pix cache issue.
+ * Except, we still have major issues, as shown by no_rast=true glxgears, or
+ * stencilwrap.
+ */
 
 /* ================================================================
  * Depth buffer
@@ -110,10 +127,12 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
  */
 
 #define WRITE_DEPTH_SPAN()                                             \
+do {                                                                   \
    r128WriteDepthSpanLocked( rmesa, n,                                 \
                             x + dPriv->x,                              \
                             y + dPriv->y,                              \
-                            depth, mask );
+                            depth, mask );                             \
+} while (0)
 
 #define WRITE_DEPTH_PIXELS()                                           \
 do {                                                                   \
@@ -183,20 +202,41 @@ do {                                                                      \
 /* 24-bit depth, 8-bit stencil buffer functions
  */
 #define WRITE_DEPTH_SPAN()                                             \
+do {                                                                   \
+   GLint buf[n];                                                       \
+   GLint i;                                                            \
+   GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB +                        \
+                               r128scrn->spanOffset);                  \
+   r128ReadDepthSpanLocked( rmesa, n,                                  \
+                           x + dPriv->x,                               \
+                           y + dPriv->y );                             \
+   r128WaitForIdleLocked( rmesa );                                     \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      buf[i] = (readbuf[i] & 0xff000000) | (depth[i] & 0x00ffffff);    \
+   }                                                                   \
    r128WriteDepthSpanLocked( rmesa, n,                                 \
                             x + dPriv->x,                              \
                             y + dPriv->y,                              \
-                            depth, mask );
+                            buf, mask );                               \
+} while (0)
 
 #define WRITE_DEPTH_PIXELS()                                           \
 do {                                                                   \
+   GLint buf[n];                                                       \
    GLint ox[MAX_WIDTH];                                                        \
    GLint oy[MAX_WIDTH];                                                        \
+   GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB +                        \
+                               r128scrn->spanOffset);                  \
    for ( i = 0 ; i < n ; i++ ) {                                       \
       ox[i] = x[i] + dPriv->x;                                         \
       oy[i] = Y_FLIP( y[i] ) + dPriv->y;                               \
    }                                                                   \
-   r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask );                \
+   r128ReadDepthPixelsLocked( rmesa, n, ox, oy );                      \
+   r128WaitForIdleLocked( rmesa );                                     \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      buf[i] = (readbuf[i] & 0xff000000) | (depth[i] & 0x00ffffff);    \
+   }                                                                   \
+   r128WriteDepthPixelsLocked( rmesa, n, ox, oy, buf, mask );          \
 } while (0)
 
 #define READ_DEPTH_SPAN()                                              \
@@ -205,6 +245,7 @@ do {                                                                        \
                            r128scrn->spanOffset);                      \
    GLint i;                                                            \
                                                                        \
+   /*if (n >= 128) fprintf(stderr, "Large number of pixels: %d\n", n);*/       \
    r128ReadDepthSpanLocked( rmesa, n,                                  \
                            x + dPriv->x,                               \
                            y + dPriv->y );                             \
@@ -258,8 +299,99 @@ do {                                                                       \
  * Stencil buffer
  */
 
-/* FIXME: Add support for hardware stencil buffers.
+/* 24 bit depth, 8 bit stencil depthbuffer functions
  */
+#define WRITE_STENCIL_SPAN()                                           \
+do {                                                                   \
+   GLint buf[n];                                                       \
+   GLint i;                                                            \
+   GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB +                        \
+                               r128scrn->spanOffset);                  \
+   r128ReadDepthSpanLocked( rmesa, n,                                  \
+                           x + dPriv->x,                               \
+                           y + dPriv->y );                             \
+   r128WaitForIdleLocked( rmesa );                                     \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      buf[i] = (readbuf[i] & 0x00ffffff) | (stencil[i] << 24);         \
+   }                                                                   \
+   r128WriteDepthSpanLocked( rmesa, n,                                 \
+                            x + dPriv->x,                              \
+                            y + dPriv->y,                              \
+                            buf, mask );                               \
+} while (0)
+
+#define WRITE_STENCIL_PIXELS()                                         \
+do {                                                                   \
+   GLint buf[n];                                                       \
+   GLint ox[MAX_WIDTH];                                                        \
+   GLint oy[MAX_WIDTH];                                                        \
+   GLuint *readbuf = (GLuint *)((GLubyte *)sPriv->pFB +                        \
+                               r128scrn->spanOffset);                  \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      ox[i] = x[i] + dPriv->x;                                         \
+      oy[i] = Y_FLIP( y[i] ) + dPriv->y;                               \
+   }                                                                   \
+   r128ReadDepthPixelsLocked( rmesa, n, ox, oy );                      \
+   r128WaitForIdleLocked( rmesa );                                     \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      buf[i] = (readbuf[i] & 0x00ffffff) | (stencil[i] << 24);         \
+   }                                                                   \
+   r128WriteDepthPixelsLocked( rmesa, n, ox, oy, buf, mask );          \
+} while (0)
+
+#define READ_STENCIL_SPAN()                                            \
+do {                                                                   \
+   GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB +                    \
+                           r128scrn->spanOffset);                      \
+   GLint i;                                                            \
+                                                                       \
+   /*if (n >= 128) fprintf(stderr, "Large number of pixels: %d\n", n);*/       \
+   r128ReadDepthSpanLocked( rmesa, n,                                  \
+                           x + dPriv->x,                               \
+                           y + dPriv->y );                             \
+   r128WaitForIdleLocked( rmesa );                                     \
+                                                                       \
+   for ( i = 0 ; i < n ; i++ ) {                                       \
+      stencil[i] = (buf[i] & 0xff000000) >> 24;                                \
+   }                                                                   \
+} while (0)
+
+#define READ_STENCIL_PIXELS()                                          \
+do {                                                                   \
+   GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB +                    \
+                           r128scrn->spanOffset);                      \
+   GLint i, remaining = n;                                             \
+                                                                       \
+   while ( remaining > 0 ) {                                           \
+      GLint ox[128];                                                   \
+      GLint oy[128];                                                   \
+      GLint count;                                                     \
+                                                                       \
+      if ( remaining <= 128 ) {                                                \
+        count = remaining;                                             \
+      } else {                                                         \
+        count = 128;                                                   \
+      }                                                                        \
+      for ( i = 0 ; i < count ; i++ ) {                                        \
+        ox[i] = x[i] + dPriv->x;                                       \
+        oy[i] = Y_FLIP( y[i] ) + dPriv->y;                             \
+      }                                                                        \
+                                                                       \
+      r128ReadDepthPixelsLocked( rmesa, count, ox, oy );               \
+      r128WaitForIdleLocked( rmesa );                                  \
+                                                                       \
+      for ( i = 0 ; i < count ; i++ ) {                                        \
+        stencil[i] = (buf[i] & 0xff000000) >> 24;                      \
+      }                                                                        \
+      stencil += count;                                                        \
+      x += count;                                                      \
+      y += count;                                                      \
+      remaining -= count;                                              \
+   }                                                                   \
+} while (0)
+
+#define TAG(x) radeon##x##_z24_s8
+#include "stenciltmp.h"
 
 static void
 r128SpanRenderStart( GLcontext *ctx )
@@ -275,6 +407,7 @@ r128SpanRenderFinish( GLcontext *ctx )
 {
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    _swrast_flush( ctx );
+   r128WaitForIdleLocked( rmesa );
    UNLOCK_HARDWARE( rmesa );
 }
 
@@ -306,4 +439,7 @@ r128SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
    else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
       r128InitDepthPointers_z24_s8(&drb->Base);
    }
+   else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
+      radeonInitStencilPointers_z24_s8(&drb->Base);
+   }
 }
index f6c6504566b58923995def4d2fe921a6cf500493..80771ae29bab446bfe20ade926d1b3dca94f1600 100644 (file)
@@ -251,6 +251,179 @@ static void r128DDBlendFuncSeparate( GLcontext *ctx,
    rmesa->new_state |= R128_NEW_ALPHA;
 }
 
+/* =============================================================
+ * Stencil
+ */
+
+static void
+r128DDStencilFuncSeparate( GLcontext *ctx, GLenum face, GLenum func,
+                           GLint ref, GLuint mask )
+{
+   r128ContextPtr rmesa = R128_CONTEXT(ctx);
+   GLuint refmask = ((ctx->Stencil.Ref[0] << 0) |
+                    (ctx->Stencil.ValueMask[0] << 16) |
+                    (ctx->Stencil.WriteMask[0] << 24)); 
+   GLuint z = rmesa->setup.z_sten_cntl_c;
+
+   z &= ~R128_STENCIL_TEST_MASK;
+   switch ( ctx->Stencil.Function[0] ) {
+   case GL_NEVER:
+      z |= R128_STENCIL_TEST_NEVER;
+      break;
+   case GL_LESS:
+      z |= R128_STENCIL_TEST_LESS;
+      break;
+   case GL_EQUAL:
+      z |= R128_STENCIL_TEST_EQUAL;
+      break;
+   case GL_LEQUAL:
+      z |= R128_STENCIL_TEST_LESSEQUAL;
+      break;
+   case GL_GREATER:
+      z |= R128_STENCIL_TEST_GREATER;
+      break;
+   case GL_NOTEQUAL:
+      z |= R128_STENCIL_TEST_NEQUAL;
+      break;
+   case GL_GEQUAL:
+      z |= R128_STENCIL_TEST_GREATEREQUAL;
+      break;
+   case GL_ALWAYS:
+      z |= R128_STENCIL_TEST_ALWAYS;
+      break;
+   }
+
+   if ( rmesa->setup.sten_ref_mask_c != refmask ) {
+      rmesa->setup.sten_ref_mask_c = refmask;
+      rmesa->dirty |= R128_UPLOAD_MASKS;
+   }
+   if ( rmesa->setup.z_sten_cntl_c != z ) {
+      rmesa->setup.z_sten_cntl_c = z;
+      rmesa->dirty |= R128_UPLOAD_CONTEXT;
+   }
+}
+
+static void
+r128DDStencilMaskSeparate( GLcontext *ctx, GLenum face, GLuint mask )
+{
+   r128ContextPtr rmesa = R128_CONTEXT(ctx);
+   GLuint refmask = ((ctx->Stencil.Ref[0] << 0) |
+                    (ctx->Stencil.ValueMask[0] << 16) |
+                    (ctx->Stencil.WriteMask[0] << 24)); 
+
+   if ( rmesa->setup.sten_ref_mask_c != refmask ) {
+      rmesa->setup.sten_ref_mask_c = refmask;
+      rmesa->dirty |= R128_UPLOAD_MASKS;
+   }
+}
+
+static void r128DDStencilOpSeparate( GLcontext *ctx, GLenum face, GLenum fail,
+                                     GLenum zfail, GLenum zpass )
+{
+   r128ContextPtr rmesa = R128_CONTEXT(ctx);
+   GLuint z = rmesa->setup.z_sten_cntl_c;
+   GLboolean ok = 1;
+
+   if (!( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ))
+      return;
+
+   z &= ~(R128_STENCIL_S_FAIL_MASK | R128_STENCIL_ZPASS_MASK |
+         R128_STENCIL_ZFAIL_MASK);
+
+   switch ( ctx->Stencil.FailFunc[0] ) {
+   case GL_KEEP:
+      z |= R128_STENCIL_S_FAIL_KEEP;
+      break;
+   case GL_ZERO:
+      z |= R128_STENCIL_S_FAIL_ZERO;
+      ok = 0; /* Hardware bug?  ZERO maps to KEEP */
+      break;
+   case GL_REPLACE:
+      z |= R128_STENCIL_S_FAIL_REPLACE;
+      ok = 0; /* Hardware bug?  REPLACE maps to KEEP */
+      break;
+   case GL_INCR:
+      z |= R128_STENCIL_S_FAIL_INC;
+      break;
+   case GL_DECR:
+      z |= R128_STENCIL_S_FAIL_DEC;
+      break;
+   case GL_INVERT:
+      z |= R128_STENCIL_S_FAIL_INV;
+      ok = 0; /* Hardware bug?  INV maps to ZERO */
+      break;
+   }
+
+   switch ( ctx->Stencil.ZFailFunc[0] ) {
+   case GL_KEEP:
+      z |= R128_STENCIL_ZFAIL_KEEP;
+      ok = 0; /* Hardware bug?  KEEP maps to ZERO */
+      break;
+   case GL_ZERO:
+      z |= R128_STENCIL_ZFAIL_ZERO;
+      break;
+   case GL_REPLACE:
+      z |= R128_STENCIL_ZFAIL_REPLACE;
+      break;
+   case GL_INCR:
+      z |= R128_STENCIL_ZFAIL_INC;
+      break;
+   case GL_DECR:
+      z |= R128_STENCIL_ZFAIL_DEC;
+      break;
+   case GL_INVERT:
+      z |= R128_STENCIL_ZFAIL_INV;
+      ok = 0; /* Hardware bug?  INV maps to ZERO */
+      break;
+   }
+
+   switch ( ctx->Stencil.ZPassFunc[0] ) {
+   case GL_KEEP:
+      z |= R128_STENCIL_ZPASS_KEEP;
+      ok = 0; /* Hardware bug?  KEEP maps to ZERO */
+      break;
+   case GL_ZERO:
+      z |= R128_STENCIL_ZPASS_ZERO;
+      break;
+   case GL_REPLACE:
+      z |= R128_STENCIL_ZPASS_REPLACE;
+      break;
+   case GL_INCR:
+      z |= R128_STENCIL_ZPASS_INC;
+      break;
+   case GL_DECR:
+      z |= R128_STENCIL_ZPASS_DEC;
+      ok = 0; /* Hardware bug?  DEC maps to INCR_WRAP */
+      break;
+   case GL_INVERT:
+      z |= R128_STENCIL_ZPASS_INV;
+      ok = 0; /* Hardware bug?  INV maps to ZERO */
+      break;
+   }
+
+   /* XXX: Now that we know whether we can do the given funcs successfully
+    * (according to testing done with a modified stencilwrap test), go
+    * ahead and drop that knowledge on the floor.  While fallbacks remain
+    * broken, they make the situation even worse (in test apps, at least) than
+    * failing in just the stencil part.
+    */
+   /*FALLBACK( rmesa, R128_FALLBACK_STENCIL, !ok );*/
+
+   if ( rmesa->setup.z_sten_cntl_c != z ) {
+      rmesa->setup.z_sten_cntl_c = z;
+      rmesa->dirty |= R128_UPLOAD_CONTEXT;
+   }
+}
+
+static void r128DDClearStencil( GLcontext *ctx, GLint s )
+{
+   r128ContextPtr rmesa = R128_CONTEXT(ctx);
+
+   if (ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24) {
+      rmesa->ClearDepth &= 0x00ffffff;
+      rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
+   }
+}
 
 /* =============================================================
  * Depth testing
@@ -339,6 +512,7 @@ static void r128DDClearDepth( GLcontext *ctx, GLclampd d )
       break;
    case R128_Z_PIX_WIDTH_24:
       rmesa->ClearDepth = d * 0x00ffffff;
+      rmesa->ClearDepth |= ctx->Stencil.Clear << 24;
       break;
    case R128_Z_PIX_WIDTH_32:
       rmesa->ClearDepth = d * 0xffffffff;
@@ -853,7 +1027,21 @@ static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state )
 
    case GL_STENCIL_TEST:
       FLUSH_BATCH( rmesa );
-      FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
+      if ( ctx->Visual.stencilBits > 0 && ctx->Visual.depthBits == 24 ) {
+        if ( state ) {
+           rmesa->setup.tex_cntl_c |=  R128_STENCIL_ENABLE;
+           /* Reset the fallback (if any) for bad stencil funcs */
+           r128DDStencilOpSeparate( ctx, 0, ctx->Stencil.FailFunc[0],
+                                    ctx->Stencil.ZFailFunc[0],
+                                    ctx->Stencil.ZPassFunc[0] );
+        } else {
+           rmesa->setup.tex_cntl_c &= ~R128_STENCIL_ENABLE;
+           FALLBACK( rmesa, R128_FALLBACK_STENCIL, GL_FALSE );
+        }
+        rmesa->dirty |= R128_UPLOAD_CONTEXT;
+      } else {
+        FALLBACK( rmesa, R128_FALLBACK_STENCIL, state );
+      }
       break;
 
    case GL_TEXTURE_1D:
@@ -1184,6 +1372,7 @@ void r128DDInitStateFuncs( GLcontext *ctx )
 
    ctx->Driver.ClearIndex              = NULL;
    ctx->Driver.ClearColor              = r128DDClearColor;
+   ctx->Driver.ClearStencil            = r128DDClearStencil;
    ctx->Driver.DrawBuffer              = r128DDDrawBuffer;
    ctx->Driver.ReadBuffer              = r128DDReadBuffer;
 
@@ -1208,6 +1397,9 @@ void r128DDInitStateFuncs( GLcontext *ctx )
    ctx->Driver.RenderMode              = r128DDRenderMode;
    ctx->Driver.Scissor                 = r128DDScissor;
    ctx->Driver.ShadeModel              = r128DDShadeModel;
+   ctx->Driver.StencilFuncSeparate     = r128DDStencilFuncSeparate;
+   ctx->Driver.StencilMaskSeparate     = r128DDStencilMaskSeparate;
+   ctx->Driver.StencilOpSeparate       = r128DDStencilOpSeparate;
 
    ctx->Driver.DepthRange               = r128DepthRange;
    ctx->Driver.Viewport                 = r128Viewport;
index 00f5041c11dc6d33d31cc9e2f72a7f0f23786c13..cb979cb70d43db0ae6d8bb474f18fb9cadb4e9ec 100644 (file)
 #       define R128_STENCIL_TEST_GREATER      (5 << 12)
 #       define R128_STENCIL_TEST_NEQUAL       (6 << 12)
 #       define R128_STENCIL_TEST_ALWAYS       (7 << 12)
+#       define R128_STENCIL_TEST_MASK         (7 << 12)
 #       define R128_STENCIL_S_FAIL_KEEP       (0 << 16)
 #       define R128_STENCIL_S_FAIL_ZERO       (1 << 16)
 #       define R128_STENCIL_S_FAIL_REPLACE    (2 << 16)
 #       define R128_STENCIL_S_FAIL_INC        (3 << 16)
 #       define R128_STENCIL_S_FAIL_DEC        (4 << 16)
 #       define R128_STENCIL_S_FAIL_INV        (5 << 16)
+#       define R128_STENCIL_S_FAIL_MASK       (7 << 16)
 #       define R128_STENCIL_ZPASS_KEEP        (0 << 20)
 #       define R128_STENCIL_ZPASS_ZERO        (1 << 20)
 #       define R128_STENCIL_ZPASS_REPLACE     (2 << 20)
 #       define R128_STENCIL_ZPASS_INC         (3 << 20)
 #       define R128_STENCIL_ZPASS_DEC         (4 << 20)
 #       define R128_STENCIL_ZPASS_INV         (5 << 20)
+#       define R128_STENCIL_ZPASS_MASK        (7 << 20)
 #       define R128_STENCIL_ZFAIL_KEEP        (0 << 24)
 #       define R128_STENCIL_ZFAIL_ZERO        (1 << 24)
 #       define R128_STENCIL_ZFAIL_REPLACE     (2 << 24)
 #       define R128_STENCIL_ZFAIL_INC         (3 << 24)
 #       define R128_STENCIL_ZFAIL_DEC         (4 << 24)
 #       define R128_STENCIL_ZFAIL_INV         (5 << 24)
+#       define R128_STENCIL_ZFAIL_MASK        (7 << 24)
 #define R128_TEX_CNTL_C                   0x1c9c
 #       define R128_Z_ENABLE                   (1 <<  0)
 #       define R128_Z_WRITE_ENABLE             (1 <<  1)