mesa: Replace MESA_FORMAT_L8A8/A8L8 UNORM/SNORM/SRGB with an array format.
[mesa.git] / src / mesa / swrast / s_depth.c
index 0788644b76d79b4f82e57751f9dfeb6066a9987c..6bc737c79568e16e3852caac7b39f0d22c16f18d 100644 (file)
@@ -1,6 +1,5 @@
 /*
  * Mesa 3-D graphics library
- * Version:  7.2.1
  *
  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
  *
  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
  */
 
 
@@ -171,12 +171,12 @@ _swrast_depth_clamp_span( struct gl_context *ctx, SWspan *span )
    GLfloat min_f, max_f;
    GLuint i;
 
-   if (ctx->Viewport.Near < ctx->Viewport.Far) {
-      min_f = ctx->Viewport.Near;
-      max_f = ctx->Viewport.Far;
+   if (ctx->ViewportArray[0].Near < ctx->ViewportArray[0].Far) {
+      min_f = ctx->ViewportArray[0].Near;
+      max_f = ctx->ViewportArray[0].Far;
    } else {
-      min_f = ctx->Viewport.Far;
-      max_f = ctx->Viewport.Near;
+      min_f = ctx->ViewportArray[0].Far;
+      max_f = ctx->ViewportArray[0].Near;
    }
 
    /* Convert floating point values in [0,1] to device Z coordinates in
@@ -212,12 +212,13 @@ get_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
                GLuint count, const GLint x[], const GLint y[],
                GLuint zbuffer[])
 {
+   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
    const GLint w = rb->Width, h = rb->Height;
    const GLubyte *map = _swrast_pixel_address(rb, 0, 0);
    GLuint i;
 
-   if (rb->Format == MESA_FORMAT_Z32) {
-      const GLint rowStride = rb->RowStrideBytes;
+   if (rb->Format == MESA_FORMAT_Z_UNORM32) {
+      const GLint rowStride = srb->RowStride;
       for (i = 0; i < count; i++) {
          if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
             zbuffer[i] = *((GLuint *) (map + y[i] * rowStride + x[i] * 4));
@@ -226,7 +227,7 @@ get_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
    }
    else {
       const GLint bpp = _mesa_get_format_bytes(rb->Format);
-      const GLint rowStride = rb->RowStrideBytes;
+      const GLint rowStride = srb->RowStride;
       for (i = 0; i < count; i++) {
          if (x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
             const GLubyte *src = map + y[i] * rowStride+ x[i] * bpp;
@@ -246,12 +247,13 @@ put_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
                GLuint count, const GLint x[], const GLint y[],
                const GLuint zvalues[], const GLubyte mask[])
 {
+   struct swrast_renderbuffer *srb = swrast_renderbuffer(rb);
    const GLint w = rb->Width, h = rb->Height;
    GLubyte *map = _swrast_pixel_address(rb, 0, 0);
    GLuint i;
 
-   if (rb->Format == MESA_FORMAT_Z32) {
-      const GLuint rowStride = rb->RowStrideBytes;
+   if (rb->Format == MESA_FORMAT_Z_UNORM32) {
+      const GLint rowStride = srb->RowStride;
       for (i = 0; i < count; i++) {
          if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
             GLuint *dst = (GLuint *) (map + y[i] * rowStride + x[i] * 4);
@@ -260,9 +262,9 @@ put_z32_values(struct gl_context *ctx, struct gl_renderbuffer *rb,
       }
    }
    else {
-      gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
+      mesa_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
       const GLint bpp = _mesa_get_format_bytes(rb->Format);
-      const GLint rowStride = rb->RowStrideBytes;
+      const GLint rowStride = srb->RowStride;
       for (i = 0; i < count; i++) {
          if (mask[i] && x[i] >= 0 && y[i] >= 0 && x[i] < w && y[i] < h) {
             void *dst = map + y[i] * rowStride + x[i] * bpp;
@@ -298,18 +300,18 @@ _swrast_depth_test_span(struct gl_context *ctx, SWspan *span)
    else
       zStart = _swrast_pixel_address(rb, span->x, span->y);
 
-   if (rb->Format == MESA_FORMAT_Z16 && !(span->arrayMask & SPAN_XY)) {
+   if (rb->Format == MESA_FORMAT_Z_UNORM16 && !(span->arrayMask & SPAN_XY)) {
       /* directly read/write row of 16-bit Z values */
       zBufferVals = zStart;
       ztest16 = GL_TRUE;
    }
