diff options
| author | Brian Paul <brian.paul@tungstengraphics.com> | 2005-09-30 03:01:30 +0000 | 
|---|---|---|
| committer | Brian Paul <brian.paul@tungstengraphics.com> | 2005-09-30 03:01:30 +0000 | 
| commit | 76560af99d36bbccb7e390c622ee83a9ec05a775 (patch) | |
| tree | 65601fcf4ae3b498e0a4bdbe925b82714ea7398f | |
| parent | 82b29819a9ede846ad5c37ff70b71d45cf72357a (diff) | |
implemented fallbacks for GL_EXT_packed_depth_stencil
| -rw-r--r-- | src/mesa/swrast/s_texstore.c | 272 | 
1 files changed, 216 insertions, 56 deletions
| diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c index 68c8b376f8..4f4684ddb5 100644 --- a/src/mesa/swrast/s_texstore.c +++ b/src/mesa/swrast/s_texstore.c @@ -64,30 +64,30 @@ read_color_image( GLcontext *ctx, GLint x, GLint y,                    GLsizei width, GLsizei height )  {     SWcontext *swrast = SWRAST_CONTEXT(ctx); -   GLint stride, i; +   const GLint stride = 4 * width; +   GLint i;     GLchan *image, *dst;     image = (GLchan *) _mesa_malloc(width * height * 4 * sizeof(GLchan));     if (!image)        return NULL; -   RENDER_START(swrast,ctx); +   RENDER_START(swrast, ctx);     dst = image; -   stride = width * 4;     for (i = 0; i < height; i++) {        _swrast_read_rgba_span(ctx, ctx->ReadBuffer->_ColorReadBuffer,                               width, x, y + i, (GLchan (*)[4]) dst);        dst += stride;     } -   RENDER_FINISH(swrast,ctx); +   RENDER_FINISH(swrast, ctx);     return image;  } -/* +/**   * As above, but read data from depth buffer.   */  static GLfloat * @@ -104,7 +104,7 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y,     if (!image)        return NULL; -   RENDER_START(swrast,ctx); +   RENDER_START(swrast, ctx);     dst = image;     for (i = 0; i < height; i++) { @@ -112,12 +112,100 @@ read_depth_image( GLcontext *ctx, GLint x, GLint y,        dst += width;     } -   RENDER_FINISH(swrast,ctx); +   RENDER_FINISH(swrast, ctx);     return image;  } +/** + * As above, but read data from depth+stencil buffers. + */ +static GLuint * +read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y, +                         GLsizei width, GLsizei height) +{ +   struct gl_renderbuffer *depthRb +      = ctx->ReadBuffer->Attachment[BUFFER_DEPTH].Renderbuffer; +   struct gl_renderbuffer *stencilRb +      = ctx->ReadBuffer->Attachment[BUFFER_STENCIL].Renderbuffer; +   SWcontext *swrast = SWRAST_CONTEXT(ctx); +   GLuint *image, *dst; +   GLint i; + +   ASSERT(depthRb); +   ASSERT(stencilRb); + +   image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); +   if (!image) +      return NULL; + +   RENDER_START(swrast, ctx); + +   /* read from depth buffer */ +   dst = image; +   if (depthRb->DataType == GL_UNSIGNED_INT) { +      for (i = 0; i < height; i++) { +         _swrast_get_row(ctx, depthRb, width, x, y + i, dst, sizeof(GLuint)); +         dst += width; +      } +   } +   else { +      GLuint z16[MAX_WIDTH]; +      ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT); +      for (i = 0; i < height; i++) { +         GLint j; +         _swrast_get_row(ctx, depthRb, width, x, y + i, z16, sizeof(GLushort)); +         for (j = 0; j < width; j++) { +            dst[j] = z16[j]; +         } +         dst += width; +      } +   } + +   /* put depth values into bits 0xffffff00 */ +   if (depthRb->DepthBits == 24) { +      GLint j; +      for (j = 0; j < width * height; j++) { +         image[j] <<= 8; +      } +   } +   else if (depthRb->DepthBits == 16) { +      GLint j; +      for (j = 0; j < width * height; j++) { +         image[j] = (image[j] << 16) | (image[j] & 0xff00); +      }       +   } +   else { +      /* this handles arbitrary depthBits >= 12 */ +      GLint lShift = 32 - depthRb->DepthBits; +      GLint rShift = depthRb->DepthBits; +      GLint j; +      for (j = 0; j < width * height; j++) { +         GLuint z = (image[j] << lShift); +         image[j] = z | (z >> rShift); +      } +   } + +   /* read stencil values and interleave into image array */ +   dst = image; +   for (i = 0; i < height; i++) { +      GLstencil stencil[MAX_WIDTH]; +      GLint j; +      ASSERT(sizeof(GLstencil) == stencilRb->StencilBits); +      _swrast_get_row(ctx, stencilRb, width, x, y + i, +                      stencil, sizeof(GLstencil)); +      for (j = 0; j < width; j++) { +         dst[j] = (dst[j] & 0xffffff00) | (stencil[j] & 0xff); +      } +      dst += width; +   } + +   RENDER_FINISH(swrast, ctx); + +   return image; +} +  static GLboolean  is_depth_format(GLenum format) @@ -134,6 +222,19 @@ is_depth_format(GLenum format)  } +static GLboolean +is_depth_stencil_format(GLenum format) +{ +   switch (format) { +      case GL_DEPTH_STENCIL_EXT: +      case GL_DEPTH24_STENCIL8_EXT: +         return GL_TRUE; +      default: +         return GL_FALSE; +   } +} + +  /*   * Fallback for Driver.CopyTexImage1D().   */ @@ -161,12 +262,25 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");           return;        } -        /* call glTexImage1D to redefine the texture */ -      (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, -                                width, border, -                                GL_DEPTH_COMPONENT, GL_FLOAT, image, -                                &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexImage1D(ctx, target, level, internalFormat, +                             width, border, +                             GL_DEPTH_COMPONENT, GL_FLOAT, image, +                             &ctx->DefaultPacking, texObj, texImage); +      _mesa_free(image); +   } +   else if (is_depth_stencil_format(internalFormat)) { +      /* read depth/stencil image from framebuffer */ +      GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1); +      if (!image) { +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D"); +         return; +      } +      /* call glTexImage1D to redefine the texture */ +      ctx->Driver.TexImage1D(ctx, target, level, internalFormat, +                             width, border, +                             GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, +                             image, &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     }     else { @@ -176,12 +290,11 @@ _swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");           return;        } -        /* call glTexImage1D to redefine the texture */ -      (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat, -                                width, border, -                                GL_RGBA, CHAN_TYPE, image, -                                &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexImage1D(ctx, target, level, internalFormat, +                             width, border, +                             GL_RGBA, CHAN_TYPE, image, +                             &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     } @@ -220,12 +333,24 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");           return;        } -        /* call glTexImage2D to redefine the texture */ -      (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, -                                width, height, border, -                                GL_DEPTH_COMPONENT, GL_FLOAT, image, -                                &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexImage2D(ctx, target, level, internalFormat, +                             width, height, border, +                             GL_DEPTH_COMPONENT, GL_FLOAT, image, +                             &ctx->DefaultPacking, texObj, texImage); +      _mesa_free(image); +   } +   else if (is_depth_stencil_format(internalFormat)) { +      GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); +      if (!image) { +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D"); +         return; +      } +      /* call glTexImage2D to redefine the texture */ +      ctx->Driver.TexImage2D(ctx, target, level, internalFormat, +                             width, height, border, +                             GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, +                             image, &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     }     else { @@ -235,12 +360,11 @@ _swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");           return;        } -        /* call glTexImage2D to redefine the texture */ -      (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat, -                                width, height, border, -                                GL_RGBA, CHAN_TYPE, image, -                                &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexImage2D(ctx, target, level, internalFormat, +                             width, height, border, +                             GL_RGBA, CHAN_TYPE, image, +                             &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     } @@ -279,9 +403,22 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,        }        /* call glTexSubImage1D to redefine the texture */ -      (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, -                                   GL_DEPTH_COMPONENT, GL_FLOAT, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, +                                GL_DEPTH_COMPONENT, GL_FLOAT, image, +                                &ctx->DefaultPacking, texObj, texImage); +      _mesa_free(image); +   } +   else if (texImage->Format == GL_DEPTH_STENCIL_EXT) { +      /* read depth/stencil image from framebuffer */ +      GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1); +      if (!image) { +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D"); +         return; +      } +      /* call glTexImage1D to redefine the texture */ +      ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, +                                GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, +                                image, &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     }     else { @@ -291,11 +428,10 @@ _swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,           _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );           return;        } -        /* now call glTexSubImage1D to do the real work */ -      (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width, -                                   GL_RGBA, CHAN_TYPE, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width, +                                GL_RGBA, CHAN_TYPE, image, +                                &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     } @@ -334,12 +470,25 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");           return;        } - -      /* call glTexImage1D to redefine the texture */ -      (*ctx->Driver.TexSubImage2D)(ctx, target, level, -                                   xoffset, yoffset, width, height, -                                   GL_DEPTH_COMPONENT, GL_FLOAT, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      /* call glTexImage2D to redefine the texture */ +      ctx->Driver.TexSubImage2D(ctx, target, level, +                                xoffset, yoffset, width, height, +                                GL_DEPTH_COMPONENT, GL_FLOAT, image, +                                &ctx->DefaultPacking, texObj, texImage); +      _mesa_free(image); +   } +   else if (texImage->Format == GL_DEPTH_STENCIL_EXT) { +      /* read depth/stencil image from framebuffer */ +      GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); +      if (!image) { +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D"); +         return; +      } +      /* call glTexImage2D to redefine the texture */ +      ctx->Driver.TexSubImage2D(ctx, target, level, +                                xoffset, yoffset, width, height, +                                GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, +                                image, &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     }     else { @@ -349,12 +498,11 @@ _swrast_copy_texsubimage2d( GLcontext *ctx,           _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );           return;        } -        /* now call glTexSubImage2D to do the real work */ -      (*ctx->Driver.TexSubImage2D)(ctx, target, level, -                                   xoffset, yoffset, width, height, -                                   GL_RGBA, CHAN_TYPE, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexSubImage2D(ctx, target, level, +                                xoffset, yoffset, width, height, +                                GL_RGBA, CHAN_TYPE, image, +                                &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     } @@ -393,12 +541,25 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,           _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");           return;        } - -      /* call glTexImage1D to redefine the texture */ -      (*ctx->Driver.TexSubImage3D)(ctx, target, level, -                                   xoffset, yoffset, zoffset, width, height, 1, -                                   GL_DEPTH_COMPONENT, GL_FLOAT, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      /* call glTexImage3D to redefine the texture */ +      ctx->Driver.TexSubImage3D(ctx, target, level, +                                xoffset, yoffset, zoffset, width, height, 1, +                                GL_DEPTH_COMPONENT, GL_FLOAT, image, +                                &ctx->DefaultPacking, texObj, texImage); +      _mesa_free(image); +   } +   else if (texImage->Format == GL_DEPTH_STENCIL_EXT) { +      /* read depth/stencil image from framebuffer */ +      GLuint *image = read_depth_stencil_image(ctx, x, y, width, height); +      if (!image) { +         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D"); +         return; +      } +      /* call glTexImage3D to redefine the texture */ +      ctx->Driver.TexSubImage3D(ctx, target, level, +                                xoffset, yoffset, zoffset, width, height, 1, +                                GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, +                                image, &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     }     else { @@ -408,12 +569,11 @@ _swrast_copy_texsubimage3d( GLcontext *ctx,           _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );           return;        } -        /* now call glTexSubImage3D to do the real work */ -      (*ctx->Driver.TexSubImage3D)(ctx, target, level, -                                   xoffset, yoffset, zoffset, width, height, 1, -                                   GL_RGBA, CHAN_TYPE, image, -                                   &ctx->DefaultPacking, texObj, texImage); +      ctx->Driver.TexSubImage3D(ctx, target, level, +                                xoffset, yoffset, zoffset, width, height, 1, +                                GL_RGBA, CHAN_TYPE, image, +                                &ctx->DefaultPacking, texObj, texImage);        _mesa_free(image);     } | 
