Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / dri / r128 / r128_span.c
index fd4722b3b36d170aa4e3fa86bb4957c8abf12e3a..307de56ee13d3f7d55907cd0de672dc7bc509447 100644 (file)
@@ -1,4 +1,3 @@
-/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.8 2002/10/30 12:51:39 alanh Exp $ */
 /**************************************************************************
 
 Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc.,
@@ -36,9 +35,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #include "r128_context.h"
 #include "r128_ioctl.h"
-#include "r128_state.h"
 #include "r128_span.h"
-#include "r128_tex.h"
 
 #include "swrast/swrast.h"
 
@@ -46,30 +43,23 @@ 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);                           \
-   r128ScreenPtr r128scrn = rmesa->r128Screen;                         \
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;                       \
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;                   \
-   GLuint pitch = r128scrn->frontPitch * r128scrn->cpp;                        \
+   __DRIscreen *sPriv = rmesa->driScreen;                      \
+   __DRIdrawable *dPriv = rmesa->driDrawable;                  \
+   driRenderbuffer *drb = (driRenderbuffer *) rb;                      \
    GLuint height = dPriv->h;                                           \
-   char *buf = (char *)(sPriv->pFB +                                   \
-                       rmesa->drawOffset +                             \
-                       (dPriv->x * r128scrn->cpp) +                    \
-                       (dPriv->y * pitch));                            \
-   char *read_buf = (char *)(sPriv->pFB +                              \
-                            rmesa->readOffset +                        \
-                            (dPriv->x * r128scrn->cpp) +               \
-                            (dPriv->y * pitch));                       \
    GLuint p;                                                           \
-   (void) read_buf; (void) buf; (void) p
+   (void) p;
 
 #define LOCAL_DEPTH_VARS                                               \
    r128ContextPtr rmesa = R128_CONTEXT(ctx);                           \
    r128ScreenPtr r128scrn = rmesa->r128Screen;                         \
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;                       \
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;                   \
+   __DRIscreen *sPriv = rmesa->driScreen;                      \
+   __DRIdrawable *dPriv = rmesa->driDrawable;                  \
    GLuint height = dPriv->h;                                           \
    (void) r128scrn; (void) sPriv; (void) height
 
@@ -94,6 +84,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define TAG(x)    r128##x##_RGB565
 #define TAG2(x,y) r128##x##_RGB565##y
+#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset          \
+     + ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
 #include "spantmp2.h"
 
 
@@ -104,21 +96,47 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 #define TAG(x)    r128##x##_ARGB8888
 #define TAG2(x,y) r128##x##_ARGB8888##y
+#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset          \
+     + ((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
  */
 
+/* These functions require locking */
+#undef HW_LOCK
+#undef HW_UNLOCK
+#define HW_LOCK()    LOCK_HARDWARE(R128_CONTEXT(ctx));
+#define HW_UNLOCK()  UNLOCK_HARDWARE(R128_CONTEXT(ctx));
+
 /* 16-bit depth buffer functions
  */
+#define VALUE_TYPE GLushort
 
 #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 {                                                                   \
@@ -181,27 +199,50 @@ do {                                                                      \
    }                                                                   \
 } while (0)
 
-#define TAG(x) r128##x##_16
+#define TAG(x) r128##x##_z16
 #include "depthtmp.h"
 
 
 /* 24-bit depth, 8-bit stencil buffer functions
  */
+#define VALUE_TYPE GLuint
+
 #define WRITE_DEPTH_SPAN()                                             \
+do {                                                                   \
+   GLuint 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 {                                                                   \
+   GLuint 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()                                              \
@@ -210,6 +251,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 );                             \
@@ -254,7 +296,7 @@ do {                                                                        \
    }                                                                   \
 } while (0)
 
-#define TAG(x) r128##x##_24_8
+#define TAG(x) r128##x##_z24_s8
 #include "depthtmp.h"
 
 
