summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Skeggs <skeggsb@gmail.com>2007-11-21 19:20:38 +1100
committerBen Skeggs <skeggsb@gmail.com>2007-11-21 19:20:38 +1100
commitff7edad0776603aa62b8f684db20c84bde75ea0b (patch)
treeaec9ae47780ab491c4778c3ad4d902e1ec97de6e /src
parentaf1a38893946cf2fabd0fc6956efd07ef15b954b (diff)
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.
Diffstat (limited to 'src')
-rw-r--r--src/mesa/pipe/nv40/nv40_miptree.c69
-rw-r--r--src/mesa/pipe/nv40/nv40_state_tex.c4
2 files changed, 41 insertions, 32 deletions
diff --git a/src/mesa/pipe/nv40/nv40_miptree.c b/src/mesa/pipe/nv40/nv40_miptree.c
index 2d8ef8ced7..15639f01e9 100644
--- a/src/mesa/pipe/nv40/nv40_miptree.c
+++ b/src/mesa/pipe/nv40/nv40_miptree.c
@@ -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;
-
- 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->total_height += height;
+ mt->level[l].level_offset = 0;
- offset += (pitch * mt->cpp * height);
- }
+ 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;
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;
}
diff --git a/src/mesa/pipe/nv40/nv40_state_tex.c b/src/mesa/pipe/nv40/nv40_state_tex.c
index cf2a7a9fe0..bd779df9b3 100644
--- a/src/mesa/pipe/nv40/nv40_state_tex.c
+++ b/src/mesa/pipe/nv40/nv40_state_tex.c
@@ -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: