summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAlex Deucher <[email protected]>2011-04-19 13:35:19 -0400
committerAlex Deucher <[email protected]>2011-04-19 13:35:19 -0400
commit08d1c91e6c185a186e49189b7ed48629f35a4659 (patch)
treed1814dcefb79ca71d8736d466e6889ea1485fcff /src
parent843dfe3206c4f397c7911b748373dde5540392a4 (diff)
r600g: add evergreen+ big endian support
Based on Cédric's r6xx/r7xx patch. Signed-off-by: Alex Deucher <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/r600/eg_state_inlines.h51
-rw-r--r--src/gallium/drivers/r600/evergreen_state.c21
-rw-r--r--src/gallium/drivers/r600/evergreend.h6
-rw-r--r--src/gallium/drivers/r600/r600_buffer.c2
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 627dcb8e07f..a67e72e4f35 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 6aa22d99d0a..febc6139a81 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 c51a163bd06..8489c29a691 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 c1f063fc21a..71b47e1b056 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);