nv50: some mipmapping fixes
authorBen Skeggs <bskeggs@redhat.com>
Thu, 28 May 2009 05:47:54 +0000 (15:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 28 May 2009 06:06:25 +0000 (16:06 +1000)
src/gallium/drivers/nv50/nv50_state.c
src/gallium/drivers/nv50/nv50_surface.c
src/gallium/drivers/nv50/nv50_tex.c
src/gallium/drivers/nv50/nv50_transfer.c

index ba852194cddde7f6e5b417d566a722c27e1a2f59..9d41ef55b0f649f8eebccb69e6d4871308089ba2 100644 (file)
@@ -137,8 +137,9 @@ nv50_sampler_state_create(struct pipe_context *pipe,
                          const struct pipe_sampler_state *cso)
 {
        unsigned *tsc = CALLOC(8, sizeof(unsigned));
+       float limit;
 
-       tsc[0] = (0x00024000 |
+       tsc[0] = (0x00026000 |
                  (wrap_mode(cso->wrap_s) << 0) |
                  (wrap_mode(cso->wrap_t) << 3) |
                  (wrap_mode(cso->wrap_r) << 6));
@@ -202,6 +203,12 @@ nv50_sampler_state_create(struct pipe_context *pipe,
                tsc[0] |= (nvgl_comparison_op(cso->compare_func) & 0x7);
        }
 
+       limit = CLAMP(cso->lod_bias, -16.0, 15.0);
+       tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11;
+
+       tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) |
+                 ((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8);
+
        return (void *)tsc;
 }
 
index 0cc5168144d644923ed6e3da7978e5e7135206ab..c0f0efe158bdb51fe513aec28640d5013c4bb70a 100644 (file)
@@ -57,7 +57,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
        struct nouveau_bo *bo;
        int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
        int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
+
        bo = screen->nvws->get_bo(nv50_miptree(ps->texture)->buffer);
        if (!bo)
                return 1;
index 223c8a3a456197bf04931e817c6ba0b1470456e2..775e9f30ef3ee6f1e88848fa6f478cb9d218504c 100644 (file)
@@ -122,10 +122,10 @@ nv50_tex_construct(struct nouveau_stateobj *so, struct nv50_miptree *mt)
        so_data (so, 0xd0005000);
        so_data (so, 0x00300000);
        so_data (so, mt->base.width[0]);
-       so_data (so, (mt->base.depth[0] << 16) | mt->base.height[0]);
+       so_data (so, (mt->base.last_level << 28) |
+                    (mt->base.depth[0] << 16) | mt->base.height[0]);
        so_data (so, 0x03000000);
-       so_reloc(so, mt->buffer, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_HIGH |
-                    NOUVEAU_BO_RD, 0, 0);
+       so_data (so, mt->base.last_level << 4);
 
        return 0;
 }
index 747195b4f6370555c6cecafee36b8c63e4c5f8f9..28e7edd144a2ab2e5201f16c545af94a37783c95 100644 (file)
@@ -7,7 +7,7 @@
 struct nv50_transfer {
        struct pipe_transfer base;
        struct pipe_buffer *buffer;
-       struct nv50_miptree_level *level;
+       unsigned level_offset;
        int level_pitch;
        int level_width;
        int level_height;
@@ -17,8 +17,9 @@ struct nv50_transfer {
 
 static void
 nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
-                       int src_pitch, int sx, int sy, int sw, int sh,
-                       struct pipe_buffer *dst, int dst_pitch, int dx, int dy,
+                       unsigned src_offset, int src_pitch, int sx, int sy,
+                       int sw, int sh, struct pipe_buffer *dst,
+                       unsigned dst_offset, int dst_pitch, int dx, int dy,
                        int dw, int dh, int cpp, int width, int height,
                        unsigned src_reloc, unsigned dst_reloc)
 {
@@ -28,7 +29,6 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
        struct nouveau_grobj *m2mf = screen->m2mf;
        struct nouveau_bo *src_bo = nvws->get_bo(src);
        struct nouveau_bo *dst_bo = nvws->get_bo(dst);
-       unsigned src_offset = 0, dst_offset = 0;
 
        src_reloc |= NOUVEAU_BO_RD;
        dst_reloc |= NOUVEAU_BO_WR;
@@ -40,7 +40,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
                OUT_RING  (chan, 1);
                BEGIN_RING(chan, m2mf, 0x0314, 1);
                OUT_RING  (chan, src_pitch);
-               src_offset = (sy * src_pitch) + (sx * cpp);
+               src_offset += (sy * src_pitch) + (sx * cpp);
        } else {
                BEGIN_RING(chan, m2mf, 0x0200, 6);
                OUT_RING  (chan, 0);
@@ -56,7 +56,7 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct pipe_buffer *src,
                OUT_RING  (chan, 1);
                BEGIN_RING(chan, m2mf, 0x0318, 1);
                OUT_RING  (chan, dst_pitch);
-               dst_offset = (dy * dst_pitch) + (dx * cpp);
+               dst_offset += (dy * dst_pitch) + (dx * cpp);
        } else {
                BEGIN_RING(chan, m2mf, 0x021c, 6);
                OUT_RING  (chan, 0);
@@ -133,10 +133,10 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
        tx->base.stride = (w * pt->block.size);
        tx->base.usage = usage;
 
-       tx->level = lvl;
        tx->level_pitch = lvl->pitch;
        tx->level_width = mt->base.width[level];
        tx->level_height = mt->base.height[level];
+       tx->level_offset = lvl->image_offset[image];
        tx->level_x = x;
        tx->level_y = y;
        tx->buffer =
@@ -144,9 +144,10 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
                                   w * tx->base.block.size * h);
 
        if (usage != PIPE_TRANSFER_WRITE) {
-               nv50_transfer_rect_m2mf(pscreen, mt->buffer, tx->level_pitch,
-                                       x, y, tx->level_width, tx->level_height,
-                                       tx->buffer, tx->base.stride, 0, 0,
+               nv50_transfer_rect_m2mf(pscreen, mt->buffer, tx->level_offset,
+                                       tx->level_pitch, x, y, tx->level_width,
+                                       tx->level_height, tx->buffer, 0,
+                                       tx->base.stride, 0, 0,
                                        tx->base.width, tx->base.height,
                                        tx->base.block.size, w, h,
                                        NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
@@ -164,14 +165,15 @@ nv50_transfer_del(struct pipe_transfer *ptx)
 
        if (ptx->usage != PIPE_TRANSFER_READ) {
                struct pipe_screen *pscreen = ptx->texture->screen;
-               nv50_transfer_rect_m2mf(pscreen, tx->buffer, tx->base.stride,
+               nv50_transfer_rect_m2mf(pscreen, tx->buffer, 0, tx->base.stride,
                                        0, 0, tx->base.width, tx->base.height,
-                                       mt->buffer, tx->level_pitch,
-                                       tx->level_x, tx->level_y,
-                                       tx->level_width, tx->level_height,
-                                       tx->base.block.size, tx->base.width,
-                                       tx->base.height, NOUVEAU_BO_GART,
-                                       NOUVEAU_BO_VRAM | NOUVEAU_BO_GART);
+                                       mt->buffer, tx->level_offset,
+                                       tx->level_pitch, tx->level_x,
+                                       tx->level_y, tx->level_width,
+                                       tx->level_height, tx->base.block.size,
+                                       tx->base.width, tx->base.height,
+                                       NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
+                                       NOUVEAU_BO_GART);
        }
 
        pipe_buffer_reference(&tx->buffer, NULL);