#include "macros.h"
+static int align(int value, int alignment)
+{
+ return (value + alignment - 1) & ~(alignment - 1);
+}
+
void i945_miptree_layout_2d( struct intel_mipmap_tree *mt )
{
- GLint align_h = 2;
+ GLint align_h = 2, align_w = 4;
GLuint level;
GLuint x = 0;
GLuint y = 0;
GLuint width = mt->width0;
GLuint height = mt->height0;
- mt->pitch = ((mt->width0 * mt->cpp + 3) & ~3) / mt->cpp;
+ mt->pitch = mt->width0;
+
+ /* 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));
+
+ if (mip1_width > mt->width0)
+ mt->pitch = mip1_width;
+ }
+
+ /* Pitch must be a whole number of dwords, even though we
+ * express it in texels.
+ */
+ mt->pitch = align(mt->pitch * mt->cpp, 4) / mt->cpp;
mt->total_height = 0;
for ( level = mt->first_level ; level <= mt->last_level ; level++ ) {
if (mt->compressed)
img_height = MAX2(1, height/4);
else
- img_height = MAX2(align_h, height);
+ img_height = align(height, align_h);
/* Because the images are packed better, the final offset
/* Layout_below: step right after second mipmap.
*/
if (level == mt->first_level + 1) {
- x += mt->pitch / 2;
- x = (x + 3) & ~ 3;
+ x += align(width, align_w);
}
else {
y += img_height;
- y += align_h - 1;
- y &= ~(align_h - 1);
}
width = minify(width);