Mesa (master): r600g: add evergreen+ big endian support

Alex Deucher agd5f at kemper.freedesktop.org
Tue Apr 19 10:43:43 PDT 2011


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

Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Tue Apr 19 13:35:19 2011 -0400

r600g: add evergreen+ big endian support

Based on Cédric's r6xx/r7xx patch.

Signed-off-by: Alex Deucher <alexdeucher at gmail.com>

---

 src/gallium/drivers/r600/eg_state_inlines.h |   51 +++++++++++++++++++++++++++
 src/gallium/drivers/r600/evergreen_state.c  |   21 ++++++++---
 src/gallium/drivers/r600/evergreend.h       |    6 +++
 src/gallium/drivers/r600/r600_buffer.c      |    2 +-
 4 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/src/gallium/drivers/r600/eg_state_inlines.h b/src/gallium/drivers/r600/eg_state_inlines.h
index 627dcb8..a67e72e 100644
--- a/src/gallium/drivers/r600/eg_state_inlines.h
+++ b/src/gallium/drivers/r600/eg_state_inlines.h
@@ -506,6 +506,57 @@ static INLINE uint32_t r600_translate_colorformat(enum pipe_format format)
 	}
 }
 
+static INLINE uint32_t r600_colorformat_endian_swap(uint32_t colorformat)
+{
+#ifdef PIPE_ARCH_BIG_ENDIAN
+	switch(colorformat) {
+	case V_0280A0_COLOR_4_4:
+		return(ENDIAN_NONE);
+
+		/* 8-bit buffers. */
+	case V_0280A0_COLOR_8:
+		return(ENDIAN_NONE);
+
+		/* 16-bit buffers. */
+	case V_0280A0_COLOR_5_6_5:
+	case V_0280A0_COLOR_1_5_5_5:
+	case V_0280A0_COLOR_4_4_4_4:
+	case V_0280A0_COLOR_16:
+	case V_0280A0_COLOR_8_8:
+		return(ENDIAN_8IN16);
+
+		/* 32-bit buffers. */
+	case V_0280A0_COLOR_8_8_8_8:
+	case V_0280A0_COLOR_2_10_10_10:
+	case V_0280A0_COLOR_8_24:
+	case V_0280A0_COLOR_24_8:
+	case V_0280A0_COLOR_32_FLOAT:
+	case V_0280A0_COLOR_16_16_FLOAT:
+	case V_0280A0_COLOR_16_16:
+		return(ENDIAN_8IN32);
+
+		/* 64-bit buffers. */
+	case V_0280A0_COLOR_16_16_16_16:
+	case V_0280A0_COLOR_16_16_16_16_FLOAT:
+		return(ENDIAN_8IN16);
+
+	case V_0280A0_COLOR_32_32_FLOAT:
+	case V_0280A0_COLOR_32_32:
+		return(ENDIAN_8IN32);
+
+		/* 128-bit buffers. */
+	case V_0280A0_COLOR_32_32_32_FLOAT:
+	case V_0280A0_COLOR_32_32_32_32_FLOAT:
+	case V_0280A0_COLOR_32_32_32_32:
+		return(ENDIAN_8IN32);
+	default:
+		return ENDIAN_NONE; /* Unsupported. */
+	}
+#else
+	return ENDIAN_NONE;
+#endif
+}
+
 static INLINE boolean r600_is_sampler_format_supported(struct pipe_screen *screen, enum pipe_format format)
 {
 	return r600_translate_texformat(screen, format, NULL, NULL, NULL) != ~0;
diff --git a/src/gallium/drivers/r600/evergreen_state.c b/src/gallium/drivers/r600/evergreen_state.c
index 6aa22d9..febc613 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -357,7 +357,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	const struct util_format_description *desc;
 	struct r600_resource_texture *tmp;
 	struct r600_resource *rbuffer;
-	unsigned format;
+	unsigned format, endian;
 	uint32_t word4 = 0, yuv_format = 0, pitch = 0;
 	unsigned char swizzle[4], array_mode = 0, tile_type = 0;
 	struct r600_bo *bo[2];
@@ -394,6 +394,8 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 		tmp = tmp->flushed_depth_texture;
 	}
 
