Mesa (master): nvfx: fix the temporary copying logic and add asserts

Luca Barbieri lb at kemper.freedesktop.org
Sat Sep 4 21:01:22 UTC 2010


Module: Mesa
Branch: master
Commit: 11d29739e114350693eb8ee36d356cfdde432191
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=11d29739e114350693eb8ee36d356cfdde432191

Author: Luca Barbieri <luca at luca-barbieri.com>
Date:   Sat Sep  4 20:17:39 2010 +0200

nvfx: fix the temporary copying logic and add asserts

---

 src/gallium/drivers/nvfx/nvfx_miptree.c    |    1 +
 src/gallium/drivers/nvfx/nvfx_state_emit.c |    8 ++++++--
 src/gallium/drivers/nvfx/nvfx_surface.c    |   22 +++++++++++++++++-----
 3 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/nvfx/nvfx_miptree.c b/src/gallium/drivers/nvfx/nvfx_miptree.c
index 0916aaa..7677fde 100644
--- a/src/gallium/drivers/nvfx/nvfx_miptree.c
+++ b/src/gallium/drivers/nvfx/nvfx_miptree.c
@@ -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);
diff --git a/src/gallium/drivers/nvfx/nvfx_state_emit.c b/src/gallium/drivers/nvfx/nvfx_state_emit.c
index 28b8c10..308c25f 100644
--- a/src/gallium/drivers/nvfx/nvfx_state_emit.c
+++ b/src/gallium/drivers/nvfx/nvfx_state_emit.c
@@ -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;
diff --git a/src/gallium/drivers/nvfx/nvfx_surface.c b/src/gallium/drivers/nvfx/nvfx_surface.c
index 6743d06..34fd4c4 100644
--- a/src/gallium/drivers/nvfx/nvfx_surface.c
+++ b/src/gallium/drivers/nvfx/nvfx_surface.c
@@ -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




More information about the mesa-commit mailing list