-   else if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
+   else if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
       /* directly read/write row of 32-bit Z values */
       zBufferVals = zStart;
    }
    else {
       /* copy Z buffer values into temp buffer (32-bit Z values) */
-      zBufferTemp = (GLuint *) malloc(count * sizeof(GLuint));
+      zBufferTemp = malloc(count * sizeof(GLuint));
       if (!zBufferTemp)
          return 0;
 
@@ -377,7 +379,7 @@ _swrast_depth_test_span(struct gl_context *ctx, SWspan *span)
       }
       else {
          /* horizontal row */
-         gl_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
+         mesa_pack_uint_z_func packZ = _mesa_get_pack_uint_z_func(rb->Format);
          GLubyte *dst = zStart;
          GLuint i;
          for (i = 0; i < count; i++) {
@@ -411,25 +413,41 @@ _swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
    struct gl_framebuffer *fb = ctx->DrawBuffer;
    struct gl_renderbuffer *rb = fb->Attachment[BUFFER_DEPTH].Renderbuffer;
    GLubyte *zStart;
-   GLuint zMin = (GLuint) (ctx->Depth.BoundsMin * fb->_DepthMaxF + 0.5F);
-   GLuint zMax = (GLuint) (ctx->Depth.BoundsMax * fb->_DepthMaxF + 0.5F);
+   GLuint zMin = (GLuint)((double)ctx->Depth.BoundsMin * 0xffffffff);
+   GLuint zMax = (GLuint)((double)ctx->Depth.BoundsMax * 0xffffffff);
    GLubyte *mask = span->array->mask;
    const GLuint count = span->end;
    GLuint i;
    GLboolean anyPass = GL_FALSE;
-   GLuint zBufferTemp[MAX_WIDTH];
+   GLuint *zBufferTemp;
    const GLuint *zBufferVals;
 
+   zBufferTemp = malloc(count * sizeof(GLuint));
+   if (!zBufferTemp) {
+      /* don't generate a stream of OUT_OF_MEMORY errors here */
+      return GL_FALSE;
+   }
+
    if (span->arrayMask & SPAN_XY)
       zStart = NULL;
    else
       zStart = _swrast_pixel_address(rb, span->x, span->y);
 
-   if (rb->Format == MESA_FORMAT_Z32 && !(span->arrayMask & SPAN_XY)) {
+   if (rb->Format == MESA_FORMAT_Z_UNORM32 && !(span->arrayMask & SPAN_XY)) {
       /* directly access 32-bit values in the depth buffer */
       zBufferVals = (const GLuint *) zStart;
    }
    else {
+      /* Round the bounds to the precision of the zbuffer. */
+      if (rb->Format == MESA_FORMAT_Z_UNORM16) {
+         zMin = (zMin & 0xffff0000) | (zMin >> 16);
+         zMax = (zMax & 0xffff0000) | (zMax >> 16);
+      } else {
+         /* 24 bits */
+         zMin = (zMin & 0xffffff00) | (zMin >> 24);
+         zMax = (zMax & 0xffffff00) | (zMax >> 24);
+      }
+
       /* unpack Z values into a temporary array */
       if (span->arrayMask & SPAN_XY) {
          get_z32_values(ctx, rb, count, span->array->x, span->array->y,
@@ -451,6 +469,8 @@ _swrast_depth_bounds_test( struct gl_context *ctx, SWspan *span )
       }
    }
 
+   free(zBufferTemp);
+
    return anyPass;
 }
 
@@ -536,22 +556,23 @@ _swrast_clear_depth_buffer(struct gl_context *ctx)
    height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
 
    mapMode = GL_MAP_WRITE_BIT;
-   if (rb->Format == MESA_FORMAT_S8_Z24 ||
-       rb->Format == MESA_FORMAT_X8_Z24 ||
-       rb->Format == MESA_FORMAT_Z24_S8 ||
-       rb->Format == MESA_FORMAT_Z24_X8) {
+   if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
+       rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT ||
+       rb->Format == MESA_FORMAT_S8_UINT_Z24_UNORM ||
+       rb->Format == MESA_FORMAT_X8_UINT_Z24_UNORM) {
       mapMode |= GL_MAP_READ_BIT;
    }
 
    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
-                               mapMode, &map, &rowStride);
+                               mapMode, &map, &rowStride,
+                               ctx->DrawBuffer->FlipY);
    if (!map) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth)");
       return;
    }
 
    switch (rb->Format) {
-   case MESA_FORMAT_Z16:
+   case MESA_FORMAT_Z_UNORM16:
       {
          GLfloat clear = (GLfloat) ctx->Depth.Clear;
          GLushort clearVal = 0;
@@ -571,8 +592,8 @@ _swrast_clear_depth_buffer(struct gl_context *ctx)
          }
       }
       break;