+	endian = r600_colorformat_endian_swap(format);
+
 	if (tmp->force_int_type) {
 		word4 &= C_030010_NUM_FORMAT_ALL;
 		word4 |= S_030010_NUM_FORMAT_ALL(V_030010_SQ_NUM_FORMAT_INT);
@@ -425,6 +427,7 @@ static struct pipe_sampler_view *evergreen_create_sampler_view(struct pipe_conte
 	r600_pipe_state_add_reg(rstate, R_030010_RESOURCE0_WORD4,
 				word4 |
 				S_030010_SRF_MODE_ALL(V_030010_SRF_MODE_NO_ZERO) |
+				S_030010_ENDIAN_SWAP(endian) |
 				S_030010_BASE_LEVEL(state->u.tex.first_level), 0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate, R_030014_RESOURCE0_WORD5,
 				S_030014_LAST_LEVEL(state->u.tex.last_level) |
@@ -655,7 +658,7 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 	unsigned level = state->cbufs[cb]->u.tex.level;
 	unsigned pitch, slice;
 	unsigned color_info;
-	unsigned format, swap, ntype;
+	unsigned format, swap, ntype, endian;
 	unsigned offset;
 	unsigned tile_type;
 	const struct util_format_description *desc;
@@ -694,6 +697,11 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 
 	format = r600_translate_colorformat(surf->base.format);
 	swap = r600_translate_colorswap(surf->base.format);
+	if (rbuffer->b.b.b.usage == PIPE_USAGE_STAGING) {
+		endian = ENDIAN_NONE;
+	} else {
+		endian = r600_colorformat_endian_swap(format);
+	}
 
 	/* disable when gallium grows int textures */
 	if ((format == FMT_32_32_32_32 || format == FMT_16_16_16_16) && rtex->force_int_type)
@@ -703,7 +711,8 @@ static void evergreen_cb(struct r600_pipe_context *rctx, struct r600_pipe_state
 		S_028C70_COMP_SWAP(swap) |
 		S_028C70_ARRAY_MODE(rtex->array_mode[level]) |
 		S_028C70_BLEND_CLAMP(1) |
-		S_028C70_NUMBER_TYPE(ntype);
+		S_028C70_NUMBER_TYPE(ntype) |
+		S_028C70_ENDIAN(endian);
 
 
 	/* we can only set the export size if any thing is snorm/unorm component is > 11 bits,
@@ -1548,8 +1557,10 @@ void evergreen_pipe_set_buffer_resource(struct r600_pipe_context *rctx,
 	r600_pipe_state_add_reg(rstate, R_030004_RESOURCE0_WORD1,
 				rbuffer->bo_size - offset - 1, 0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate, R_030008_RESOURCE0_WORD2,
-				S_030008_STRIDE(stride),
-				0xFFFFFFFF, NULL);
+#ifdef PIPE_ARCH_BIG_ENDIAN
+				S_030008_ENDIAN_SWAP(ENDIAN_8IN32) |
+#endif
+				S_030008_STRIDE(stride), 0xFFFFFFFF, NULL);
 	r600_pipe_state_add_reg(rstate, R_03000C_RESOURCE0_WORD3,
 				S_03000C_DST_SEL_X(V_03000C_SQ_SEL_X) |
 				S_03000C_DST_SEL_Y(V_03000C_SQ_SEL_Y) |
diff --git a/src/gallium/drivers/r600/evergreend.h b/src/gallium/drivers/r600/evergreend.h
index c51a163..8489c29 100644
--- a/src/gallium/drivers/r600/evergreend.h
+++ b/src/gallium/drivers/r600/evergreend.h
@@ -1885,4 +1885,10 @@
 #define R_03CFF4_SQ_VTX_START_INST_LOC                  0x03CFF4
 
 #define R_03A200_SQ_LOOP_CONST_0                     0x3A200
+
+#define ENDIAN_NONE	0
+#define ENDIAN_8IN16	1
+#define ENDIAN_8IN32	2
+#define ENDIAN_8IN64	3
+
 #endif
diff --git a/src/gallium/drivers/r600/r600_buffer.c b/src/gallium/drivers/r600/r600_buffer.c
index c1f063f..71b47e1 100644
--- a/src/gallium/drivers/r600/r600_buffer.c
+++ b/src/gallium/drivers/r600/r600_buffer.c
@@ -282,7 +282,7 @@ void r600_upload_const_buffer(struct r600_pipe_context *rctx, struct r600_resour
 		for(i = 0; i < size / 4; i++) {
 			tmpPtr[i] = bswap_32(*((uint32_t *)ptr + i));
 		}
-	
+
 		u_upload_data(rctx->vbuf_mgr->uploader, 0, size, tmpPtr, const_offset,
 			      (struct pipe_resource**)rbuffer, &flushed);
 



More information about the mesa-commit mailing list