nvfx: fix the temporary copying logic and add asserts
authorLuca Barbieri <luca@luca-barbieri.com>
Sat, 4 Sep 2010 18:17:39 +0000 (20:17 +0200)
committerLuca Barbieri <luca@luca-barbieri.com>
Sat, 4 Sep 2010 20:45:21 +0000 (22:45 +0200)
src/gallium/drivers/nvfx/nvfx_miptree.c
src/gallium/drivers/nvfx/nvfx_state_emit.c
src/gallium/drivers/nvfx/nvfx_surface.c

index 0916aaa..7677fde 100644 (file)
@@ -214,6 +214,7 @@ nvfx_miptree_surface_del(struct pipe_surface *ps)
 
        if(!ns->temp)
        {
+               assert(!util_dirty_surface_is_dirty(&ns->base));
                util_surfaces_detach(&((struct nvfx_miptree*)ps->texture)->surfaces, ps);
                pipe_resource_reference(&ps->texture, 0);
                FREE(ps);
index 28b8c10..308c25f 100644 (file)
@@ -351,14 +351,18 @@ nvfx_state_validate_common(struct nvfx_context *nvfx)
        {
                for(int i = 0; i < nvfx->framebuffer.nr_cbufs; ++i)
                {
-                       if(render_temps & (1 << i))
+                       if(render_temps & (1 << i)) {
+                               assert(((struct nvfx_surface*)nvfx->framebuffer.cbufs[i])->temp);
                                util_dirty_surface_set_dirty(nvfx_surface_get_dirty_surfaces(nvfx->framebuffer.cbufs[i]),
                                                (struct util_dirty_surface*)nvfx->framebuffer.cbufs[i]);
+                       }
                }
 
-               if(render_temps & 0x80)
+               if(render_temps & 0x80) {
+                       assert(((struct nvfx_surface*)nvfx->framebuffer.zsbuf)->temp);
                        util_dirty_surface_set_dirty(nvfx_surface_get_dirty_surfaces(nvfx->framebuffer.zsbuf),
                                        (struct util_dirty_surface*)nvfx->framebuffer.zsbuf);
+               }
        }
 
        return TRUE;
index 6743d06..34fd4c4 100644 (file)
@@ -384,6 +384,10 @@ nvfx_surface_copy_temp(struct pipe_context* pipe, struct pipe_surface* surf, int
        struct pipe_subresource tempsr, surfsr;
        struct nvfx_context* nvfx = nvfx_context(pipe);
 
+       /* temporarily detach the temp, so it isn't used in place of the actual resource */
+       struct nvfx_miptree* temp = ns->temp;
+       ns->temp = 0;
+
        // TODO: we really should do this validation before setting these variable in draw calls
        unsigned use_vertex_buffers = nvfx->use_vertex_buffers;
        boolean use_index_buffer = nvfx->use_index_buffer;
@@ -395,9 +399,16 @@ nvfx_surface_copy_temp(struct pipe_context* pipe, struct pipe_surface* surf, int
        surfsr.level = surf->level;
 
        if(to_temp)
-               nvfx_resource_copy_region(pipe, &ns->temp->base.base, tempsr, 0, 0, 0, surf->texture, surfsr, 0, 0, surf->zslice, surf->width, surf->height);
+               nvfx_resource_copy_region(pipe, &temp->base.base, tempsr, 0, 0, 0, surf->texture, surfsr, 0, 0, surf->zslice, surf->width, surf->height);
        else
-               nvfx_resource_copy_region(pipe, surf->texture, surfsr, 0, 0, surf->zslice, &ns->temp->base.base, tempsr, 0, 0, 0, surf->width, surf->height);
+               nvfx_resource_copy_region(pipe, surf->texture, surfsr, 0, 0, surf->zslice, &temp->base.base, tempsr, 0, 0, 0, surf->width, surf->height);
+
+       /* If this triggers, it probably means we attempted to use the blitter
+        * but failed due to non-renderability of the target.
+        * Obviously, this would lead to infinite recursion if supported. */
+       assert(!ns->temp);
+
+       ns->temp = temp;
 
        nvfx->use_vertex_buffers = use_vertex_buffers;
        nvfx->use_index_buffer = use_index_buffer;
@@ -421,6 +432,8 @@ nvfx_surface_create_temp(struct pipe_context* pipe, struct pipe_surface* surf)
        template.nr_samples = surf->texture->nr_samples;
        template.flags = NVFX_RESOURCE_FLAG_LINEAR;
 
+       assert(!ns->temp && !util_dirty_surface_is_dirty(&ns->base));
+
        ns->temp = (struct nvfx_miptree*)nvfx_miptree_create(pipe->screen, &template);
        nvfx_surface_copy_temp(pipe, surf, 1);
 }
@@ -432,11 +445,10 @@ nvfx_surface_flush(struct pipe_context* pipe, struct pipe_surface* surf)
        struct nvfx_surface* ns = (struct nvfx_surface*)surf;
        boolean bound = FALSE;
 
-       /* must be done before the copy, otherwise the copy will use the temp as destination */
-       util_dirty_surface_set_clean(nvfx_surface_get_dirty_surfaces(surf), &ns->base);
-
        nvfx_surface_copy_temp(pipe, surf, 0);
 
+       util_dirty_surface_set_clean(nvfx_surface_get_dirty_surfaces(surf), &ns->base);
+
        if(nvfx->framebuffer.zsbuf == surf)
                bound = TRUE;
        else