-   case MESA_FORMAT_Z32:
-   case MESA_FORMAT_Z32_FLOAT:
+   case MESA_FORMAT_Z_UNORM32:
+   case MESA_FORMAT_Z_FLOAT32:
       {
          GLfloat clear = (GLfloat) ctx->Depth.Clear;
          GLuint clearVal = 0;
@@ -586,17 +607,17 @@ _swrast_clear_depth_buffer(struct gl_context *ctx)
          }
       }
       break;
-   case MESA_FORMAT_S8_Z24:
-   case MESA_FORMAT_X8_Z24:
-   case MESA_FORMAT_Z24_S8:
-   case MESA_FORMAT_Z24_X8:
+   case MESA_FORMAT_Z24_UNORM_S8_UINT:
+   case MESA_FORMAT_Z24_UNORM_X8_UINT:
+   case MESA_FORMAT_S8_UINT_Z24_UNORM:
+   case MESA_FORMAT_X8_UINT_Z24_UNORM:
       {
          GLfloat clear = (GLfloat) ctx->Depth.Clear;
          GLuint clearVal = 0;
          GLuint mask;
 
-         if (rb->Format == MESA_FORMAT_S8_Z24 ||
-             rb->Format == MESA_FORMAT_X8_Z24)
+         if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT ||
+             rb->Format == MESA_FORMAT_Z24_UNORM_X8_UINT)
             mask = 0xff000000;
          else
             mask = 0xff;
@@ -612,7 +633,7 @@ _swrast_clear_depth_buffer(struct gl_context *ctx)
 
       }
       break;
-   case MESA_FORMAT_Z32_FLOAT_X24S8:
+   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
       /* XXX untested */
       {
          GLfloat clearVal = (GLfloat) ctx->Depth.Clear;
@@ -669,22 +690,23 @@ _swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
    }
 
    ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height,
-                               mapMode, &map, &rowStride);
+                               mapMode, &map, &rowStride,
+                               ctx->DrawBuffer->FlipY);
    if (!map) {
       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClear(depth+stencil)");
       return;
    }
 
    switch (rb->Format) {
-   case MESA_FORMAT_S8_Z24:
-   case MESA_FORMAT_Z24_S8:
+   case MESA_FORMAT_Z24_UNORM_S8_UINT:
+   case MESA_FORMAT_S8_UINT_Z24_UNORM:
       {
          GLfloat zClear = (GLfloat) ctx->Depth.Clear;
          GLuint clear = 0, mask;
 
          _mesa_pack_float_z_row(rb->Format, 1, &zClear, &clear);
 
-         if (rb->Format == MESA_FORMAT_S8_Z24) {
+         if (rb->Format == MESA_FORMAT_Z24_UNORM_S8_UINT) {
             mask = ((~writeMask) & 0xff) << 24;
             clear |= (ctx->Stencil.Clear & writeMask & 0xff) << 24;
          }
@@ -709,7 +731,7 @@ _swrast_clear_depth_stencil_buffer(struct gl_context *ctx)
          }
       }
       break;
-   case MESA_FORMAT_Z32_FLOAT_X24S8:
+   case MESA_FORMAT_Z32_FLOAT_S8X24_UINT:
       /* XXX untested */
       {
          const GLfloat zClear = (GLfloat) ctx->Depth.Clear;