nv40: Better teximage layout, probably not 100% correct still.

Gallium represents image layout by saying that each mipmap level has a number
of "face" images within it.  However, nv40 represents them as "faces" that
have a number of mipmap levels.  I'm not sure if the gallium representation
allows this, but I've made an attempt to match it as closely as possible.

CUBE/3D textures with mipmaps are probably broken, but untested currently.
This commit is contained in:
Ben Skeggs 2007-11-21 19:20:38 +11:00
parent af1a388939
commit ff7edad077
2 changed files with 40 additions and 31 deletions

View file

@ -8,53 +8,60 @@ boolean
nv40_miptree_layout(struct pipe_context *pipe, struct pipe_mipmap_tree *mt)
{
struct nv40_context *nv40 = (struct nv40_context *)pipe;
uint width, height, depth, offset;
boolean swizzled = FALSE;
int l;
uint width = mt->width0, height = mt->height0, depth = mt->depth0;
uint offset;
int nr_faces, l, f;
mt->pitch = mt->width0;
mt->total_height = 0;
width = mt->width0;
height = mt->height0;
depth = mt->depth0;
offset = 0;
for (l = mt->first_level; l <= mt->last_level; l++) {
uint pitch, f;
if (mt->target == PIPE_TEXTURE_CUBE) {
nr_faces = 6;
} else
if (mt->target == PIPE_TEXTURE_3D) {
nr_faces = mt->depth0;
} else {
nr_faces = 1;
}
for (l = mt->first_level; l <= mt->last_level; l++) {
mt->level[l].width = width;
mt->level[l].height = height;
mt->level[l].depth = depth;
mt->level[l].level_offset = offset;
mt->level[l].level_offset = 0;
if (!swizzled)
pitch = mt->width0;
else
pitch = width;
if (mt->target == PIPE_TEXTURE_CUBE)
mt->level[l].nr_images = 6;
else
if (mt->target == PIPE_TEXTURE_3D)
mt->level[l].nr_images = mt->level[l].depth;
else
mt->level[l].nr_images = 1;
mt->level[l].image_offset =
malloc(mt->level[l].nr_images * sizeof(unsigned));
for (f = 0; f < mt->level[l].nr_images; f++) {
mt->level[l].image_offset[f] =
(offset - mt->level[l].level_offset) / mt->cpp;
mt->level[l].nr_images = nr_faces;
mt->level[l].image_offset = malloc(nr_faces * sizeof(unsigned));
for (f = 0; f < nr_faces; f++)
mt->total_height += height;
offset += (pitch * mt->cpp * height);
}
width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);
}
offset = 0;
for (f = 0; f < nr_faces; f++) {
for (l = mt->first_level; l <= mt->last_level; l++) {
if (f == 0) {
mt->level[l].level_offset = offset;
}
uint pitch;
if (swizzled)
pitch = mt->level[l].width * mt->cpp;
else
pitch = mt->width0 * mt->cpp;
pitch = (pitch + 63) & ~63;
mt->level[l].image_offset[f] =
(offset - mt->level[l].level_offset) / mt->cpp;
offset += pitch * mt->level[l].height;
}
}
return TRUE;
}

View file

@ -75,8 +75,10 @@ nv40_tex_unit_enable(struct nv40_context *nv40, int unit)
txf |= NV40TCL_TEX_FORMAT_NO_BORDER;
switch (mt->target) {
case PIPE_TEXTURE_2D:
case PIPE_TEXTURE_CUBE:
txf |= NV40TCL_TEX_FORMAT_CUBIC;
/* fall-through */
case PIPE_TEXTURE_2D:
txf |= NV40TCL_TEX_FORMAT_DIMS_2D;
break;
case PIPE_TEXTURE_3D: