Hi,

attached is a set of patches to r600g.

0001-r600g-Fix-typo.patch:
Fix a more or less obvious typo in shader initialization setup.

0002-r600g-Set-the-domains-value-also-for-recycled-buffer.patch:
Makes sure that buffer objects from the userspace bo manager does not have a 
degraded domains value set. Without this it could happen that buffer objects 
for display lists for example ended up in gtt even if they could savely be 
placed somewhere deep in the gpu board.

0003-r600g-Allow-VRAM-for-the-initial-domain-for-every-bu.patch:
This improoves rendering (not draw) times on plenty openscenegraph examples by 
about 20% in average.
This turned out to be the most effective part of the past change that I 
requested review for and that I never sent an updated patch up to now.

0004-r600g-Put-shaders-into-immutable-buffers.patch:
Shaders programs are immutable for the driver. So put them into immutable 
buffer objects.

0005-r600g-Make-use-of-PIPE_TRANSFER_DISCARD_WHOLE_RESOUR.patch:
This makes use of the DISCARD_WHOLE_RESOURCE flag for memory mappings.

Please review/apply!

Thanks

Mathias

From 51c15a805e7b93bc1627d8771788c55c71acb990 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <mathias.froehl...@web.de>
Date: Wed, 8 Jun 2011 17:33:57 +0200
Subject: [PATCH 1/5] r600g: Fix typo.

Fix an obvious typo in the yet unused part of the shader setup.
---
 src/gallium/drivers/r600/r600_state.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index 5a1c456..98f5c51 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -1243,7 +1243,7 @@ void r600_init_config(struct r600_pipe_context *rctx)
 	/* SQ_GPR_RESOURCE_MGMT_2 */
 	tmp = 0;
 	tmp |= S_008C08_NUM_GS_GPRS(num_gs_gprs);
-	tmp |= S_008C08_NUM_GS_GPRS(num_es_gprs);
+	tmp |= S_008C08_NUM_ES_GPRS(num_es_gprs);
 	r600_pipe_state_add_reg(rstate, R_008C08_SQ_GPR_RESOURCE_MGMT_2, tmp, 0xFFFFFFFF, NULL);
 
 	/* SQ_THREAD_RESOURCE_MGMT */
-- 
1.7.4.4

From ad95ec4446a610d5d4a061958ab811e474c849df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <mathias.froehl...@gmx.net>
Date: Sun, 12 Jun 2011 14:25:26 +0200
Subject: [PATCH 2/5] r600g: Set the domains value also for recycled buffer
 objects.

---
 src/gallium/winsys/r600/drm/r600_bo.c |   26 ++++++++++++++------------
 1 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 8bb216d..093660f 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -38,11 +38,23 @@ struct r600_bo *r600_bo(struct radeon *radeon,
 {
 	struct r600_bo *bo;
 	struct radeon_bo *rbo;
-	uint32_t initial_domain;
+	uint32_t initial_domain, domains;
 	  
+	/* Staging resources particpate in transfers and blits only
+	 * and are used for uploads and downloads from regular
+	 * resources.  We generate them internally for some transfers.
+	 */
+	if (usage == PIPE_USAGE_STAGING)
+		domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
+	else
+		domains = (RADEON_GEM_DOMAIN_CPU |
+				RADEON_GEM_DOMAIN_GTT |
+				RADEON_GEM_DOMAIN_VRAM);
+
 	if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
 		bo = r600_bomgr_bo_create(radeon->bomgr, size, alignment, *radeon->cfence);
 		if (bo) {
+			bo->domains = domains;
 			return bo;
 		}
 	}
@@ -72,22 +84,12 @@ struct r600_bo *r600_bo(struct radeon *radeon,
 	bo = calloc(1, sizeof(struct r600_bo));
 	bo->size = size;
 	bo->alignment = alignment;
+	bo->domains = domains;
 	bo->bo = rbo;
 	if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
 		r600_bomgr_bo_init(radeon->bomgr, bo);
 	}
 
-	/* Staging resources particpate in transfers and blits only
-	 * and are used for uploads and downloads from regular
-	 * resources.  We generate them internally for some transfers.
-	 */
-	if (usage == PIPE_USAGE_STAGING)
-		bo->domains = RADEON_GEM_DOMAIN_CPU | RADEON_GEM_DOMAIN_GTT;
-	else
-		bo->domains = (RADEON_GEM_DOMAIN_CPU |
-				RADEON_GEM_DOMAIN_GTT |
-				RADEON_GEM_DOMAIN_VRAM);
-
 	pipe_reference_init(&bo->reference, 1);
 	return bo;
 }
-- 
1.7.4.4

From 473fd8ce3f23ea972d6907edec21d36dd631bf43 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <mathias.froehl...@gmx.net>
Date: Sun, 12 Jun 2011 14:32:03 +0200
Subject: [PATCH 3/5] r600g: Allow VRAM for the initial domain for every
 buffer binding.

---
 src/gallium/winsys/r600/drm/r600_bo.c |   26 +++++++++++---------------
 1 files changed, 11 insertions(+), 15 deletions(-)

diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 093660f..4098a6e 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -59,22 +59,18 @@ struct r600_bo *r600_bo(struct radeon *radeon,
 		}
 	}
 
-	if (binding & (PIPE_BIND_CONSTANT_BUFFER | PIPE_BIND_VERTEX_BUFFER | PIPE_BIND_INDEX_BUFFER)) {
+	switch(usage) {
+	case PIPE_USAGE_DYNAMIC:
+	case PIPE_USAGE_STREAM:
+	case PIPE_USAGE_STAGING:
 		initial_domain = RADEON_GEM_DOMAIN_GTT;
-	} else {
-		switch(usage) {
-		case PIPE_USAGE_DYNAMIC:
-		case PIPE_USAGE_STREAM:
-		case PIPE_USAGE_STAGING:
-			initial_domain = RADEON_GEM_DOMAIN_GTT;
-			break;
-		case PIPE_USAGE_DEFAULT:
-		case PIPE_USAGE_STATIC:
-		case PIPE_USAGE_IMMUTABLE:
-		default:
-			initial_domain = RADEON_GEM_DOMAIN_VRAM;
-			break;
-		}
+		break;
+	case PIPE_USAGE_DEFAULT:
+	case PIPE_USAGE_STATIC:
+	case PIPE_USAGE_IMMUTABLE:
+	default:
+		initial_domain = RADEON_GEM_DOMAIN_VRAM;
+		break;
 	}
 	rbo = radeon_bo(radeon, 0, size, alignment, initial_domain);
 	if (rbo == NULL) {
-- 
1.7.4.4

From f9e7a7647ea0aa90d9f2ee73073e2770f2f0ea91 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <mathias.froehl...@web.de>
Date: Sat, 4 Jun 2011 00:21:29 +0200
Subject: [PATCH 4/5] r600g: Put shaders into immutable buffers.

Put the shader programs into an immutable buffer object.
Also make sure that those object can be taken from the user
space buffer object pool.
---
 src/gallium/drivers/r600/r600_asm.c    |    2 +-
 src/gallium/drivers/r600/r600_shader.c |    3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_asm.c b/src/gallium/drivers/r600/r600_asm.c
index 3196d97..aeb1175 100644
--- a/src/gallium/drivers/r600/r600_asm.c
+++ b/src/gallium/drivers/r600/r600_asm.c
@@ -2258,7 +2258,7 @@ int r600_vertex_elements_build_fetch_shader(struct r600_pipe_context *rctx, stru
 	ve->fs_size = bc.ndw*4;
 
 	/* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */
-	ve->fetch_shader = r600_bo(rctx->radeon, ve->fs_size, 256, PIPE_BIND_VERTEX_BUFFER, 0);
+	ve->fetch_shader = r600_bo(rctx->radeon, ve->fs_size, 256, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_IMMUTABLE);
 	if (ve->fetch_shader == NULL) {
 		r600_bc_clear(&bc);
 		return -ENOMEM;
diff --git a/src/gallium/drivers/r600/r600_shader.c b/src/gallium/drivers/r600/r600_shader.c
index 39e6d85..d111caa 100644
--- a/src/gallium/drivers/r600/r600_shader.c
+++ b/src/gallium/drivers/r600/r600_shader.c
@@ -85,7 +85,8 @@ static int r600_pipe_shader(struct pipe_context *ctx, struct r600_pipe_shader *s
 
 	/* copy new shader */
 	if (shader->bo == NULL) {
-		shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, 0, 0);
+		/* use PIPE_BIND_VERTEX_BUFFER so we use the cache buffer manager */
+		shader->bo = r600_bo(rctx->radeon, rshader->bc.ndw * 4, 4096, PIPE_BIND_VERTEX_BUFFER, PIPE_USAGE_IMMUTABLE);
 		if (shader->bo == NULL) {
 			return -ENOMEM;
 		}
-- 
1.7.4.4

From edbfa9c08f7d4cc662fe239f4342ccda42133369 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mathias=20Fr=C3=B6hlich?= <mathias.froehl...@web.de>
Date: Sun, 30 Jan 2011 11:53:21 +0100
Subject: [PATCH 5/5] r600g: Make use of PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE.

Detach from the underlying buffer object if this
is busy and reallocating a new one is successful.
---
 src/gallium/drivers/r600/r600.h          |    2 ++
 src/gallium/drivers/r600/r600_buffer.c   |   20 ++++++++++++++++++--
 src/gallium/drivers/r600/r600_resource.h |   21 +++++++++++++++++++++
 src/gallium/winsys/r600/drm/r600_bo.c    |   19 +++++++++++++++++++
 4 files changed, 60 insertions(+), 2 deletions(-)

diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index bf7138d..496ff36 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -100,6 +100,8 @@ struct r600_bo;
 struct r600_bo *r600_bo(struct radeon *radeon,
 			unsigned size, unsigned alignment,
 			unsigned binding, unsigned usage);
+void r600_bo_detach(struct radeon *radeon, struct r600_bo **bo,
+			unsigned binding, unsigned usage);
 struct r600_bo *r600_bo_handle(struct radeon *radeon,
 				unsigned handle, unsigned *array_mode);
 void *r600_bo_map(struct radeon *radeon, struct r600_bo *bo, unsigned usage, void *ctx);
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index 72f352d..7400498 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -81,12 +81,19 @@ static void *r600_buffer_transfer_map(struct pipe_context *pipe,
 				      struct pipe_transfer *transfer)
 {
 	struct r600_resource_buffer *rbuffer = r600_buffer(transfer->resource);
+	unsigned usage;
 	uint8_t *data;
 
 	if (rbuffer->r.b.user_ptr)
 		return (uint8_t*)rbuffer->r.b.user_ptr + transfer->box.x;
 
-	data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, transfer->usage, pipe);
+	if (!(transfer->usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
+	    (transfer->usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE))
+		r600_bo_detach((struct radeon*)pipe->winsys, &rbuffer->r.bo,
+				rbuffer->r.b.b.b.bind, rbuffer->r.b.b.b.usage);
+
+	usage = r600_resource_pb_usage_from_transfer(transfer->usage);
+	data = r600_bo_map((struct radeon*)pipe->winsys, rbuffer->r.bo, usage, pipe);
 	if (!data)
 		return NULL;
 
@@ -133,8 +140,17 @@ static void r600_buffer_transfer_inline_write(struct pipe_context *pipe,
 
 	assert(rbuffer->r.b.user_ptr == NULL);
 
+	if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
+		if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)
+			r600_bo_detach(ws, &rbuffer->r.bo,
+				rbuffer->r.b.b.b.bind, rbuffer->r.b.b.b.usage);
+		else if (box->x == 0 && box->width == rbuffer->r.size)
+			r600_bo_detach(ws, &rbuffer->r.bo,
+				rbuffer->r.b.b.b.bind, rbuffer->r.b.b.b.usage);
+	}
+
 	map = r600_bo_map(ws, rbuffer->r.bo,
-			  PIPE_TRANSFER_WRITE | PIPE_TRANSFER_DISCARD | usage,
+			  r600_resource_pb_usage_from_transfer(usage),
 			  pipe);
 
 	memcpy(map + box->x, data, box->width);
diff --git a/src/gallium/drivers/r600/r600_resource.h b/src/gallium/drivers/r600/r600_resource.h
index 836e749..55bf0c1 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -25,6 +25,7 @@
 
 #include "util/u_transfer.h"
 #include "util/u_vbuf_mgr.h"
+#include "pipebuffer/pb_buffer.h"
 
 /* flag to indicate a resource is to be used as a transfer so should not be tiled */
 #define R600_RESOURCE_FLAG_TRANSFER     PIPE_RESOURCE_FLAG_DRV_PRIV
@@ -119,6 +120,26 @@ void* r600_texture_transfer_map(struct pipe_context *ctx,
 void r600_texture_transfer_unmap(struct pipe_context *ctx,
 				 struct pipe_transfer* transfer);
 
+static INLINE unsigned
+r600_resource_pb_usage_from_transfer(enum pipe_transfer_usage usage)
+{
+	unsigned res = 0;
+
+	if (usage & PIPE_TRANSFER_READ)
+		res |= PB_USAGE_CPU_READ;
+
+	if (usage & PIPE_TRANSFER_WRITE)
+		res |= PB_USAGE_CPU_WRITE;
+
+	if (usage & PIPE_TRANSFER_DONTBLOCK)
+		res |= PB_USAGE_DONTBLOCK;
+
+	if (usage & PIPE_TRANSFER_UNSYNCHRONIZED)
+		res |= PB_USAGE_UNSYNCHRONIZED;
+
+	return res;
+}
+
 struct r600_pipe_context;
 
 void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resource_buffer **rbuffer, uint32_t *offset);
diff --git a/src/gallium/winsys/r600/drm/r600_bo.c b/src/gallium/winsys/r600/drm/r600_bo.c
index 4098a6e..621bd96 100644
--- a/src/gallium/winsys/r600/drm/r600_bo.c
+++ b/src/gallium/winsys/r600/drm/r600_bo.c
@@ -90,6 +90,25 @@ struct r600_bo *r600_bo(struct radeon *radeon,
 	return bo;
 }
 
+void r600_bo_detach(struct radeon *radeon, struct r600_bo **bo, unsigned binding, unsigned usage)
+{
+	struct r600_bo *replacement;
+	uint32_t domain;
+
+	if ((*bo)->tiling_flags)
+		return;
+
+	if (p_atomic_read(&(*bo)->bo->reference.count) <= 1 && !radeon_bo_busy(radeon, (*bo)->bo, &domain))
+		return;
+
+	replacement = r600_bo(radeon, (*bo)->size, (*bo)->alignment, binding, usage);
+	if (!replacement)
+		return;
+
+	r600_bo_reference(radeon, bo, NULL);
+	*bo = replacement;
+}
+
 struct r600_bo *r600_bo_handle(struct radeon *radeon,
 			       unsigned handle, unsigned *array_mode)
 {
-- 
1.7.4.4

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

Reply via email to