Mesa (master): r600g: get tiling info from kernel

Dave Airlie airlied at kemper.freedesktop.org
Sun Oct 17 23:25:58 UTC 2010


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Fri Oct  8 11:56:43 2010 +1000

r600g: get tiling info from kernel

---

 src/gallium/drivers/r600/r600.h         |    7 +++
 src/gallium/drivers/r600/r600_pipe.c    |    2 +
 src/gallium/drivers/r600/r600_pipe.h    |    1 +
 src/gallium/winsys/r600/drm/r600.c      |    5 ++
 src/gallium/winsys/r600/drm/r600_drm.c  |   62 +++++++++++++++++++++++++++++++
 src/gallium/winsys/r600/drm/r600_priv.h |    1 +
 6 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/src/gallium/drivers/r600/r600.h b/src/gallium/drivers/r600/r600.h
index 24e25ce..15ee001 100644
--- a/src/gallium/drivers/r600/r600.h
+++ b/src/gallium/drivers/r600/r600.h
@@ -99,8 +99,15 @@ enum chip_class {
 	EVERGREEN,
 };
 
+struct r600_tiling_info {
+	unsigned num_channels;
+	unsigned num_banks;
+	unsigned group_bytes;
+};
+
 enum radeon_family r600_get_family(struct radeon *rw);
 enum chip_class r600_get_family_class(struct radeon *radeon);
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon);
 
 /* r600_bo.c */
 struct r600_bo;
diff --git a/src/gallium/drivers/r600/r600_pipe.c b/src/gallium/drivers/r600/r600_pipe.c
index 8eb9799..dd8fa4f 100644
--- a/src/gallium/drivers/r600/r600_pipe.c
+++ b/src/gallium/drivers/r600/r600_pipe.c
@@ -443,5 +443,7 @@ struct pipe_screen *r600_screen_create(struct radeon *radeon)
 	r600_init_screen_texture_functions(&rscreen->screen);
 	r600_init_screen_resource_functions(&rscreen->screen);
 
+	rscreen->tiling_info = r600_get_tiling_info(radeon);
+
 	return &rscreen->screen;
 }
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 47a1b30..3554832 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -58,6 +58,7 @@ enum r600_pipe_state_id {
 struct r600_screen {
 	struct pipe_screen		screen;
 	struct radeon			*radeon;
+	struct r600_tiling_info		*tiling_info;
 };
 
 struct r600_pipe_sampler_view {
diff --git a/src/gallium/winsys/r600/drm/r600.c b/src/gallium/winsys/r600/drm/r600.c
index 496547c..0a4d2e7 100644
--- a/src/gallium/winsys/r600/drm/r600.c
+++ b/src/gallium/winsys/r600/drm/r600.c
@@ -40,6 +40,11 @@ enum chip_class r600_get_family_class(struct radeon *radeon)
 	return radeon->chip_class;
 }
 
+struct r600_tiling_info *r600_get_tiling_info(struct radeon *radeon)
+{
+	return &radeon->tiling_info;
+}
+
 static int r600_get_device(struct radeon *r600)
 {
 	struct drm_radeon_info info;
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 4916843..c9de95f 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -37,6 +37,9 @@
 #include "xf86drm.h"
 #include "radeon_drm.h"
 
+#ifndef RADEON_INFO_TILING_CONFIG
+#define RADEON_INFO_TILING_CONFIG 0x6
+#endif
 static int radeon_get_device(struct radeon *radeon)
 {
 	struct drm_radeon_info info;
@@ -50,6 +53,61 @@ static int radeon_get_device(struct radeon *radeon)
 	return r;
 }
 
+static int radeon_drm_get_tiling(struct radeon *radeon)
+{
+	struct drm_radeon_info info;
+	int r;
+	uint32_t tiling_config;
+
+	info.request = RADEON_INFO_TILING_CONFIG;
+	info.value = (uintptr_t)&tiling_config;
+	r = drmCommandWriteRead(radeon->fd, DRM_RADEON_INFO, &info,
+				sizeof(struct drm_radeon_info));
+
+	if (r)
+		return r;
+
+	switch ((tiling_config & 0xe) >> 1) {
+	case 0:
+		radeon->tiling_info.num_channels = 1;
+		break;
+	case 1:
+		radeon->tiling_info.num_channels = 2;
+		break;
+	case 2:
+		radeon->tiling_info.num_channels = 4;
+		break;
+	case 3:
+		radeon->tiling_info.num_channels = 8;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch ((tiling_config & 0x30) >> 4) {
+	case 0:
+		radeon->tiling_info.num_banks = 4;
+		break;
+	case 1:
+		radeon->tiling_info.num_banks = 8;
+		break;
+	default:
+		return -EINVAL;
+
+	}
+	switch ((tiling_config & 0xc0) >> 6) {
+	case 0:
+		radeon->tiling_info.group_bytes = 256;
+		break;
+	case 1:
+		radeon->tiling_info.group_bytes = 512;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
 struct radeon *radeon_new(int fd, unsigned device)
 {
 	struct radeon *radeon;
@@ -157,6 +215,10 @@ struct radeon *radeon_new(int fd, unsigned device)
 		break;
 	}
 
+	if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+		if (radeon_drm_get_tiling(radeon))
+			return NULL;
+	}
 	radeon->kman = radeon_bo_pbmgr_create(radeon);
 	if (!radeon->kman)
 		return NULL;
diff --git a/src/gallium/winsys/r600/drm/r600_priv.h b/src/gallium/winsys/r600/drm/r600_priv.h
index e3868d3..08e243b 100644
--- a/src/gallium/winsys/r600/drm/r600_priv.h
+++ b/src/gallium/winsys/r600/drm/r600_priv.h
@@ -42,6 +42,7 @@ struct radeon {
 	enum chip_class			chip_class;
 	struct pb_manager *kman; /* kernel bo manager */
 	struct pb_manager *cman; /* cached bo manager */
+	struct r600_tiling_info tiling_info;
 };
 
 struct radeon *r600_new(int fd, unsigned device);




More information about the mesa-commit mailing list