On 17.11.2014 23:30, Aaron Watry wrote:
On Mon, Nov 17, 2014 at 1:45 AM, Michel Dänzer <mic...@daenzer.net> wrote:
On 14.11.2014 19:37, Marek Olšák wrote:
surface_destroy should never be called directly, because surfaces have
a reference counter. For unreferencing resources, use
pipe_surface_reference(&pointer, NULL). It will call surface_destroy
if needed.

Indeed, if this was the right place for this, it could be done both
easier and more robustly:

                for (int i = 0; i < fb_state->nr_cbufs; i++)
                        pipe_surface_reference(&fb_state->cbufs[i], NULL);


Yeah, you're right about that.  After your (Michel/Marek) replies, I
had come to the same conclusion about simplifying things.  I'm having
*fun* deciding where the proper place to put this in the evergreen
code is.  We end up calling evergreen_set_rat from multiple places,
which is where the surfaces are created, and then we keep a list with
a set count...  and the individual surfaces themselves get freed as
their reference counts change.  In theory, they all get
referenced/freed at the same point, but there's no guarantees that I
can see.

The first logical place that I saw to put the de-reference is in
evergreen_set_global_binding and the matching
create/delete_compute_state functions.

AFAICT it indeed needs to be handled in evergreen_set_compute_resources and evergreen_set_global_binding. Does the attached patch work?


--
Earthling Michel Dänzer               |               http://www.amd.com
Libre software enthusiast             |             Mesa and X developer
>From 2ee9c0c435405df7382363ae8f276cd3ce4f8c6b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michel=20D=C3=A4nzer?= <michel.daen...@amd.com>
Date: Tue, 18 Nov 2014 11:46:22 +0900
Subject: [PATCH] r600g/compute: Fix cbuf leaks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>
---
 src/gallium/drivers/r600/evergreen_compute.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_compute.c b/src/gallium/drivers/r600/evergreen_compute.c
index 90fdd79..64c3cee 100644
--- a/src/gallium/drivers/r600/evergreen_compute.c
+++ b/src/gallium/drivers/r600/evergreen_compute.c
@@ -127,6 +127,7 @@ static void evergreen_set_rat(
 	rat_templ.u.tex.last_layer = 0;
 
 	/* Add the RAT the list of color buffers */
+	pipe_surface_reference(&pipe->ctx->framebuffer.state.cbufs[id], NULL);
 	pipe->ctx->framebuffer.state.cbufs[id] = pipe->ctx->b.b.create_surface(
 		(struct pipe_context *)pipe->ctx,
 		(struct pipe_resource *)bo, &rat_templ);
@@ -627,11 +628,16 @@ static void evergreen_set_compute_resources(struct pipe_context * ctx_,
 {
 	struct r600_context *ctx = (struct r600_context *)ctx_;
 	struct r600_surface **resources = (struct r600_surface **)surfaces;
+	unsigned i;
 
 	COMPUTE_DBG(ctx->screen, "*** evergreen_set_compute_resources: start = %u count = %u\n",
 			start, count);
 
-	for (unsigned i = 0; i < count; i++) {
+	/* Unreference unused surfaces */
+	for (i = count + 1; i < ctx->framebuffer.state.nr_cbufs; i++)
+		pipe_surface_reference(&ctx->framebuffer.state.cbufs[i], NULL);
+
+	for (i = 0; i < count; i++) {
 		/* The First two vertex buffers are reserved for parameters and
 		 * global buffers. */
 		unsigned vtx_id = 2 + i;
@@ -651,6 +657,9 @@ static void evergreen_set_compute_resources(struct pipe_context * ctx_,
 			evergreen_cs_set_vertex_buffer(ctx, vtx_id,
 					buffer->chunk->start_in_dw * 4,
 					resources[i]->base.texture);
+		} else {
+			pipe_surface_reference(&ctx->framebuffer.state.cbufs[i+1],
+					       NULL);
 		}
 	}
 }
@@ -688,10 +697,11 @@ static void evergreen_set_global_binding(
 	COMPUTE_DBG(ctx->screen, "*** evergreen_set_global_binding first = %u n = %u\n",
 			first, n);
 
-	if (!resources) {
-		/* XXX: Unset */
+	/* Unreference previous resource */
+	pipe_surface_reference(&ctx->framebuffer.state.cbufs[0], NULL);
+
+	if (!resources)
 		return;
-	}
 
 	/* We mark these items for promotion to the pool if they
 	 * aren't already there */
@@ -702,10 +712,8 @@ static void evergreen_set_global_binding(
 			buffers[i]->chunk->status |= ITEM_FOR_PROMOTING;
 	}
 
-	if (compute_memory_finalize_pending(pool, ctx_) == -1) {
-		/* XXX: Unset */
+	if (compute_memory_finalize_pending(pool, ctx_) == -1)
 		return;
-	}
 
 	for (i = first; i < first + n; i++)
 	{
-- 
2.1.3

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to