r600g: add evergreen+ big endian support
authorAlex Deucher <alexdeucher@gmail.com>
Tue, 19 Apr 2011 17:35:19 +0000 (13:35 -0400)
committerAlex Deucher <alexdeucher@gmail.com>
Tue, 19 Apr 2011 17:35:19 +0000 (13:35 -0400)
Based on Cédric's r6xx/r7xx patch.

Signed-off-by: Alex Deucher <alexdeucher@gmail.com>
src/gallium/drivers/r600/eg_state_inlines.h
src/gallium/drivers/r600/evergreen_state.c
src/gallium/drivers/r600/evergreend.h
src/gallium/drivers/r600/r600_buffer.c

index 627dcb8e07f5319b9f78c4f828f08f7838f08a5c..a67e72e4f3515972f9d069742887d6d9b48180e3 100644 (file)
@@ -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;
index 6aa22d99d0a481d0f5ed0efb82e5630e794dc289..febc6139a81dfb50b3b3dd99ed9bea06ab67c794 100644 (file)
@@ -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) |
index c51a163bd06433db1402c36fbef55e6922f336e6..8489c29a6915e40a2d86ef71684bf9253dc3f997 100644 (file)
 #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
index c1f063fc21a3bc68c320ef4ffa30112c3de7d499..71b47e1b0569299d0ebab2c9555dfd1b8b29f5c4 100644 (file)
@@ -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);