fixes for C++ warnings/errors
[mesa.git] / src / mesa / swrast / s_depth.c
index e36878e6fc8be0981ebfeafc59abe3e493f30ffc..408174c990fb165941a8ee0df4015852e42347b5 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * Mesa 3-D graphics library
- * Version:  6.3
+ * Version:  6.5.1
  *
- * Copyright (C) 1999-2005  Brian Paul   All Rights Reserved.
+ * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -31,6 +31,7 @@
 
 #include "s_depth.h"
 #include "s_context.h"
+#include "s_span.h"
 
 
 /**
@@ -502,10 +503,10 @@ depth_test_span32( GLcontext *ctx, GLuint n,
  * Apply depth test to span of fragments.
  */
 static GLuint
-depth_test_span( GLcontext *ctx, struct sw_span *span)
+depth_test_span( GLcontext *ctx, SWspan *span)
 {
    struct gl_framebuffer *fb = ctx->DrawBuffer;
-   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+   struct gl_renderbuffer *rb = fb->_DepthBuffer;
    const GLint x = span->x;
    const GLint y = span->y;
    const GLuint count = span->end;
@@ -518,12 +519,13 @@ depth_test_span( GLcontext *ctx, struct sw_span *span)
    
    if (rb->GetPointer(ctx, rb, 0, 0)) {
       /* Directly access buffer */
-      if (ctx->DrawBuffer->Visual.depthBits <= 16) {
+      if (rb->DataType == GL_UNSIGNED_SHORT) {
          GLushort *zbuffer = (GLushort *) rb->GetPointer(ctx, rb, x, y);
          passed = depth_test_span16(ctx, count, zbuffer, zValues, mask);
       }
       else {
          GLuint *zbuffer = (GLuint *) rb->GetPointer(ctx, rb, x, y);
+         ASSERT(rb->DataType == GL_UNSIGNED_INT);
          passed = depth_test_span32(ctx, count, zbuffer, zValues, mask);
       }
    }
@@ -1049,10 +1051,10 @@ direct_depth_test_pixels32(GLcontext *ctx, GLuint *zStart, GLuint stride,
 
 
 static GLuint
-depth_test_pixels( GLcontext *ctx, struct sw_span *span )
+depth_test_pixels( GLcontext *ctx, SWspan *span )
 {
    struct gl_framebuffer *fb = ctx->DrawBuffer;
-   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+   struct gl_renderbuffer *rb = fb->_DepthBuffer;
    const GLuint count = span->end;
    const GLint *x = span->array->x;
    const GLint *y = span->array->y;
@@ -1069,6 +1071,7 @@ depth_test_pixels( GLcontext *ctx, struct sw_span *span )
       else {
          GLuint *zStart = (GLuint *) rb->Data;
          GLuint stride = rb->Width;
+         ASSERT(rb->DataType == GL_UNSIGNED_INT);
          direct_depth_test_pixels32(ctx, zStart, stride, count, x, y, z, mask);
       }
    }
@@ -1076,14 +1079,14 @@ depth_test_pixels( GLcontext *ctx, struct sw_span *span )
       /* read depth values from buffer, test, write back */
       if (rb->DataType == GL_UNSIGNED_SHORT) {
          GLushort zbuffer[MAX_WIDTH];
-         rb->GetValues(ctx, rb, count, x, y, zbuffer);
+         _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLushort));
          depth_test_span16(ctx, count, zbuffer, z, mask );
          rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
       }
       else {
          GLuint zbuffer[MAX_WIDTH];
          ASSERT(rb->DataType == GL_UNSIGNED_INT);
-         rb->GetValues(ctx, rb, count, x, y, zbuffer);
+         _swrast_get_values(ctx, rb, count, x, y, zbuffer, sizeof(GLuint));
          depth_test_span32(ctx, count, zbuffer, z, mask );
          rb->PutValues(ctx, rb, count, x, y, zbuffer, NULL);
       }
@@ -1098,7 +1101,7 @@ depth_test_pixels( GLcontext *ctx, struct sw_span *span )
  * \return approx number of pixels that passed (only zero is reliable)
  */
 GLuint
-_swrast_depth_test_span( GLcontext *ctx, struct sw_span *span)
+_swrast_depth_test_span( GLcontext *ctx, SWspan *span)
 {
    if (span->arrayMask & SPAN_XY)
       return depth_test_pixels(ctx, span);
@@ -1115,10 +1118,10 @@ _swrast_depth_test_span( GLcontext *ctx, struct sw_span *span)
  * \return GL_TRUE if any fragments pass, GL_FALSE if no fragments pass
  */
 GLboolean
-_swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
+_swrast_depth_bounds_test( GLcontext *ctx, SWspan *span )
 {
    struct gl_framebuffer *fb = ctx->DrawBuffer;
-   struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
+   struct gl_renderbuffer *rb = fb->_DepthBuffer;
    GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
    GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
    GLubyte *mask = span->array->mask;
@@ -1130,11 +1133,12 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
       /* get 16-bit values */
       GLushort zbuffer16[MAX_WIDTH], *zbuffer;
       if (span->arrayMask & SPAN_XY) {
-         rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer16);
+         _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
+                            zbuffer16, sizeof(GLushort));
          zbuffer = zbuffer16;
       }
       else {
-         zbuffer = rb->GetPointer(ctx, rb, span->x, span->y);
+         zbuffer = (GLushort*) rb->GetPointer(ctx, rb, span->x, span->y);
          if (!zbuffer) {
             rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer16);
             zbuffer = zbuffer16;
@@ -1155,12 +1159,14 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
    else {
       /* get 32-bit values */
       GLuint zbuffer32[MAX_WIDTH], *zbuffer;
+      ASSERT(rb->DataType == GL_UNSIGNED_INT);
       if (span->arrayMask & SPAN_XY) {
-         rb->GetValues(ctx, rb, count, span->array->x, span->array->y, zbuffer32);
+         _swrast_get_values(ctx, rb, count, span->array->x, span->array->y,
+                            zbuffer32, sizeof(GLuint));
          zbuffer = zbuffer32;
       }
       else {
-         zbuffer = rb->GetPointer(ctx, rb, span->x, span->y);
+         zbuffer = (GLuint*) rb->GetPointer(ctx, rb, span->x, span->y);
          if (!zbuffer) {
             rb->GetRow(ctx, rb, count, span->x, span->y, zbuffer32);
             zbuffer = zbuffer32;
@@ -1190,22 +1196,29 @@ _swrast_depth_bounds_test( GLcontext *ctx, struct sw_span *span )
 
 
 /**
- * Read a span of depth values from the depth buffer.
- * This function does clipping before calling the device driver function.
- *
- * XXXX this is no longer a swrast function!!!
- *
+ * Read a span of depth values from the given depth renderbuffer, returning
+ * the values as GLfloats.
+ * This function does clipping to prevent reading outside the depth buffer's
+ * bounds.  Though the clipping is redundant when we're called from
+ * _swrast_ReadPixels.
  */
 void
-_swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb,
-                         GLint n, GLint x, GLint y, GLuint depth[] )
+_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
+                               GLint n, GLint x, GLint y, GLfloat depth[] )
 {
+   const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
+
+   if (!rb) {
+      /* really only doing this to prevent FP exceptions later */
+      _mesa_bzero(depth, n * sizeof(GLfloat));
+   }
+
+   ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
+
    if (y < 0 || y >= (GLint) rb->Height ||
-       x + (GLint) n <= 0 || x >= (GLint) rb->Width) {
+       x + n <= 0 || x >= (GLint) rb->Width) {
       /* span is completely outside framebuffer */
-      GLint i;
-      for (i = 0; i < n; i++)
-         depth[i] = 0;
+      _mesa_bzero(depth, n * sizeof(GLfloat));
       return;
    }
 
@@ -1213,7 +1226,7 @@ _swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb,
       GLint dx = -x;
       GLint i;
       for (i = 0; i < dx; i++)
-         depth[i] = 0;
+         depth[i] = 0.0;
       x = 0;
       n -= dx;
       depth += dx;
@@ -1222,64 +1235,119 @@ _swrast_read_depth_span( GLcontext *ctx, struct gl_renderbuffer *rb,
       GLint dx = x + n - (GLint) rb->Width;
       GLint i;
       for (i = 0; i < dx; i++)
-         depth[n - i - 1] = 0;
+         depth[n - i - 1] = 0.0;
       n -= dx;
    }
    if (n <= 0) {
       return;
    }
 
-   /* we'll always return 32-bit values to our caller */
-   if (!rb) {
-      _mesa_bzero(depth, n * sizeof(GLuint));
-   }
-   else if (rb->DataType == GL_UNSIGNED_INT) {
-      rb->GetRow(ctx, rb, x, y, n, depth);
+   if (rb->DataType == GL_UNSIGNED_INT) {
+      GLuint temp[MAX_WIDTH];
+      GLint i;
+      rb->GetRow(ctx, rb, n, x, y, temp);
+      for (i = 0; i < n; i++) {
+         depth[i] = temp[i] * scale;
+      }
    }
-   else {
+   else if (rb->DataType == GL_UNSIGNED_SHORT) {
       GLushort temp[MAX_WIDTH];
-      GLuint i;
-      ASSERT(rb->DataType == GL_UNSIGNED_SHORT);
+      GLint i;
       rb->GetRow(ctx, rb, n, x, y, temp);
       for (i = 0; i < n; i++) {
-         depth[i] = temp[i];
+         depth[i] = temp[i] * scale;
       }
    }
+   else {
+      _mesa_problem(ctx, "Invalid depth renderbuffer data type");
+   }
 }
 
 
 /**
- * Return a span of depth values from the depth buffer as floats in [0,1].
- * Input:  n - how many pixels
- *         x,y - location of first pixel
- * Output:  depth - the array of depth values
+ * As above, but return 32-bit GLuint values.
  */
 void
-_swrast_read_depth_span_float( GLcontext *ctx, struct gl_renderbuffer *rb,
-                               GLint n, GLint x, GLint y, GLfloat depth[] )
+_swrast_read_depth_span_uint( GLcontext *ctx, struct gl_renderbuffer *rb,
+                              GLint n, GLint x, GLint y, GLuint depth[] )
 {
-   const GLfloat scale = 1.0F / ctx->DrawBuffer->_DepthMaxF;
-   GLuint temp[MAX_WIDTH];
-   GLint i;
+   if (!rb) {
+      /* really only doing this to prevent FP exceptions later */
+      _mesa_bzero(depth, n * sizeof(GLfloat));
+   }
+
+   ASSERT(rb->_BaseFormat == GL_DEPTH_COMPONENT);
+
+   if (y < 0 || y >= (GLint) rb->Height ||
+       x + n <= 0 || x >= (GLint) rb->Width) {
+      /* span is completely outside framebuffer */
+      _mesa_bzero(depth, n * sizeof(GLfloat));
+      return;
+   }
 
-   assert(n <= MAX_WIDTH);
+   if (x < 0) {
+      GLint dx = -x;
+      GLint i;
+      for (i = 0; i < dx; i++)
+         depth[i] = 0;
+      x = 0;
+      n -= dx;
+      depth += dx;
+   }
+   if (x + n > (GLint) rb->Width) {
+      GLint dx = x + n - (GLint) rb->Width;
+      GLint i;
+      for (i = 0; i < dx; i++)
+         depth[n - i - 1] = 0;
+      n -= dx;
+   }
+   if (n <= 0) {
+      return;
+   }
 
-   _swrast_read_depth_span(ctx, rb, n, x, y, temp);
-   for (i = 0; i < n; i++) {
-      depth[i] = temp[i] * scale;
+   if (rb->DataType == GL_UNSIGNED_INT) {
+      rb->GetRow(ctx, rb, n, x, y, depth);
+      if (rb->DepthBits < 32) {
+         GLuint shift = 32 - rb->DepthBits;
+         GLint i;
+         for (i = 0; i < n; i++) {
+            GLuint z = depth[i];
+            depth[i] = z << shift; /* XXX lsb bits? */
+         }
+      }
+   }
+   else if (rb->DataType == GL_UNSIGNED_SHORT) {
+      GLushort temp[MAX_WIDTH];
+      GLint i;
+      rb->GetRow(ctx, rb, n, x, y, temp);
+      if (rb->DepthBits == 16) {
+         for (i = 0; i < n; i++) {
+            GLuint z = temp[i];
+            depth[i] = (z << 16) | z;
+         }
+      }
+      else {
+         GLuint shift = 16 - rb->DepthBits;
+         for (i = 0; i < n; i++) {
+            GLuint z = temp[i];
+            depth[i] = (z << (shift + 16)) | (z << shift); /* XXX lsb bits? */
+         }
+      }
+   }
+   else {
+      _mesa_problem(ctx, "Invalid depth renderbuffer data type");
    }
 }
 
 
+
 /**
- * Clear the depth buffer.
- * XXX this is no longer a swrast function!!!
+ * Clear the given z/depth renderbuffer.
  */
 void
 _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
 {
-   const GLuint clearValue
-      = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
+   GLuint clearValue;
    GLint x, y, width, height;
 
    if (!rb || !ctx->Depth.Mask) {
@@ -1287,6 +1355,14 @@ _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
       return;
    }
 
+   /* compute integer clearing value */
+   if (ctx->Depth.Clear == 1.0) {
+      clearValue = ctx->DrawBuffer->_DepthMax;
+   }
+   else {
+      clearValue = (GLuint) (ctx->Depth.Clear * ctx->DrawBuffer->_DepthMaxF);
+   }
+
    assert(rb->_BaseFormat == GL_DEPTH_COMPONENT);
 
    /* compute region to clear */
@@ -1300,8 +1376,9 @@ _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
        * memory, or perhaps the driver mmap'd the zbuffer memory.
        */
       if (rb->DataType == GL_UNSIGNED_SHORT) {
-         if (width == rb->Width &&
-             (clearValue & 0xff) == ((clearValue >> 8) & 0xff)) {
+         if ((clearValue & 0xff) == ((clearValue >> 8) & 0xff) &&
+             ((GLushort *) rb->GetPointer(ctx, rb, 0, 0) + width ==
+              (GLushort *) rb->GetPointer(ctx, rb, 0, 1))) {
             /* optimized case */
             GLushort *dst = (GLushort *) rb->GetPointer(ctx, rb, x, y);
             GLuint len = width * height * sizeof(GLushort);
@@ -1332,25 +1409,21 @@ _swrast_clear_depth_buffer( GLcontext *ctx, struct gl_renderbuffer *rb )
    else {
       /* Direct access not possible.  Use PutRow to write new values. */
       if (rb->DataType == GL_UNSIGNED_SHORT) {
-         GLushort clearRow[MAX_WIDTH];
-         GLint i, j;
-         for (j = 0; j < width; j++) {
-            clearRow[j] = clearValue;
-         }
+         GLushort clearVal16 = (GLushort) (clearValue & 0xffff);
+         GLint i;
          for (i = 0; i < height; i++) {
-            rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL);
+            rb->PutMonoRow(ctx, rb, width, x, y + i, &clearVal16, NULL);
          }
       }
-      else {
-         GLuint clearRow[MAX_WIDTH];
-         GLint i, j;
-         assert(rb->DataType == GL_UNSIGNED_INT);
-         for (j = 0; j < width; j++) {
-            clearRow[j] = clearValue;
-         }
+      else if (rb->DataType == GL_UNSIGNED_INT) {
+         GLint i;
+         ASSERT(sizeof(clearValue) == sizeof(GLuint));
          for (i = 0; i < height; i++) {
-            rb->PutRow(ctx, rb, width, x, y + i, clearRow, NULL);
+            rb->PutMonoRow(ctx, rb, width, x, y + i, &clearValue, NULL);
          }
       }
+      else {
+         _mesa_problem(ctx, "bad depth renderbuffer DataType");
+      }
    }
 }