@@ -263,45 +305,102 @@ do {                                                                     \
  * Stencil buffer
  */
 
-/* FIXME: Add support for hardware stencil buffers.
+/* 24 bit depth, 8 bit stencil depthbuffer functions
  */
+#define WRITE_STENCIL_SPAN()                                           \
+do {                                                                   \
+   GLuint 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)
 
-/*
- * This function is called to specify which buffer to read and write
- * for software rasterization (swrast) fallbacks.  This doesn't necessarily
- * correspond to glDrawBuffer() or glReadBuffer() calls.
- */
-static void r128DDSetBuffer( GLcontext *ctx,
-                             GLframebuffer *colorBuffer,
-                             GLuint bufferBit )
-{
-   r128ContextPtr rmesa = R128_CONTEXT(ctx);
+#define WRITE_STENCIL_PIXELS()                                         \
+do {                                                                   \
+   GLuint 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)
 
-   switch ( bufferBit ) {
-   case BUFFER_BIT_FRONT_LEFT:
-      if ( rmesa->sarea->pfCurrentPage == 1 ) {
-         rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset;
-         rmesa->drawPitch  = rmesa->readPitch  = rmesa->r128Screen->backPitch;
-      } else {
-         rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset;
-         rmesa->drawPitch  = rmesa->readPitch  = rmesa->r128Screen->frontPitch;
-      }
-      break;
-   case BUFFER_BIT_BACK_LEFT:
-      if ( rmesa->sarea->pfCurrentPage == 1 ) {
-         rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset;
-         rmesa->drawPitch  = rmesa->readPitch  = rmesa->r128Screen->frontPitch;
-      } else {
-         rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset;
-         rmesa->drawPitch  = rmesa->readPitch  = rmesa->r128Screen->backPitch;
-      }
-      break;
-   default:
-      break;
-   }
-}
+#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"
 
-void r128SpanRenderStart( GLcontext *ctx )
+static void
+r128SpanRenderStart( struct gl_context *ctx )
 {
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    FLUSH_BATCH(rmesa);
@@ -309,19 +408,18 @@ void r128SpanRenderStart( GLcontext *ctx )
    r128WaitForIdleLocked( rmesa );
 }
 
-void r128SpanRenderFinish( GLcontext *ctx )
+static void
+r128SpanRenderFinish( struct gl_context *ctx )
 {
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    _swrast_flush( ctx );
+   r128WaitForIdleLocked( rmesa );
    UNLOCK_HARDWARE( rmesa );
 }
 
-void r128DDInitSpanFuncs( GLcontext *ctx )
+void r128DDInitSpanFuncs( struct gl_context *ctx )
 {
-   r128ContextPtr rmesa = R128_CONTEXT(ctx);
    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
-
-   swdd->SetBuffer = r128DDSetBuffer;
    swdd->SpanRenderStart       = r128SpanRenderStart;
    swdd->SpanRenderFinish      = r128SpanRenderFinish;
 }
@@ -331,38 +429,21 @@ void r128DDInitSpanFuncs( GLcontext *ctx )
  * Plug in the Get/Put routines for the given driRenderbuffer.
  */
 void
-r128SetSpanFunctions(driRenderbuffer *drb, const GLvisual *vis)
+r128SetSpanFunctions(driRenderbuffer *drb, const struct gl_config *vis)
 {
-   if (drb->Base.InternalFormat == GL_RGBA) {
-      if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) {
-         r128InitPointers_RGB565(&drb->Base);
-      }
-      else {
-         r128InitPointers_ARGB8888(&drb->Base);
-      }
+   if (drb->Base.Format == MESA_FORMAT_RGB565) {
+      r128InitPointers_RGB565(&drb->Base);
+   }
+   else if (drb->Base.Format == MESA_FORMAT_ARGB8888) {
+      r128InitPointers_ARGB8888(&drb->Base);
    }
-   else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT16) {
-      drb->Base.GetRow        = r128ReadDepthSpan_16;
-      drb->Base.GetValues     = r128ReadDepthPixels_16;
-      drb->Base.PutRow        = r128WriteDepthSpan_16;
-      drb->Base.PutMonoRow    = r128WriteMonoDepthSpan_16;
-      drb->Base.PutValues     = r128WriteDepthPixels_16;
-      drb->Base.PutMonoValues = NULL;
+   else if (drb->Base.Format == MESA_FORMAT_Z16) {
+      r128InitDepthPointers_z16(&drb->Base);
    }
-   else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
-      drb->Base.GetRow        = r128ReadDepthSpan_24_8;
-      drb->Base.GetValues     = r128ReadDepthPixels_24_8;
-      drb->Base.PutRow        = r128WriteDepthSpan_24_8;
-      drb->Base.PutMonoRow    = r128WriteMonoDepthSpan_24_8;
-      drb->Base.PutValues     = r128WriteDepthPixels_24_8;
-      drb->Base.PutMonoValues = NULL;
+   else if (drb->Base.Format == MESA_FORMAT_S8_Z24) {
+      r128InitDepthPointers_z24_s8(&drb->Base);
    }
-   else if (drb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) {
-      drb->Base.GetRow        = NULL;
-      drb->Base.GetValues     = NULL;
-      drb->Base.PutRow        = NULL;
-      drb->Base.PutMonoRow    = NULL;
-      drb->Base.PutValues     = NULL;
-      drb->Base.PutMonoValues = NULL;
+   else if (drb->Base.Format == MESA_FORMAT_S8) {
+      radeonInitStencilPointers_z24_s8(&drb->Base);
    }
 }