Mesa (master): r600g: start looking at evergreen tiling.

Dave Airlie airlied at kemper.freedesktop.org
Tue Feb 1 00:35:48 UTC 2011


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

Author: Dave Airlie <airlied at redhat.com>
Date:   Sat Jan 29 21:25:37 2011 +1000

r600g: start looking at evergreen tiling.

this just adds the ioctl interface and sets the tile type
and array mode in the correct place.

This seems to bring eg 1D tiling to the same level, and issues
as on r600. No idea how to address 2D yet.

---

 src/gallium/drivers/r600/evergreen_state.c |   19 ++++++-
 src/gallium/drivers/r600/evergreend.h      |    3 +
 src/gallium/winsys/r600/drm/r600_drm.c     |   77 +++++++++++++++++++++------
 3 files changed, 79 insertions(+), 20 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 5a923db..8c4f0f9 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -351,7 +351,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	struct r600_resource *rbuffer;
 	unsigned format;
 	uint32_t word4 = 0, yuv_format = 0, pitch = 0;
-	unsigned char swizzle[4];
+	unsigned char swizzle[4], array_mode = 0, tile_type = 0;
 	struct r600_bo *bo[2];
 
 	if (resource == NULL)
@@ -390,15 +390,21 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	bo[1] = rbuffer->bo;
 
 	pitch = align(tmp->pitch_in_pixels[0], 8);
+	if (tmp->tiled) {
+		array_mode = tmp->array_mode[0];
+		tile_type = tmp->tile_type;
+	}
 
 	/* FIXME properly handle first level != 0 */
 	r600_pipe_state_add_reg(rstate, R_030000_RESOURCE0_WORD0,
 				S_030000_DIM(r600_tex_dim(texture->target)) |
 				S_030000_PITCH((pitch / 8) - 1) |
+				S_030000_NON_DISP_TILING_ORDER(tile_type) |
 				S_030000_TEX_WIDTH(texture->width0 - 1), 0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
 				S_030004_TEX_HEIGHT(texture->height0 - 1) |
-				S_030004_TEX_DEPTH(texture->depth0 - 1),
+				S_030004_TEX_DEPTH(texture->depth0 - 1) |
+				S_030004_ARRAY_MODE(array_mode),
 				0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
 				(tmp->offset[0] + r600_bo_offset(bo[0])) >> 8, 0xFFFFFFFF, bo[0]);
@@ -635,6 +641,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	unsigned color_info;
 	unsigned format, swap, ntype;
 	unsigned offset;
+	unsigned tile_type;
 	const struct util_format_description *desc;
 	struct r600_bo *bo[3];
 
@@ -659,11 +666,17 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	swap = r600_translate_colorswap(rtex->resource.base.b.format);
 	color_info = S_028C70_FORMAT(format) |
 		S_028C70_COMP_SWAP(swap) |
+		S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
 		S_028C70_BLEND_CLAMP(1) |
 		S_028C70_NUMBER_TYPE(ntype);
 	if (desc->colorspace != UTIL_FORMAT_COLORSPACE_ZS)
 		color_info |= S_028C70_SOURCE_FORMAT(1);
 
+	if (rtex->tiled) {
+		tile_type = rtex->tile_type;
+	} else /* workaround for linear buffers */
+		tile_type = 1;
+
 	/* FIXME handle enabling of CB beyond BASE8 which has different offset */
 	r600_pipe_state_add_reg(rstate,
 				R_028C60_CB_COLOR0_BASE + cb * 0x3C,
@@ -687,7 +700,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 				0x00000000, 0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate,
 				R_028C74_CB_COLOR0_ATTRIB + cb * 0x3C,
-				S_028C74_NON_DISP_TILING_ORDER(1),
+				S_028C74_NON_DISP_TILING_ORDER(tile_type),
 				0xFFFFFFFF, bo[0]);
 }
 
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index f7f0085..dec32b5 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -930,6 +930,9 @@
 #define     V_030000_SQ_TEX_DIM_2D_ARRAY               0x00000005
 #define     V_030000_SQ_TEX_DIM_2D_MSAA                0x00000006
 #define     V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA          0x00000007
+#define   S_030000_NON_DISP_TILING_ORDER(x)            (((x) & 0x1) << 5)
+#define   G_030000_NON_DISP_TILING_ORDER(x)            (((x) >> 5) & 0x1)
+#define   C_030000_NON_DISP_TILING_ORDER               0xFFFFFFDF
 #define   S_030000_PITCH(x)                            (((x) & 0xFFF) << 6)
 #define   G_030000_PITCH(x)                            (((x) >> 6) & 0xFFF)
 #define   C_030000_PITCH                               0xFFFC003F
diff --git a/src/gallium/winsys/r600/drm/r600_drm.c b/src/gallium/winsys/r600/drm/r600_drm.c
index 3c7e9aa..096c178 100644
--- a/src/gallium/winsys/r600/drm/r600_drm.c
+++ b/src/gallium/winsys/r600/drm/r600_drm.c
@@ -78,20 +78,8 @@ static int radeon_get_device(struct radeon *radeon)
 	return r;
 }
 
-static int radeon_drm_get_tiling(struct radeon *radeon)
+static int r600_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
 {
-	struct drm_radeon_info info;
-	int r;
-	uint32_t tiling_config = 0;
-
-	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 0;
-
 	switch ((tiling_config & 0xe) >> 1) {
 	case 0:
 		radeon->tiling_info.num_channels = 1;
@@ -133,6 +121,62 @@ static int radeon_drm_get_tiling(struct radeon *radeon)
 	return 0;
 }
 
+static int eg_interpret_tiling(struct radeon *radeon, uint32_t tiling_config)
+{
+	switch (tiling_config & 0xf) {
+	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;
+	}
+
+	radeon->tiling_info.num_banks = (tiling_config & 0xf0) >> 4;
+
+	switch ((tiling_config & 0xf00) >> 8) {
+	case 0:
+		radeon->tiling_info.group_bytes = 256;
+		break;
+	case 1:
+		radeon->tiling_info.group_bytes = 512;
+		break;
+	default:
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int radeon_drm_get_tiling(struct radeon *radeon)
+{
+	struct drm_radeon_info info;
+	int r;
+	uint32_t tiling_config = 0;
+
+	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 0;
+
+	if (radeon->chip_class == R600 || radeon->chip_class == R700) {
+		r = r600_interpret_tiling(radeon, tiling_config);
+	} else {
+		r = eg_interpret_tiling(radeon, tiling_config);
+	}
+	return r;
+}
+
 static int radeon_get_clock_crystal_freq(struct radeon *radeon)
 {
 	struct drm_radeon_info info;
@@ -228,10 +272,9 @@ static 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;
-	}
+	if (radeon_drm_get_tiling(radeon))
+		return NULL;
+
 	/* get the GPU counter frequency, failure is non fatal */
 	radeon_get_clock_crystal_freq(radeon);
 




More information about the mesa-commit mailing list