nv50: fix handling of depth textures
authorBen Skeggs <skeggsb@gmail.com>
Mon, 12 Jan 2009 06:32:49 +0000 (16:32 +1000)
committerBen Skeggs <skeggsb@gmail.com>
Mon, 12 Jan 2009 06:59:35 +0000 (16:59 +1000)
src/gallium/drivers/nv50/nv50_context.h
src/gallium/drivers/nv50/nv50_miptree.c

index a1a6b2cb887c91b5ef9a53b590e4c8b957abff42..061a4c064b62bc843d88ba9595a8b4b795a35805 100644 (file)
@@ -70,8 +70,8 @@ struct nv50_rasterizer_stateobj {
 struct nv50_miptree_level {
        struct pipe_buffer **image;
        int *image_offset;
-       unsigned image_dirty_cpu;
-       unsigned image_dirty_gpu;
+       unsigned image_dirty_cpu[512/32];
+       unsigned image_dirty_gpu[512/32];
 };
 
 struct nv50_miptree {
@@ -192,4 +192,8 @@ extern boolean nv50_state_validate(struct nv50_context *nv50);
 /* nv50_tex.c */
 extern void nv50_tex_validate(struct nv50_context *);
 
+/* nv50_miptree.c */
+extern void nv50_miptree_sync(struct pipe_screen *, struct nv50_miptree *,
+                             unsigned level, unsigned image);
+
 #endif
index 3c10a4ff745d32bc0cc095b7ea20eff21d8819ec..f25922784e3b23df7efacabcbdbe6be7014daad0 100644 (file)
@@ -104,6 +104,24 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
        return &mt->base;
 }
 
+static INLINE void
+mark_dirty(uint32_t *flags, unsigned image)
+{
+       flags[image / 32] |= (1 << (image % 32));
+}
+
+static INLINE void
+mark_clean(uint32_t *flags, unsigned image)
+{
+       flags[image / 32] &= ~(1 << (image % 32));
+}
+
+static INLINE int
+is_dirty(uint32_t *flags, unsigned image)
+{
+       return !!(flags[image / 32] & (1 << (image % 32)));
+}
+
 static void
 nv50_miptree_release(struct pipe_screen *pscreen, struct pipe_texture **ppt)
 {
@@ -128,7 +146,7 @@ nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt,
        struct pipe_surface *dst, *src;
        unsigned face = 0, zslice = 0;
 
-       if (!(lvl->image_dirty_cpu & (1 << image)))
+       if (!is_dirty(lvl->image_dirty_cpu, image))
                return;
 
        if (mt->base.target == PIPE_TEXTURE_CUBE)
@@ -140,7 +158,7 @@ nv50_miptree_sync(struct pipe_screen *pscreen, struct nv50_miptree *mt,
        /* Mark as clean already - so we don't continually call this function
         * trying to get a GPU_WRITE pipe_surface!
         */
-       lvl->image_dirty_cpu &= ~(1 << image);
+       mark_clean(lvl->image_dirty_cpu, image);
 
        /* Pretend we're doing CPU access so we get the backing pipe_surface
         * and not a view into the larger miptree.
@@ -198,14 +216,14 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
 
        if (flags & PIPE_BUFFER_USAGE_CPU_READ_WRITE) {
                assert(!(flags & PIPE_BUFFER_USAGE_GPU_READ_WRITE));
-               assert(!(lvl->image_dirty_gpu & (1 << img)));
+               assert(!is_dirty(lvl->image_dirty_gpu, img));
 
                ps->offset = 0;
                pipe_texture_reference(&ps->texture, pt);
                pipe_buffer_reference(pscreen, &ps->buffer, lvl->image[img]);
 
                if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
-                       lvl->image_dirty_cpu |= (1 << img);
+                       mark_dirty(lvl->image_dirty_cpu, img);
        } else {
                nv50_miptree_sync(pscreen, mt, level, img);
 
@@ -214,7 +232,7 @@ nv50_miptree_surface_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
                pipe_buffer_reference(pscreen, &ps->buffer, mt->buffer);
 
                if (flags & PIPE_BUFFER_USAGE_GPU_WRITE)
-                       lvl->image_dirty_gpu |= (1 << img);
+                       mark_dirty(lvl->image_dirty_gpu, img);
        }
 
        return ps;