Drop GLcontext typedef and use struct gl_context instead
[mesa.git] / src / mesa / drivers / dri / r128 / r128_span.c
index e64282b8a7538df4e7b2cbbd4b75ac95b592aa23..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,24 +35,21 @@ 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"
 
 #define DBG 0
 
-#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset          \
-     + ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
-
 #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);                           \
-   __DRIscreenPrivate *sPriv = rmesa->driScreen;                       \
-   __DRIdrawablePrivate *dPriv = rmesa->driDrawable;                   \
+   __DRIscreen *sPriv = rmesa->driScreen;                      \
+   __DRIdrawable *dPriv = rmesa->driDrawable;                  \
    driRenderbuffer *drb = (driRenderbuffer *) rb;                      \
    GLuint height = dPriv->h;                                           \
    GLuint p;                                                           \
@@ -62,8 +58,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
 #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
 
@@ -88,8 +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_SRC_PTR(X,Y) GET_PTR(X,Y)
-#define GET_DST_PTR(X,Y) GET_PTR(X,Y)
+#define GET_PTR(X,Y) (sPriv->pFB + drb->flippedOffset          \
+     + ((dPriv->y + (Y)) * drb->flippedPitch + (dPriv->x + (X))) * drb->cpp)
 #include "spantmp2.h"
 
 
@@ -100,23 +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_SRC_PTR(X,Y) GET_PTR(X,Y)
-#define GET_DST_PTR(X,Y) GET_PTR(X,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 {                                                                   \
@@ -185,21 +205,44 @@ do {                                                                      \
 
 /* 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()                                              \
@@ -208,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 );                             \
@@ -261,10 +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)
+
+#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)
+
+#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)
 
-void r128SpanRenderStart( GLcontext *ctx )
+#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( struct gl_context *ctx )
 {
    r128ContextPtr rmesa = R128_CONTEXT(ctx);
    FLUSH_BATCH(rmesa);
@@ -272,14 +408,16 @@ 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 )
 {
    struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
    swdd->SpanRenderStart       = r128SpanRenderStart;
@@ -291,20 +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) {
+   else if (drb->Base.Format == MESA_FORMAT_Z16) {
       r128InitDepthPointers_z16(&drb->Base);
    }
-   else if (drb->Base.InternalFormat == GL_DEPTH_COMPONENT24) {
+   else if (drb->Base.Format == MESA_FORMAT_S8_Z24) {
       r128InitDepthPointers_z24_s8(&drb->Base);
    }
+   else if (drb->Base.Format == MESA_FORMAT_S8) {
+      radeonInitStencilPointers_z24_s8(&drb->Base);
+   }
 }