mesa: implement depth/stencil renderbuffer wrapper accessors for Z32F_X24S8
authorMarek Olšák <maraeo@gmail.com>
Fri, 1 Jul 2011 00:04:34 +0000 (02:04 +0200)
committerMarek Olšák <maraeo@gmail.com>
Sun, 10 Jul 2011 19:41:17 +0000 (21:41 +0200)
Reviewed-by: Kenneth Graunke <kenneth@whitecape.org>
src/mesa/main/depthstencil.c
src/mesa/main/depthstencil.h
src/mesa/main/framebuffer.c

index ab62c97fe5ac5728b71cf3dac2a5363acee01b13..4d0600050ffecafd48ad78be8379f6b26b837676 100644 (file)
@@ -393,6 +393,217 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
 }
 
 
+static void
+get_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+             GLint x, GLint y, void *values)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   GLfloat temp[MAX_WIDTH*2];
+   GLfloat *dst = (GLfloat *) values;
+   const GLfloat *src = (const GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+   GLuint i;
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   if (!src) {
+      dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+      src = temp;
+   }
+   for (i = 0; i < count; i++) {
+      dst[i] = src[i*2];
+   }
+}
+
+static void
+get_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+                const GLint x[], const GLint y[], void *values)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   GLfloat temp[MAX_WIDTH*2];
+   GLfloat *dst = (GLfloat *) values;
+   GLuint i;
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   ASSERT(count <= MAX_WIDTH);
+   /* don't bother trying direct access */
+   dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+   for (i = 0; i < count; i++) {
+      dst[i] = temp[i*2];
+   }
+}
+
+static void
+put_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+             GLint x, GLint y, const void *values, const GLubyte *mask)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   const GLfloat *src = (const GLfloat *) values;
+   GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   if (dst) {
+      /* direct access */
+      GLuint i;
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            dst[i*2] = src[i];
+         }
+      }
+   }
+   else {
+      /* get, modify, put */
+      GLfloat temp[MAX_WIDTH*2];
+      GLuint i;
+      dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            temp[i*2] = src[i];
+         }
+      }
+      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+   }
+}
+
+static void
+put_mono_row_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+                  GLint x, GLint y, const void *value, const GLubyte *mask)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x, y);
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   if (dst) {
+      /* direct access */
+      GLuint i;
+      const GLfloat val = *(GLfloat*)value;
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            dst[i*2] = val;
+         }
+      }
+   }
+   else {
+      /* get, modify, put */
+      GLfloat temp[MAX_WIDTH*2];
+      GLuint i;
+      const GLfloat val = *(GLfloat *)value;
+      dsrb->GetRow(ctx, dsrb, count, x, y, temp);
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            temp[i*2] = val;
+         }
+      }
+      dsrb->PutRow(ctx, dsrb, count, x, y, temp, mask);
+   }
+}
+
+static void
+put_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb, GLuint count,
+                const GLint x[], const GLint y[],
+                const void *values, const GLubyte *mask)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   const GLfloat *src = (const GLfloat *) values;
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
+      /* direct access */
+      GLuint i;
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            GLfloat *dst = (GLfloat *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+            *dst = src[i];
+         }
+      }
+   }
+   else {
+      /* get, modify, put */
+      GLfloat temp[MAX_WIDTH*2];
+      GLuint i;
+      dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            temp[i*2] = src[i];
+         }
+      }
+      dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+   }
+}
+
+static void
+put_mono_values_z32f(struct gl_context *ctx, struct gl_renderbuffer *z32frb,
+                     GLuint count, const GLint x[], const GLint y[],
+                     const void *value, const GLubyte *mask)
+{
+   struct gl_renderbuffer *dsrb = z32frb->Wrapped;
+   GLfloat temp[MAX_WIDTH*2];
+   GLuint i;
+   const GLfloat val = *(GLfloat *)value;
+   ASSERT(z32frb->DataType == GL_FLOAT);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   /* get, modify, put */
+   dsrb->GetValues(ctx, dsrb, count, x, y, temp);
+   for (i = 0; i < count; i++) {
+      if (!mask || mask[i]) {
+         temp[i*2] = val;
+      }
+   }
+   dsrb->PutValues(ctx, dsrb, count, x, y, temp, mask);
+}
+
+
+/**
+ * Wrap the given GL_DEPTH_STENCIL renderbuffer so that it acts like
+ * a depth renderbuffer.
+ * \return new depth renderbuffer
+ */
+struct gl_renderbuffer *
+_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
+                                    struct gl_renderbuffer *dsrb)
+{
+   struct gl_renderbuffer *z32frb;
+
+   ASSERT(dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   ASSERT(dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
+
+   z32frb = ctx->Driver.NewRenderbuffer(ctx, 0);
+   if (!z32frb)
+      return NULL;
+
+   /* NOTE: need to do manual refcounting here */
+   z32frb->Wrapped = dsrb;
+   dsrb->RefCount++;
+
+   z32frb->Name = dsrb->Name;
+   z32frb->RefCount = 0;
+   z32frb->Width = dsrb->Width;
+   z32frb->Height = dsrb->Height;
+   z32frb->RowStride = dsrb->RowStride;
+   z32frb->InternalFormat = GL_DEPTH_COMPONENT32F;
+   z32frb->Format = MESA_FORMAT_Z32_FLOAT;
+   z32frb->_BaseFormat = GL_DEPTH_COMPONENT;
+   z32frb->DataType = GL_FLOAT;
+   z32frb->Data = NULL;
+   z32frb->Delete = delete_wrapper;
+   z32frb->AllocStorage = alloc_wrapper_storage;
+   z32frb->GetPointer = nop_get_pointer;
+   z32frb->GetRow = get_row_z32f;
+   z32frb->GetValues = get_values_z32f;
+   z32frb->PutRow = put_row_z32f;
+   z32frb->PutRowRGB = NULL;
+   z32frb->PutMonoRow = put_mono_row_z32f;
+   z32frb->PutValues = put_values_z32f;
+   z32frb->PutMonoValues = put_mono_values_z32f;
+
+   return z32frb;
+}
+
+
 /*======================================================================
  * Stencil wrapper around depth/stencil renderbuffer
  */
@@ -402,16 +613,22 @@ get_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
            GLint x, GLint y, void *values)
 {
    struct gl_renderbuffer *dsrb = s8rb->Wrapped;
-   GLuint temp[MAX_WIDTH], i;
+   GLuint temp[MAX_WIDTH*2], i;
    GLubyte *dst = (GLubyte *) values;
    const GLuint *src = (const GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
    ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
    if (!src) {
       dsrb->GetRow(ctx, dsrb, count, x, y, temp);
       src = temp;
    }
-   if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+   if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+      for (i = 0; i < count; i++) {
+         dst[i] = src[i*2+1] & 0xff;
+      }
+   }
+   else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
       for (i = 0; i < count; i++) {
          dst[i] = src[i] & 0xff;
       }
@@ -429,14 +646,20 @@ get_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
               const GLint x[], const GLint y[], void *values)
 {
    struct gl_renderbuffer *dsrb = s8rb->Wrapped;
-   GLuint temp[MAX_WIDTH], i;
+   GLuint temp[MAX_WIDTH*2], i;
    GLubyte *dst = (GLubyte *) values;
    ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
    ASSERT(count <= MAX_WIDTH);
    /* don't bother trying direct access */
    dsrb->GetValues(ctx, dsrb, count, x, y, temp);
-   if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+   if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+      for (i = 0; i < count; i++) {
+         dst[i] = temp[i*2+1] & 0xff;
+      }
+   }
+   else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
       for (i = 0; i < count; i++) {
          dst[i] = temp[i] & 0xff;
       }
@@ -457,11 +680,19 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
    const GLubyte *src = (const GLubyte *) values;
    GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
    ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
    if (dst) {
       /* direct access */
       GLuint i;
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               dst[i*2+1] = src[i];
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                dst[i] = (dst[i] & 0xffffff00) | src[i];
@@ -479,9 +710,16 @@ put_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count,
    }
    else {
       /* get, modify, put */
-      GLuint temp[MAX_WIDTH], i;
+      GLuint temp[MAX_WIDTH*2], i;
       dsrb->GetRow(ctx, dsrb, count, x, y, temp);
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               temp[i*2+1] = src[i];
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                temp[i] = (temp[i] & 0xffffff00) | src[i];
@@ -508,11 +746,19 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
    const GLubyte val = *((GLubyte *) value);
    GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x, y);
    ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
    if (dst) {
       /* direct access */
       GLuint i;
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               dst[i*2+1] = val;
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                dst[i] = (dst[i] & 0xffffff00) | val;
@@ -530,9 +776,16 @@ put_mono_row_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint cou
    }
    else {
       /* get, modify, put */
-      GLuint temp[MAX_WIDTH], i;
+      GLuint temp[MAX_WIDTH*2], i;
       dsrb->GetRow(ctx, dsrb, count, x, y, temp);
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               temp[i*2+1] = val;
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                temp[i] = (temp[i] & 0xffffff00) | val;
@@ -559,11 +812,20 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
    struct gl_renderbuffer *dsrb = s8rb->Wrapped;
    const GLubyte *src = (const GLubyte *) values;
    ASSERT(s8rb->DataType == GL_UNSIGNED_BYTE);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
    if (dsrb->GetPointer(ctx, dsrb, 0, 0)) {
       /* direct access */
       GLuint i;
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
+               dst[1] = src[i];
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                GLuint *dst = (GLuint *) dsrb->GetPointer(ctx, dsrb, x[i], y[i]);
@@ -583,9 +845,16 @@ put_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint count
    }
    else {
       /* get, modify, put */
-      GLuint temp[MAX_WIDTH], i;
+      GLuint temp[MAX_WIDTH*2], i;
       dsrb->GetValues(ctx, dsrb, count, x, y, temp);
-      if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+      if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+         for (i = 0; i < count; i++) {
+            if (!mask || mask[i]) {
+               temp[i*2+1] = src[i];
+            }
+         }
+      }
+      else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
          for (i = 0; i < count; i++) {
             if (!mask || mask[i]) {
                temp[i] = (temp[i] & 0xffffff00) | src[i];
@@ -610,11 +879,18 @@ put_mono_values_s8(struct gl_context *ctx, struct gl_renderbuffer *s8rb, GLuint
                    const void *value, const GLubyte *mask)
 {
    struct gl_renderbuffer *dsrb = s8rb->Wrapped;
-   GLuint temp[MAX_WIDTH], i;
+   GLuint temp[MAX_WIDTH*2], i;
    const GLubyte val = *((GLubyte *) value);
    /* get, modify, put */
    dsrb->GetValues(ctx, dsrb, count, x, y, temp);
-   if (dsrb->Format == MESA_FORMAT_Z24_S8) {
+   if (dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+      for (i = 0; i < count; i++) {
+         if (!mask || mask[i]) {
+            temp[i*2+1] = val;
+         }
+      }
+   }
+   else if (dsrb->Format == MESA_FORMAT_Z24_S8) {
       for (i = 0; i < count; i++) {
          if (!mask || mask[i]) {
             temp[i] = (temp[i] & 0xffffff00) | val;
@@ -644,8 +920,10 @@ _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx, struct gl_renderbuffer
    struct gl_renderbuffer *s8rb;
 
    ASSERT(dsrb->Format == MESA_FORMAT_Z24_S8 ||
-          dsrb->Format == MESA_FORMAT_S8_Z24);
-   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT);
+          dsrb->Format == MESA_FORMAT_S8_Z24 ||
+          dsrb->Format == MESA_FORMAT_Z32_FLOAT_X24S8);
+   ASSERT(dsrb->DataType == GL_UNSIGNED_INT_24_8_EXT ||
+          dsrb->DataType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
 
    s8rb = ctx->Driver.NewRenderbuffer(ctx, 0);
    if (!s8rb)
index ef63c5d7a31fbd8326b49a14943b647de2a3d655..b47a2e482c21debb1d5c93817efbfee6c300cea4 100644 (file)
@@ -33,6 +33,11 @@ _mesa_new_z24_renderbuffer_wrapper(struct gl_context *ctx,
                                    struct gl_renderbuffer *dsrb);
 
 
+extern struct gl_renderbuffer *
+_mesa_new_z32f_renderbuffer_wrapper(struct gl_context *ctx,
+                                    struct gl_renderbuffer *dsrb);
+
+
 extern struct gl_renderbuffer *
 _mesa_new_s8_renderbuffer_wrapper(struct gl_context *ctx,
                                   struct gl_renderbuffer *dsrb);
index 66c9bd91096260139b1f32ea2b7cb09c5def7e83..6e2ce74212e661596b7c7e7a60478449cfe9cee7 100644 (file)
@@ -631,8 +631,14 @@ _mesa_update_depth_buffer(struct gl_context *ctx,
           || fb->_DepthBuffer->Wrapped != depthRb
           || _mesa_get_format_base_format(fb->_DepthBuffer->Format) != GL_DEPTH_COMPONENT) {
          /* need to update wrapper */
-         struct gl_renderbuffer *wrapper
-            = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
+         struct gl_renderbuffer *wrapper;
+
+         if (depthRb->Format == MESA_FORMAT_Z32_FLOAT_X24S8) {
+            wrapper = _mesa_new_z32f_renderbuffer_wrapper(ctx, depthRb);
+         }
+         else {
+            wrapper = _mesa_new_z24_renderbuffer_wrapper(ctx, depthRb);
+         }
          _mesa_reference_renderbuffer(&fb->_DepthBuffer, wrapper);
          ASSERT(fb->_DepthBuffer->Wrapped == depthRb);
       }