[Mesa-dev] [PATCH 05/37] meta: added _mesa_meta_decompress_texture_image()

Brian Paul brian.e.paul at gmail.com
Mon Aug 15 15:05:51 PDT 2011


On Mon, Aug 15, 2011 at 3:43 PM, Ian Romanick <idr at freedesktop.org> wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 08/15/2011 11:53 AM, Eric Anholt wrote:
>> From: Brian Paul <brianp at vmware.com>
>>
>> Decompress a texture by drawing quad with the texture.
>> ---
>>  src/mesa/drivers/common/meta.c |  200 ++++++++++++++++++++++++++++++++++++++++
>>  src/mesa/drivers/common/meta.h |    6 +
>>  2 files changed, 206 insertions(+), 0 deletions(-)
>>
>> diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
>> index 19eae42..751f3b6 100644
>> --- a/src/mesa/drivers/common/meta.c
>> +++ b/src/mesa/drivers/common/meta.c
>> @@ -287,6 +287,19 @@ struct gen_mipmap_state
>>     GLuint FBO;
>>  };
>>
>> +
>> +/**
>> + * State for texture decompression
>> + */
>> +struct decompress_state
>> +{
>> +   GLuint ArrayObj;
>> +   GLuint VBO, FBO, RBO;
>> +   GLint Width, Height;
>> +   GLenum RBFormat;
>> +};
>> +
>> +
>>  #define MAX_META_OPS_DEPTH      2
>>  /**
>>   * All per-context meta state.
>> @@ -306,6 +319,7 @@ struct gl_meta_state
>>     struct drawpix_state DrawPix;  /**< For _mesa_meta_DrawPixels() */
>>     struct bitmap_state Bitmap;    /**< For _mesa_meta_Bitmap() */
>>     struct gen_mipmap_state Mipmap;    /**< For _mesa_meta_GenerateMipmap() */
>> +   struct decompress_state Decompress;  /**< For texture decompression */
>>  };
>>
>>
>> @@ -3094,3 +3108,189 @@ _mesa_meta_CopyColorSubTable(struct gl_context *ctx,GLenum target, GLsizei start
>>
>>     free(buf);
>>  }
>> +
>> +
>> +/**
>> + * Decompress a texture image by drawing a quad with the compressed
>> + * texture and reading the pixels out of the color buffer.
>> + * \param slice  which slice of a 3D texture or layer of a 1D/2D texture
>> + * \param destFormat  format, ala glReadPixels
>> + * \param destType  type, ala glReadPixels
>> + * \param dest  destination buffer
>> + * \param destRowLength  dest image rowLength (ala GL_PACK_ROW_LENGTH)
>> + */
>> +void
>> +_mesa_meta_decompress_texture_image(struct gl_context *ctx,
>> +                                    struct gl_texture_image *texImage,
>> +                                    GLuint slice,
>> +                                    GLenum destFormat, GLenum destType,
>> +                                    GLvoid *dest, GLint destRowLength)
>> +{
>> +   struct decompress_state *decompress = &ctx->Meta->Decompress;
>> +   struct gl_texture_object *texObj = texImage->TexObject;
>> +   const GLint width = texImage->Width;
>> +   const GLint height = texImage->Height;
>> +   const GLenum target = texObj->Target;
>> +   GLenum faceTarget, rbFormat;
>> +   struct vertex {
>> +      GLfloat x, y, tex[3];
>> +   };
>> +   struct vertex verts[4];
>> +   GLuint fboDrawSave, fboReadSave;
>> +   GLenum destDataType = _mesa_get_format_datatype(texImage->TexFormat);
>> +
>> +   if (slice > 0) {
>> +      assert(target == GL_TEXTURE_3D ||
>> +             target == GL_TEXTURE_2D_ARRAY);
>> +   }
>> +
>> +   if (target == GL_TEXTURE_CUBE_MAP) {
>> +      faceTarget = GL_TEXTURE_CUBE_MAP_POSITIVE_X + texImage->Face;
>> +   }
>> +   else {
>> +      faceTarget = target;
>> +   }
>> +
>> +   /* save fbo bindings (not saved by _mesa_meta_begin()) */
>> +   fboDrawSave = ctx->DrawBuffer->Name;
>> +   fboReadSave = ctx->ReadBuffer->Name;
>> +
>> +   _mesa_meta_begin(ctx, META_ALL);
>> +
>> +   /* Create/bind FBO/renderbuffer */
>> +   if (decompress->FBO == 0) {
>> +      _mesa_GenFramebuffersEXT(1, &decompress->FBO);
>> +      _mesa_GenRenderbuffersEXT(1, &decompress->RBO);
>> +      _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO);
>> +      _mesa_BindRenderbufferEXT(GL_RENDERBUFFER_EXT, decompress->RBO);
>> +      _mesa_FramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
>> +                                       GL_COLOR_ATTACHMENT0_EXT,
>> +                                       GL_RENDERBUFFER_EXT,
>> +                                       decompress->RBO);
>> +   }
>> +   else {
>> +      _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, decompress->FBO);
>> +   }
>> +
>> +   if (destDataType == GL_SIGNED_NORMALIZED) {
>> +      rbFormat = GL_RGBA32F;
>> +   } else {
>> +      rbFormat = GL_RGBA;
>> +   }
>
> This bit seems odd.  Is GL_RGBA32F the right choice?  Won't this fail on
> hardware that can do SIGNED_NORMALIZED but not float rendering?

That bit wasn't in my original patch series.  I'm not sure if it's
even legal to do a glGetTexImage() of a compressed texture and get
back signed normalized values.  I'd have to do some digging through
specs.

-Brian


More information about the mesa-dev mailing list