From 28623163098a92bf43af882fbc63e9ce9f910a26 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Fri, 10 Nov 2006 00:32:35 +0000 Subject: Fix up texture compression at least Get and TexImage, not too sure about how to fix SubTexImage with compressed textures --- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 14 ++- src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h | 2 +- src/mesa/drivers/dri/i915tex/intel_tex.c | 5 + src/mesa/drivers/dri/i915tex/intel_tex.h | 14 +++ src/mesa/drivers/dri/i915tex/intel_tex_format.c | 22 ++++ src/mesa/drivers/dri/i915tex/intel_tex_image.c | 129 ++++++++++++++++------ src/mesa/drivers/dri/i915tex/intel_tex_validate.c | 6 +- 7 files changed, 151 insertions(+), 41 deletions(-) (limited to 'src/mesa/drivers/dri') diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index 2ebe3ae14e..2b1077aee0 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -56,7 +56,7 @@ intel_miptree_create(struct intel_context *intel, GLuint last_level, GLuint width0, GLuint height0, - GLuint depth0, GLuint cpp, GLboolean compressed) + GLuint depth0, GLuint cpp, GLuint compress_byte) { GLboolean ok; struct intel_mipmap_tree *mt = calloc(sizeof(*mt), 1); @@ -72,8 +72,8 @@ intel_miptree_create(struct intel_context *intel, mt->width0 = width0; mt->height0 = height0; mt->depth0 = depth0; - mt->cpp = compressed ? 2 : cpp; - mt->compressed = compressed; + mt->cpp = compress_byte ? compress_byte : cpp; + mt->compressed = compress_byte ? 1 : 0; mt->refcount = 1; switch (intel->intelScreen->deviceID) { @@ -302,11 +302,15 @@ intel_miptree_image_data(struct intel_context *intel, GLuint dst_offset = intel_miptree_image_offset(dst, face, level); const GLuint *dst_depth_offset = intel_miptree_depth_offsets(dst, level); GLuint i; + GLuint height = 0; DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { + height = dst->level[level].height; + if(dst->compressed) + height /= 4; intel_region_data(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], 0, 0, src, src_row_pitch, 0, 0, /* source x,y */ - dst->level[level].width, dst->level[level].height); + dst->level[level].width, height); src += src_image_pitch; } @@ -329,6 +333,8 @@ intel_miptree_image_copy(struct intel_context *intel, const GLuint *src_depth_offset = intel_miptree_depth_offsets(src, level); GLuint i; + if (dst->compressed) + height /= 4; for (i = 0; i < depth; i++) { intel_region_copy(intel->intelScreen, dst->region, dst_offset + dst_depth_offset[i], diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h index e6dd5bb600..ecdb7be244 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.h @@ -121,7 +121,7 @@ struct intel_mipmap_tree *intel_miptree_create(struct intel_context *intel, GLuint height0, GLuint depth0, GLuint cpp, - GLboolean compressed); + GLuint compress_byte); void intel_miptree_reference(struct intel_mipmap_tree **dst, struct intel_mipmap_tree *src); diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.c b/src/mesa/drivers/dri/i915tex/intel_tex.c index 8046c29d95..b08dee43bc 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex.c @@ -171,6 +171,11 @@ intelInitTextureFuncs(struct dd_function_table *functions) functions->CopyTexSubImage1D = intelCopyTexSubImage1D; functions->CopyTexSubImage2D = intelCopyTexSubImage2D; functions->GetTexImage = intelGetTexImage; + + /* compressed texture functions */ + functions->CompressedTexImage2D = intelCompressedTexImage2D; + functions->GetCompressedTexImage = intelGetCompressedTexImage; + functions->NewTextureObject = intelNewTextureObject; functions->NewTextureImage = intelNewTextureImage; functions->DeleteTexture = intelDeleteTextureObject; diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h index 2f3d4ec2d1..6e9938fe53 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex.h +++ b/src/mesa/drivers/dri/i915tex/intel_tex.h @@ -123,6 +123,18 @@ void intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, struct gl_texture_object *texObj, struct gl_texture_image *texImage); +void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ); + +void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage); + GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); void intel_tex_map_images(struct intel_context *intel, @@ -131,4 +143,6 @@ void intel_tex_map_images(struct intel_context *intel, void intel_tex_unmap_images(struct intel_context *intel, struct intel_texture_object *intelObj); +int intel_compressed_num_bytes(GLuint mesaFormat); + #endif diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_format.c b/src/mesa/drivers/dri/i915tex/intel_tex_format.c index 33281295dc..6e058dff69 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_format.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_format.c @@ -148,3 +148,25 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat, return NULL; /* never get here */ } + +int intel_compressed_num_bytes(GLuint mesaFormat) +{ + int bytes = 0; + switch(mesaFormat) { + + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + bytes = 2; + break; + + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_RGBA_DXT5: + bytes = 4; + default: + break; + } + + return bytes; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c index 48c2f35d3b..79f377a4b7 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -69,7 +69,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, GLuint height = intelImage->base.Height; GLuint depth = intelImage->base.Depth; GLuint l2width, l2height, l2depth; - GLuint i; + GLuint i, comp_byte = 0; DBG("%s\n", __FUNCTION__); @@ -121,6 +121,8 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, } assert(!intelObj->mt); + if (intelImage->base.IsCompressed) + comp_byte = intel_compressed_num_bytes(intelImage->base.TexFormat->MesaFormat); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, intelImage->base.InternalFormat, @@ -130,7 +132,7 @@ guess_and_alloc_mipmap_tree(struct intel_context *intel, height, depth, intelImage->base.TexFormat->TexelBytes, - intelImage->base.IsCompressed); + comp_byte); DBG("%s - success\n", __FUNCTION__); } @@ -298,7 +300,7 @@ intelTexImage(GLcontext * ctx, GLenum format, GLenum type, const void *pixels, const struct gl_pixelstore_attrib *unpack, struct gl_texture_object *texObj, - struct gl_texture_image *texImage) + struct gl_texture_image *texImage, GLsizei imageSize, int compressed) { struct intel_context *intel = intel_context(ctx); struct intel_texture_object *intelObj = intel_texture_object(texObj); @@ -346,17 +348,26 @@ intelTexImage(GLcontext * ctx, break; } - texelBytes = texImage->TexFormat->TexelBytes; - - - /* Minimum pitch of 32 bytes */ - if (postConvWidth * texelBytes < 32) { - postConvWidth = 32 / texelBytes; - texImage->RowStride = postConvWidth; + if (texImage->TexFormat->TexelBytes == 0) { + /* must be a compressed format */ + texelBytes = 0; + texImage->IsCompressed = GL_TRUE; + texImage->CompressedSize = + ctx->Driver.CompressedTextureSize(ctx, texImage->Width, + texImage->Height, texImage->Depth, + texImage->TexFormat->MesaFormat); + } else { + texelBytes = texImage->TexFormat->TexelBytes; + + /* Minimum pitch of 32 bytes */ + if (postConvWidth * texelBytes < 32) { + postConvWidth = 32 / texelBytes; + texImage->RowStride = postConvWidth; + } + + assert(texImage->RowStride == postConvWidth); } - assert(texImage->RowStride == postConvWidth); - /* Release the reference to a potentially orphaned buffer. * Release any old malloced memory. */ @@ -453,9 +464,15 @@ intelTexImage(GLcontext * ctx, * the expectation that the mipmap tree will be set up but nothing * more will be done. This is where those calls return: */ - pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, - format, type, - pixels, unpack, "glTexImage"); + if (compressed) { + pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, pixels, + unpack, + "glCompressedTexImage"); + } else { + pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, 1, + format, type, + pixels, unpack, "glTexImage"); + } if (!pixels) return; @@ -478,7 +495,7 @@ intelTexImage(GLcontext * ctx, if (texImage->IsCompressed) { sizeInBytes = texImage->CompressedSize; dstRowStride = - _mesa_compressed_row_stride(texImage->InternalFormat, width); + _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width); assert(dims != 3); } else { @@ -497,14 +514,16 @@ intelTexImage(GLcontext * ctx, * the blitter to copy. Or, use the hardware to do the format * conversion and copy: */ - if (!texImage->TexFormat->StoreImage(ctx, dims, - texImage->_BaseFormat, - texImage->TexFormat, - texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ - dstRowStride, - texImage->ImageOffsets, - width, height, depth, - format, type, pixels, unpack)) { + if (compressed) { + memcpy(texImage->Data, pixels, imageSize); + } else if (!texImage->TexFormat->StoreImage(ctx, dims, + texImage->_BaseFormat, + texImage->TexFormat, + texImage->Data, 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + texImage->ImageOffsets, + width, height, depth, + format, type, pixels, unpack)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage"); } @@ -541,7 +560,7 @@ intelTexImage3D(GLcontext * ctx, { intelTexImage(ctx, 3, target, level, internalFormat, width, height, depth, border, - format, type, pixels, unpack, texObj, texImage); + format, type, pixels, unpack, texObj, texImage, 0, 0); } @@ -557,7 +576,7 @@ intelTexImage2D(GLcontext * ctx, { intelTexImage(ctx, 2, target, level, internalFormat, width, height, 1, border, - format, type, pixels, unpack, texObj, texImage); + format, type, pixels, unpack, texObj, texImage, 0, 0); } void @@ -572,20 +591,30 @@ intelTexImage1D(GLcontext * ctx, { intelTexImage(ctx, 1, target, level, internalFormat, width, 1, 1, border, - format, type, pixels, unpack, texObj, texImage); + format, type, pixels, unpack, texObj, texImage, 0, 0); } - +void intelCompressedTexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + intelTexImage(ctx, 2, target, level, + internalFormat, width, height, 1, border, + 0, 0, data, &ctx->Unpack, texObj, texImage, imageSize, 1); +} /** * Need to map texture image into memory before copying image data, * then unmap it. */ -void -intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid * pixels, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage) +static void +intel_get_tex_image(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage, int compressed) { struct intel_context *intel = intel_context(ctx); struct intel_texture_image *intelImage = intel_texture_image(texImage); @@ -615,8 +644,15 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, assert(intelImage->base.Data); } - _mesa_get_teximage(ctx, target, level, format, type, pixels, - texObj, texImage); + + if (compressed) { + _mesa_get_compressed_teximage(ctx, target, level, pixels, + texObj, texImage); + } else { + _mesa_get_teximage(ctx, target, level, format, type, pixels, + texObj, texImage); + } + /* Unmap */ if (intelImage->mt) { @@ -624,3 +660,26 @@ intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, intelImage->base.Data = NULL; } } + +void +intelGetTexImage(GLcontext * ctx, GLenum target, GLint level, + GLenum format, GLenum type, GLvoid * pixels, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + intel_get_tex_image(ctx, target, level, format, type, pixels, + texObj, texImage, 0); + + +} + +void +intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, + GLvoid *pixels, + const struct gl_texture_object *texObj, + const struct gl_texture_image *texImage) +{ + intel_get_tex_image(ctx, target, level, 0, 0, pixels, + texObj, texImage, 1); + +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index e273716b09..5f82dfa19e 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -165,6 +165,10 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) /* May need to create a new tree: */ if (!intelObj->mt) { + int comp_byte = 0; + + if (firstImage->base.IsCompressed) + comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->base.InternalFormat, @@ -175,7 +179,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) firstImage->base.Depth, firstImage->base.TexFormat-> TexelBytes, - firstImage->base.IsCompressed); + comp_byte); } /* Pull in any images not in the object's tree: -- cgit v1.2.3