diff options
-rw-r--r-- | src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c | 9 | ||||
-rw-r--r-- | src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 16 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.c | 38 | ||||
-rw-r--r-- | src/mesa/drivers/dri/intel/intel_tex_layout.h | 1 |
4 files changed, 55 insertions, 9 deletions
diff --git a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c index 843a78eb82..fc38a28290 100644 --- a/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i915tex/intel_mipmap_tree.c @@ -325,6 +325,7 @@ intel_miptree_image_data(struct intel_context *intel, } } +extern GLuint intel_compressed_alignment(GLenum); /* Copy mipmap image between trees */ void @@ -342,8 +343,12 @@ 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; + if (dst->compressed) { + GLuint alignment = intel_compressed_alignment(dst->internal_format); + height = (height + 3) / 4; + width = ((width + alignment - 1) & ~(alignment - 1)); + } + 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/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index d7b1946ce3..f24f234682 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -211,7 +211,7 @@ GLuint intel_miptree_image_offset(struct intel_mipmap_tree *mt, - +extern GLuint intel_compressed_alignment(GLenum); /* Upload data for a particular image. */ GLboolean intel_miptree_image_data(struct intel_context *intel, @@ -226,6 +226,16 @@ GLboolean 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 width, height, alignment; + + width = dst->level[level].width; + height = dst->level[level].height; + + if (dst->compressed) { + alignment = intel_compressed_alignment(dst->internal_format); + width = ((width + alignment - 1) & ~(alignment - 1)); + height = (height + 3) / 4; + } DBG("%s\n", __FUNCTION__); for (i = 0; i < depth; i++) { @@ -237,8 +247,8 @@ GLboolean intel_miptree_image_data(struct intel_context *intel, src, src_row_pitch, 0, 0, /* source x,y */ - dst->level[level].width, - dst->level[level].height)) + width, + height)) return GL_FALSE; src += src_image_pitch; } diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index fcb5cc3906..fdecd3e186 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -40,6 +40,23 @@ static int align(int value, int alignment) return (value + alignment - 1) & ~(alignment - 1); } +GLuint intel_compressed_alignment(GLenum internalFormat) +{ + GLuint alignment = 4; + + switch (internalFormat) { + case GL_COMPRESSED_RGB_FXT1_3DFX: + case GL_COMPRESSED_RGBA_FXT1_3DFX: + alignment = 8; + break; + + default: + break; + } + + return alignment; +} + void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) { GLint align_h = 2, align_w = 4; @@ -51,17 +68,30 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) mt->pitch = mt->width0; + if (mt->compressed) { + align_w = intel_compressed_alignment(mt->internal_format); + mt->pitch = align(mt->width0, align_w); + } + /* May need to adjust pitch to accomodate the placement of * the 2nd mipmap. This occurs when the alignment * constraints of mipmap placement push the right edge of the * 2nd mipmap out past the width of its parent. */ if (mt->first_level != mt->last_level) { - GLuint mip1_width = align(minify(mt->width0), align_w) - + minify(minify(mt->width0)); + GLuint mip1_width; + + if (mt->compressed) { + mip1_width = align(minify(mt->width0), align_w) + + align(minify(minify(mt->width0)), align_w); + } else { + mip1_width = align(minify(mt->width0), align_w) + + minify(minify(mt->width0)); + } - if (mip1_width > mt->width0) - mt->pitch = mip1_width; + if (mip1_width > mt->pitch) { + mt->pitch = mip1_width; + } } /* Pitch must be a whole number of dwords, even though we diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.h b/src/mesa/drivers/dri/intel/intel_tex_layout.h index 1e37f8f525..99d41c3629 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.h +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.h @@ -39,3 +39,4 @@ static GLuint minify( GLuint d ) } extern void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ); +extern GLuint intel_compressed_alignment(GLenum); |